diff --git a/tests/test_printer_form.py b/tests/test_printer_form.py index 2eb6a76..46a65f3 100644 --- a/tests/test_printer_form.py +++ b/tests/test_printer_form.py @@ -1,4 +1,7 @@ """Tests for printer form template wiring — inline driver upload + OOB select.""" +import io +import zipfile + from fastapi.testclient import TestClient @@ -39,3 +42,97 @@ def test_printer_form_has_inline_driver_upload(client: TestClient) -> None: 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." + )