- test_printers_new_driver_list_visible: RED before fix — asserts #driver-list exists and is not hidden - test_upload_feedback_visible_on_printers_new: guards OOB contract (driver name + hx-swap-oob in response) - Added io, zipfile imports and local _make_driver_zip_for_form_test helper Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
139 lines
5.1 KiB
Python
139 lines
5.1 KiB
Python
"""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 <select> with stable id="printer-form-driver-select"
|
|
- Inline upload form with caller=printer_form hidden field
|
|
- hx-post="/drivers/upload" for the driver upload sub-form
|
|
- Plain <form action="/printers" method="post"> for the printer (no HTMX on main form)
|
|
|
|
Updated in 11-01: form moved from /printers to /printers/new (UIE-02).
|
|
"""
|
|
resp = client.get("/printers/new")
|
|
assert resp.status_code == 200
|
|
html = resp.text
|
|
|
|
# Driver select has stable id for OOB swap target
|
|
assert 'id="printer-form-driver-select"' in html, (
|
|
'Printer form driver <select> 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."
|
|
)
|