"""Tests for printer form template wiring — inline driver upload + OOB select.""" import io import zipfile from fastapi.testclient import TestClient def test_printer_form_has_inline_driver_upload(client: TestClient) -> None: """GET /printers/new renders printer form with: - Driver must have id="printer-form-driver-select" ' "for HTMX OOB swap to work" ) # Inline upload form posts caller=printer_form sentinel assert 'name="caller"' in html, 'Inline upload form missing name="caller" field' assert 'value="printer_form"' in html, ( 'Inline upload form missing value="printer_form" sentinel' ) # Inline upload form targets /drivers/upload assert 'hx-post="/drivers/upload"' in html, ( 'Inline upload form missing hx-post="/drivers/upload"' ) # Main printer form uses plain POST (no HTMX) so browser follows 303 redirect assert 'action="/printers"' in html, ( 'Printer form must use action="/printers" (plain HTML form, not hx-post)' ) assert 'method="post"' in html, ( 'Printer form must use method="post"' ) # --------------------------------------------------------------------------- # Wave 0 smoke tests — driver-list visibility and upload feedback (15-01) # --------------------------------------------------------------------------- _SAMPLE_INF_FORM = """\ [Version] Signature="$Windows NT$" Class=Printer Provider=%MFG% [Manufacturer] %MFG%=Models,NTamd64 [Models.NTamd64] %DRIVER_NAME%=Install,{12345678-1234-1234-1234-123456789012} [Strings] MFG="Test Manufacturer" DRIVER_NAME="Test LaserJet Pro" """ def _make_driver_zip_for_form_test( inf_content: str = _SAMPLE_INF_FORM, inf_name: str = "sample.inf", ) -> bytes: """Build an in-memory ZIP with one .inf file for printer form tests. Do NOT import _make_driver_zip from test_driver_upload.py — replicated here as a standalone local helper per plan instructions. """ buf = io.BytesIO() with zipfile.ZipFile(buf, "w", compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(inf_name, inf_content.encode("utf-8")) return buf.getvalue() def test_printers_new_driver_list_visible(client: TestClient) -> None: """GET /printers/new: #driver-list anchor exists and is NOT hidden. BUG (15-UX-01): printers_new.html line 98 has style="display:none" on #driver-list. The HTMX outerHTML swap succeeds but the confirmation content (driver name + table) is invisible. Fix: remove the style attribute. RED: This test FAILS until the style="display:none" is removed from printers_new.html. """ resp = client.get("/printers/new") assert resp.status_code == 200 # Anchor must exist (HTMX hx-target="#driver-list" requires this id) assert 'id="driver-list"' in resp.text, ( '#driver-list anchor missing from /printers/new — HTMX swap target not present' ) # Anchor must NOT be hidden — technician must see upload confirmation assert 'id="driver-list" style="display:none"' not in resp.text, ( '#driver-list has style="display:none" — upload confirmation will be invisible. ' 'Remove the style attribute from printers_new.html.' ) def test_upload_feedback_visible_on_printers_new(client: TestClient) -> None: """POST /drivers/upload with caller=printer_form: response contains driver name + OOB select. The server already returns the correct fragment (driver name in primary content, hx-swap-oob select in sibling). This test guards against regression of the server-side OOB contract while the DOM-side visibility bug is fixed separately in printers_new.html. NOTE: This test may PASS even before the template fix because the bug is DOM-side (hidden div) not server-side (response fragment is correct). """ zip_bytes = _make_driver_zip_for_form_test() resp = client.post( "/drivers/upload", files={"file": ("driver.zip", zip_bytes, "application/zip")}, data={"caller": "printer_form"}, ) assert resp.status_code == 200 # Upload confirmation: driver name must appear in the response fragment assert "Test LaserJet Pro" in resp.text, ( 'Upload response does not contain driver name "Test LaserJet Pro" — ' "upload confirmation content missing from server fragment" ) # OOB select must still be present (regression guard — dropdown refresh) assert 'hx-swap-oob="true"' in resp.text, ( 'Upload response missing hx-swap-oob="true" — OOB select refresh broken. ' "Regression in driver_upload_with_oob.html or upload handler." )