""" PDF generation tests for Scenar Creator v4. """ import pytest from app.core.pdf_generator import generate_pdf from app.core.validator import ScenarsError from app.models.event import ScenarioDocument, Block, ProgramType, EventInfo def make_doc(**kwargs): defaults = { "version": "1.0", "event": EventInfo(title="Test PDF", subtitle="Subtitle", date_from="2026-03-01", date_to="2026-03-01"), "program_types": [ ProgramType(id="ws", name="Workshop", color="#0070C0"), ], "blocks": [ Block(id="b1", date="2026-03-01", start="09:00", end="10:00", title="Test Program", type_id="ws", responsible="John"), ] } defaults.update(kwargs) return ScenarioDocument(**defaults) def test_generate_pdf_basic(): doc = make_doc() pdf_bytes = generate_pdf(doc) assert isinstance(pdf_bytes, bytes) assert len(pdf_bytes) > 0 assert pdf_bytes[:5] == b'%PDF-' def test_generate_pdf_is_single_page(): import re doc = make_doc() pdf_bytes = generate_pdf(doc) # Count /Type /Page (not /Pages) occurrences pages = len(re.findall(rb'/Type\s*/Page[^s]', pdf_bytes)) assert pages == 1, f"Expected 1 page, got {pages}" def test_generate_pdf_multiday(): doc = make_doc( event=EventInfo(title="Multi-day", date_from="2026-03-01", date_to="2026-03-02"), program_types=[ ProgramType(id="key", name="Keynote", color="#FF0000"), ProgramType(id="ws", name="Workshop", color="#0070C0"), ], blocks=[ Block(id="b1", date="2026-03-01", start="09:00", end="10:00", title="Day 1", type_id="key", responsible="Alice"), Block(id="b2", date="2026-03-02", start="14:00", end="15:00", title="Day 2", type_id="ws", responsible="Bob"), ] ) pdf_bytes = generate_pdf(doc) assert isinstance(pdf_bytes, bytes) assert pdf_bytes[:5] == b'%PDF-' def test_generate_pdf_overnight_block(): """Block crossing midnight (end < start) should render without error.""" doc = make_doc( blocks=[ Block(id="b1", date="2026-03-01", start="22:00", end="01:30", title="Noční hra", type_id="ws", responsible="Honza"), ] ) pdf_bytes = generate_pdf(doc) assert pdf_bytes[:5] == b'%PDF-' def test_generate_pdf_empty_blocks(): doc = make_doc(blocks=[]) with pytest.raises(ScenarsError): generate_pdf(doc) def test_generate_pdf_missing_type(): doc = make_doc( blocks=[ Block(id="b1", date="2026-03-01", start="09:00", end="10:00", title="Test", type_id="UNKNOWN"), ] ) with pytest.raises(ScenarsError): generate_pdf(doc) def test_generate_pdf_with_full_event_info(): doc = make_doc( event=EventInfo( title="Full Event", subtitle="With all fields", date_from="2026-03-01", date_to="2026-03-03", location="Prague" ), program_types=[ ProgramType(id="ws", name="Workshop", color="#0070C0"), ProgramType(id="rest", name="Odpočinek", color="#22C55E"), ], blocks=[ Block(id="b1", date="2026-03-01", start="09:00", end="10:00", title="Session 1", type_id="ws"), Block(id="b2", date="2026-03-02", start="10:00", end="11:00", title="Session 2", type_id="rest"), Block(id="b3", date="2026-03-03", start="08:00", end="09:00", title="Session 3", type_id="ws"), ] ) pdf_bytes = generate_pdf(doc) assert pdf_bytes[:5] == b'%PDF-' def test_generate_pdf_multiple_blocks_same_day(): doc = make_doc( blocks=[ Block(id="b1", date="2026-03-01", start="09:00", end="10:00", title="Morning", type_id="ws"), Block(id="b2", date="2026-03-01", start="10:00", end="11:30", title="Midday", type_id="ws"), Block(id="b3", date="2026-03-01", start="14:00", end="16:00", title="Afternoon", type_id="ws", responsible="Team"), ] ) pdf_bytes = generate_pdf(doc) assert pdf_bytes[:5] == b'%PDF-' def test_generate_pdf_many_types_legend(): """Many program types should fit in multi-column legend.""" types = [ProgramType(id=f"t{i}", name=f"Typ {i}", color=f"#{'%06x' % (i * 20000)}") for i in range(1, 9)] blocks = [Block(id=f"b{i}", date="2026-03-01", start=f"{8+i}:00", end=f"{9+i}:00", title=f"Blok {i}", type_id=f"t{i}") for i in range(1, 9)] doc = make_doc(program_types=types, blocks=blocks) pdf_bytes = generate_pdf(doc) assert pdf_bytes[:5] == b'%PDF-'