"""Tests for header/footer extraction and locked zones context."""
from landppt.services.prompts.design_prompts import DesignPrompts
# --- Default template HTML with slide-header and slide-footer classes ---
DEFAULT_TEMPLATE = """
{{ main_heading }}
{{ page_content }}
{{ current_page_number }}
"""
def test_extract_header_footer_from_default_template():
"""Should extract slide-header and slide-footer from standard template."""
result = DesignPrompts._extract_header_footer_html(DEFAULT_TEMPLATE)
assert "slide-header" in result["header_html"]
assert "slide-title" in result["header_html"]
assert "slide-footer" in result["footer_html"]
assert result["header_css"], "Header CSS should be extracted"
assert result["footer_css"], "Footer CSS should be extracted"
def test_extract_header_footer_from_template_without_semantic_classes():
"""Should fallback to position-based heuristics when no semantic classes."""
result = DesignPrompts._extract_header_footer_html(NO_SEMANTIC_TEMPLATE)
# Header may not be found without semantic classes - that's OK
# Footer should be found via absolute-positioned element with page number placeholder
assert "current_page_number" in result["footer_html"] or result["footer_html"] == ""
def test_extract_returns_empty_for_empty_template():
"""Should return empty dict values for empty/None template."""
result = DesignPrompts._extract_header_footer_html("")
assert result["header_html"] == ""
assert result["footer_html"] == ""
result2 = DesignPrompts._extract_header_footer_html(None)
assert result2["header_html"] == ""
assert result2["footer_html"] == ""
def test_locked_zones_context_for_content_page():
"""Content pages (not first/last/catalog) should get locked zone context."""
context = DesignPrompts._build_locked_zones_context(
DEFAULT_TEMPLATE, page_number=3, total_pages=10, slide_type="content")
assert "母板锁定区" in context
assert "Header 锁定结构" in context
assert "Footer 锁定结构" in context
assert "slide-header" in context
assert "slide-footer" in context
def test_locked_zones_context_empty_for_first_page():
"""First page should not get locked zone context."""
context = DesignPrompts._build_locked_zones_context(
DEFAULT_TEMPLATE, page_number=1, total_pages=10, slide_type="title")
assert context == ""
def test_locked_zones_context_empty_for_last_page():
"""Last page should not get locked zone context."""
context = DesignPrompts._build_locked_zones_context(
DEFAULT_TEMPLATE, page_number=10, total_pages=10, slide_type="thankyou")
assert context == ""
def test_locked_zones_context_empty_for_catalog_page():
"""Catalog page should not get locked zone context."""
context = DesignPrompts._build_locked_zones_context(
DEFAULT_TEMPLATE, page_number=2, total_pages=10, slide_type="catalog")
assert context == ""
# Also test title-based detection
context2 = DesignPrompts._build_locked_zones_context(
DEFAULT_TEMPLATE, page_number=2, total_pages=10, slide_type="content",
slide_title="目录概览")
assert context2 == ""
def test_locked_zones_fallback_for_unextractable_template():
"""When header/footer can't be extracted, should return fallback hint."""
minimal_template = "