"""Phase 7 job traveler builder: the page count, the work order boxes (the QR text is a barcode, never text; the work order, lot and seq are text), the blanks for a packet with no heats, the sign-off rows after signed steps, the note for a packet with no work orders, the stamp and the metadata.""" from __future__ import annotations from collections.abc import Iterator from datetime import UTC, datetime from typing import Any import pytest from closehelpers import at_complete, builder_conn, flat, page_texts, pdf_reader, who from fakedir import FakeDirectory from pkthelpers import make_draft from pshelpers import needs_pg from shophelpers import BOM3, WOS, Shop, draft, make_unit, open_shop from packetstation.pdf import traveler from packetstation.settings import Settings pytestmark = needs_pg NOW = datetime(2026, 10, 17, 21, 4, tzinfo=UTC) @pytest.fixture def shop(pg_settings: Settings, fake_dir: FakeDirectory, dev_visual: None) -> Iterator[Shop]: yield from open_shop(pg_settings, fake_dir) def build(shop: Shop, pid: int) -> Any: with builder_conn(shop.settings) as conn: return traveler.build(conn, shop.settings, pid, who=who(shop), now=NOW) def test_traveler_of_a_draft(shop: Shop) -> None: """A draft with no signed step yet (no drawing attached, so no signed attach row): the blank sign-off rows.""" _, unit_id = make_unit(shop.settings) pkt = make_draft(shop("clerk.clara"), unit_id, bom=BOM3, work_orders=WOS) built = build(shop, pkt["id"]) assert built.bytes[:5] == b"%PDF-" reader = pdf_reader(built.bytes) assert len(reader.pages) == built.pages >= 1 texts = page_texts(built.bytes) text = flat(" ".join(texts)) assert "JOB TRAVELER" in text.upper() for wo in ("L670001", "L670002"): assert wo in text assert "Lot 001" in text and "Seq" in text # the QR payload is drawn as a barcode, never as text assert "*%2" not in text and "$001$0$0$" not in text # no heats yet: blanks assert "________" in text assert "Work complete (stall)" in text and "Supervisor review" in text and "Q.C. inspection" in text project = pkt["unit"]["project"]["number"] for i, t in enumerate(texts): ft = flat(t) assert "Controlled copy - exported by Clara Clerk (4001)" in ft, i assert f"Page {i + 1} of {len(texts)}" in ft, i assert reader.metadata.title == f"{project} Lot 001 Job Traveler", reader.metadata.title assert reader.metadata.producer == "Packet Station" def test_traveler_after_signed_steps(shop: Shop) -> None: pkt = at_complete(shop) text = flat(" ".join(page_texts(build(shop, pkt["id"]).bytes))) assert "Andy Welder (3003)" in text # signed the submit assert "Wes Super (2003)" in text # signed the send to Q.C. assert "Quinn QC (5001)" in text # signed the accept assert "Work complete (stall)" not in text assert "HT-10" in text # the heats pulled in the warehouse assert "Q.C. ACCEPTED" in text def test_traveler_without_work_orders(shop: Shop) -> None: pkt = draft(shop, wos=[]) text = flat(" ".join(page_texts(build(shop, pkt["id"]).bytes))) assert "No work orders were read from this packet." in text