feat(09-01): add inline driver upload to printer form with OOB refresh
- Add id="printer-form-driver-select" to driver <select> (OOB swap target) - Add sibling <form hx-post="/drivers/upload"> AFTER printer </form>, inside Alpine x-data div — avoids invalid nested form HTML - Hidden <input name="caller" value="printer_form"> sentinel triggers OOB path - Add hidden <div id="driver-list"> anchor for HTMX outerHTML swap target - Create tests/test_printer_form.py with test_printer_form_has_inline_driver_upload asserting stable select id, caller sentinel, and non-nested upload form Full non-e2e suite: 112 passed.
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<label>
|
<label>
|
||||||
Driver
|
Driver
|
||||||
<select name="driver_id">
|
<select name="driver_id" id="printer-form-driver-select">
|
||||||
<option value="">-- No driver --</option>
|
<option value="">-- No driver --</option>
|
||||||
{% for item in driver_data %}
|
{% for item in driver_data %}
|
||||||
<option value="{{ item.driver.id }}"
|
<option value="{{ item.driver.id }}"
|
||||||
@@ -83,4 +83,17 @@
|
|||||||
|
|
||||||
<button type="submit">Save Printer</button>
|
<button type="submit">Save Printer</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form hx-post="/drivers/upload"
|
||||||
|
hx-target="#driver-list"
|
||||||
|
hx-encoding="multipart/form-data"
|
||||||
|
hx-swap="outerHTML">
|
||||||
|
<input type="hidden" name="caller" value="printer_form">
|
||||||
|
<label>
|
||||||
|
Upload New Driver
|
||||||
|
<input type="file" name="file" accept=".zip" required>
|
||||||
|
</label>
|
||||||
|
<button type="submit" class="secondary">Upload Driver</button>
|
||||||
|
</form>
|
||||||
|
<div id="driver-list" style="display:none"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
"""Tests for printer form template wiring — inline driver upload + OOB select."""
|
||||||
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
|
||||||
|
def test_printer_form_has_inline_driver_upload(client: TestClient) -> None:
|
||||||
|
"""GET /printers 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" NOT nested inside the printer <form>
|
||||||
|
"""
|
||||||
|
resp = client.get("/printers")
|
||||||
|
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\""
|
||||||
|
)
|
||||||
|
|
||||||
|
# CRITICAL: hx-post="/drivers/upload" must NOT be nested inside the printer form.
|
||||||
|
# Split on the printer form boundary and verify the upload endpoint is not inside it.
|
||||||
|
# The printer form always starts with hx-post="/printers" and ends at its </form>.
|
||||||
|
printer_form_start = html.find('hx-post="/printers"')
|
||||||
|
assert printer_form_start != -1, "Printer form hx-post not found — template changed?"
|
||||||
|
|
||||||
|
# Find the first </form> after the printer form opening tag
|
||||||
|
printer_form_end = html.find("</form>", printer_form_start)
|
||||||
|
assert printer_form_end != -1, "Printer form closing </form> not found"
|
||||||
|
|
||||||
|
printer_form_chunk = html[printer_form_start:printer_form_end]
|
||||||
|
assert 'hx-post="/drivers/upload"' not in printer_form_chunk, (
|
||||||
|
"hx-post=\"/drivers/upload\" must NOT be nested inside the printer <form> — "
|
||||||
|
"HTML forbids nested forms and browsers silently ignore the inner one"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user