Files
Donkie f475da2176 auth: integration tests and a11y coverage for the phase 2 surfaces
154 auth tests, up from 101. The new files cover API keys, user administration
and the audit log; two gaps phase 1 recorded are also closed.

test_levels.py said its read-versus-manage coverage was an approximation,
because the anonymous reader was the only low-level principal that could be
built without a command line. POST /auth/user changes that, so there is now a
genuine signed-in read user and a genuine edit user. That distinction matters:
a refusal for a real user can only be about its level, where an anonymous
caller failing the same request proves less, since allow_anonymous could have
been what stopped it. The edit level had never been exercised at all, and it is
the one that carries PUT /spool/{id}/use -- Moonraker's hot path, deliberately
below manage so a printer can record usage without being able to delete.

The route table in test_unauthenticated.py rejected the whole branch until all
thirteen new routes were listed, which is what it is for. It grew from 40
entries to 53.

The a11y audit could not see the auth screens: it runs against an
authentication-disabled build where sign-in never renders, so auditing it there
would have measured the library page twice and reported a pass. a11y-auth.spec
fixes that without a second Playwright config -- it asks the server what it is
and skips itself when auth is off, claims an unclaimed instance, and creates
its own must-change-password account to reach the forced-change screen. The
measurement code moved to audit.ts so both specs share it rather than one
copying the other.

Running it found ten controls under the advisory 44px tap target across the new
screens. Fixed rather than waived, because the phase 1 auth components were
built to 44px on purpose (see PasswordInput) and these belong with them, even
though settings and locations already sit at 30-34px. That left the native
18px checkbox, which LoginScreen has shipped since phase 1: the input is the
tap target, so a 44px label around it does not help. Checkbox.svelte draws an
18px box inside a 44px input with appearance:none, and both call sites use it.
Auth surfaces now report 0 axe violations and 0 undersized targets across 7
surfaces.

Verified: 154 auth tests pass with auth on; 372 regression tests pass with auth
off and no file under tests_integration/tests edited, which is the evidence
that phase 2 stayed additive.

Claude-Session: https://claude.ai/code/session_01J3YgMAnSapoXqS9iU8Xnmk
2026-07-28 14:25:23 +02:00
..
2026-07-27 20:09:43 +02:00
2026-07-28 13:10:55 +02:00