From 2fb947e90845fecf89befc0282fbaad23507de2d Mon Sep 17 00:00:00 2001 From: Julian Cuni Date: Sun, 21 Jun 2026 16:25:21 +0200 Subject: [PATCH] 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 --- apps/vision/tests/conftest.py | 28 ++++++++++++++++++++++++++++ wiki/concepts/booth-console.md | 13 ++++++++++--- wiki/log.md | 20 ++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 apps/vision/tests/conftest.py diff --git a/apps/vision/tests/conftest.py b/apps/vision/tests/conftest.py new file mode 100644 index 0000000..568abf3 --- /dev/null +++ b/apps/vision/tests/conftest.py @@ -0,0 +1,28 @@ +"""Shared test fixtures. + +The stub-mode smoke tests must be deterministic regardless of the developer's local +apps/vision/.env (which may set VISION_RECOGNIZER=fast_alpr for real-model work). An OS +environment variable takes precedence over the .env file in pydantic-settings, so we +force stub mode for the whole test session before the app's lifespan builds the +recognizer. Tests that exercise the real recognizer set their own override explicitly. +""" + +from __future__ import annotations + +import os + +import pytest + + +@pytest.fixture(autouse=True) +def _force_stub_recognizer() -> None: + """Pin the recognizer to the model-free stub for every test (overrides .env).""" + prev = os.environ.get("VISION_RECOGNIZER") + os.environ["VISION_RECOGNIZER"] = "stub" + try: + yield + finally: + if prev is None: + os.environ.pop("VISION_RECOGNIZER", None) + else: + os.environ["VISION_RECOGNIZER"] = prev diff --git a/wiki/concepts/booth-console.md b/wiki/concepts/booth-console.md index f6dc252..18f70d8 100644 --- a/wiki/concepts/booth-console.md +++ b/wiki/concepts/booth-console.md @@ -148,8 +148,15 @@ screen, so the operator always sees the barrier relay's reachability and the pri and served 404s in this environment). ## Open -- **No automated frontend tests** — the booth/live-feed/modal logic is verified manually - (Playwright + curl + DB inspection), not by a suite. The standing test-harness gap (see - [[reconciliation]]-adjacent notes) now spans front and back. +- **Automated test coverage landed 2026-06-21** (was: "no automated tests anywhere"). `pnpm test` + now runs across all six packages (was shared + vision only): a fresh-SQLite harness + (`@parking/db/testing` → `createTestDb()`, real migrations, never the live DB) backs server-core + suites for the anti-fraud heart — event-log hash-chain + tamper detection, signer, occupancy + + reserved-spots, pay-station, the exit GATE, and the shift takings-split; `@parking/devices` pins the + ESC/POS byte stream (CP852 fallbacks + the Code128 width contract) and printer routing; an HTTP + integration suite boots the real Fastify app (`app.inject`) to exercise the auth/RBAC/CSRF guards; + and `@parking/web` covers the booth formatters + the focus-independent `useScanner` hook. **Still + manual (Playwright):** the live-feed/modal *rendering* and full booth UI flows — the front-end unit + layer covers pure logic + the scanner hook, not component rendering (no jsdom component suite yet). - The pre-existing admin screens (Setup/Tariff/Permits/Site/Shift) still carry their **old inline styles** — reachable and functional, not yet on the terminal component system. diff --git a/wiki/log.md b/wiki/log.md index 4f36305..b71d227 100644 --- a/wiki/log.md +++ b/wiki/log.md @@ -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]].