Files
2026-07-13 13:08:41 +08:00

121 lines
3.9 KiB
Python

import pytest
from pydantic import ValidationError
from constants.presentation import MAX_NUMBER_OF_SLIDES, MAX_OUTLINE_CONTENT_WORDS
from models.presentation_outline_model import PresentationOutlineModel, SlideOutlineModel
from utils.outline_limits import count_outline_words
from utils.outline_utils import (
_extract_outline_title,
get_images_for_slides_from_outline,
get_no_of_toc_required_for_n_outlines,
get_presentation_outline_model_with_toc,
get_presentation_title_from_presentation_outline,
)
def test_get_presentation_title_handles_prefixed_page_heading():
outline = PresentationOutlineModel(
slides=[SlideOutlineModel(content="## Page 1: Growth/Plan\\Roadmap\nBody")]
)
title = get_presentation_title_from_presentation_outline(outline)
assert title == "GrowthPlanRoadmap Body"
def test_get_presentation_title_for_empty_outline():
outline = PresentationOutlineModel(slides=[])
assert get_presentation_title_from_presentation_outline(outline) == "Untitled Presentation"
def test_slide_outline_content_is_trimmed_to_word_limit():
content = " ".join(
f"word{i}" for i in range(MAX_OUTLINE_CONTENT_WORDS + 3)
)
slide = SlideOutlineModel(content=content)
assert count_outline_words(slide.content) == MAX_OUTLINE_CONTENT_WORDS
assert f"word{MAX_OUTLINE_CONTENT_WORDS - 1}" in slide.content
assert f"word{MAX_OUTLINE_CONTENT_WORDS}" not in slide.content
def test_presentation_outline_rejects_more_than_max_slides():
with pytest.raises(ValidationError):
PresentationOutlineModel(
slides=[
SlideOutlineModel(content=f"## Slide {index}")
for index in range(MAX_NUMBER_OF_SLIDES + 1)
]
)
@pytest.mark.parametrize(
("n_outlines", "title_slide", "target_total_slides", "expected"),
[
(0, True, None, 0),
(12, True, None, 2),
(12, False, None, 2),
(8, True, 25, 3),
],
)
def test_calculate_no_of_toc_required_for_n_outlines(
n_outlines: int,
title_slide: bool,
target_total_slides: int | None,
expected: int,
):
assert (
get_no_of_toc_required_for_n_outlines(
n_outlines=n_outlines,
title_slide=title_slide,
target_total_slides=target_total_slides,
)
== expected
)
def test_get_presentation_outline_model_with_toc_inserts_expected_slide_structure():
outline = PresentationOutlineModel(
slides=[
SlideOutlineModel(content="## Title slide"),
SlideOutlineModel(content="## Market Overview"),
SlideOutlineModel(content="## Product Strategy"),
]
)
with_toc = get_presentation_outline_model_with_toc(
outline=outline,
n_toc_slides=1,
title_slide=True,
)
assert len(with_toc.slides) == 4
toc_content = with_toc.slides[1].content
assert toc_content.startswith("## Table of Contents")
assert "Page number: 3, Title: Market Overview" in toc_content
assert "Page number: 4, Title: Product Strategy" in toc_content
def test_extract_outline_title_uses_heading_then_sentence_then_fallback():
assert _extract_outline_title("## Heading title\nBody") == "Heading title"
assert _extract_outline_title("First sentence. Second sentence.") == "First sentence."
assert _extract_outline_title(" \nline fallback\n") == "line fallback"
assert _extract_outline_title("") == "Slide"
def test_get_images_for_slides_from_outline_deduplicates_and_filters():
slides = [
SlideOutlineModel(
content=(
"Image https://cdn.example.com/a.png and duplicate "
"https://cdn.example.com/a.png and invalid https://example.com/nope.txt"
)
),
SlideOutlineModel(content="No URL here"),
]
extracted = get_images_for_slides_from_outline(slides)
assert extracted[0] == ["https://cdn.example.com/a.png"]
assert extracted[1] == []