test(vision): fix stub-mode tests; close the testing-gap wiki note

The two failing apps/vision smoke tests assumed stub mode but the local .env sets
VISION_RECOGNIZER=fast_alpr (real-model work, 2026-06-19), so the app built the real
recognizer: /health reported "fast_alpr" not "stub", and /analyze on garbage bytes
422'd (real decode reject) instead of returning the empty stub contract.

Fix is test isolation: a conftest autouse fixture pins VISION_RECOGNIZER=stub for the
session (an OS env var overrides the .env in pydantic-settings), restoring it after.
vision 7/7.

Updates wiki/concepts/booth-console.md (the "no automated tests" Open note now reflects
the coverage that landed) and appends wiki/log.md.

Full workspace: shared 87, server 75, devices 18, web 17, vision 7 = 204 tests across
8 turbo test tasks, 0 failures; build/lint 14/14.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-06-21 16:25:21 +02:00
parent cae900afd2
commit 2fb947e908
3 changed files with 58 additions and 3 deletions
+20
View File
@@ -1309,3 +1309,23 @@ setActiveTicket. Ignores keystrokes into editable fields so the manual ticket in
paused while a modal is open so a scan can't abandon an in-progress payment. Verified at runtime
(Playwright): scan with focus on BODY opens the modal; second scan while open is ignored; slow typing
doesn't trigger; manual form submit still works. build+lint 14/14. See [[booth-console]].
## [2026-06-21] test | Automated test coverage across every service (was shared + vision only)
Added a fresh-SQLite test harness and suites for all six packages; `pnpm test` (turbo `test` task) now
covers them all (previously only @parking/shared + @parking/vision had test scripts). New
`@parking/db/testing` exports `createTestDb()` — an in-memory SQLite with the real Drizzle migrations
applied, so server tests run against the production schema with NO live-DB risk. Coverage: **server**
(anti-fraud core) — event-log hash-chain linkage + `verifyChain` catching every tamper class (edited
payload, deleted row/index gap, broken prevHash, unknown keyId), signer round-trip/forgery/rotation,
occupancy fold + reserved-spots (no double-count of a parked subscriber), pay-station quote/sign/lookup,
the exit GATE (refuse unknown/unpaid/grace-expired; no booth subscription bypass; assist path), and the
shift takings-SPLIT by source (subscription sales vs out-of-window vs transient tickets) + drawer
carry-forward + Z-report; plus an HTTP integration suite booting the real Fastify app via `app.inject`
for the auth/RBAC/CSRF guards. **devices** — ESC/POS byte stream (CP852 ë/Ë mapping + em-dash/⚠ ASCII
fallbacks, no stray "?"; the Code128 module-width contract: width 2 for the ~20-char out-of-window id so
it fits the 80mm head) + printer-routing failover. **web** — booth formatters + the focus-independent
`useScanner` hook (jsdom). **vision** — fixed 2 pre-existing stub-mode test failures via a conftest
autouse fixture that pins `VISION_RECOGNIZER=stub` (the dev `.env` had set `fast_alpr`, which broke the
model-free smoke tests). Also stopped `*.test.ts` leaking into shipped `dist/` (server + shared
tsconfig excludes). Totals: shared 87, server 75, devices 18, web 17, vision 7 = 204 tests; build/lint
14/14. See [[booth-console]].