Three failing test suites blocked CI. All three were test defects, not
application bugs.
Integration tests (integration/database.test.ts)
------------------------------------------------
The suite set NODE_ENV=test, which makes cache.cached() short-circuit both
its Redis read (src/lib/cache.ts:226) and its write (:249). A suite whose
stated purpose is exercising the real Redis path therefore never touched
Redis. Switched to NODE_ENV=development, the only non-production value
src/env.ts accepts, so the shared-cache code paths are genuinely covered.
Three assertions then needed correcting for real Redis semantics:
- `await cache.cached(...)` followed by `.resolves` can never hold: await
yields a value, not a Promise. Assert the value directly.
- A cached negative result is stored as the JSON encoding of null, so
`redis.get(key)` returns "null", not null.
- The news negative-cache key does not exist at all, so `ttl()` returned -2.
Now that the write path is live the key is created and the TTL assertion
holds as originally written.
UI tests (src/app/admin/prefixes/prefix-dialog.tsx)
---------------------------------------------------
The form-reset effect had `isOpen` removed from its dependency array. The
component returns null when closed, so the effect only ever ran on mount:
reopening the dialog no longer cleared the fields and a dismissed-but-
unsaved edit reappeared. Two tests in e2e/ui/unsaved-changes.spec.ts caught
this. Restored the dependency and documented why it is load-bearing.
The remaining edits in this branch drop stale biome-ignore comments that
suppressed useExhaustiveDependencies and noArrayIndexKey diagnostics. Where
the suppression had been load-bearing for behaviour, the underlying
dependency is now listed explicitly rather than silenced.
Verified: check (toolchain, audit, lint, i18n, typecheck), unit 3315
passed, integration 20 passed, UI 72 passed / 2 skipped.
- Split ManageClient into ManageSection, PresetsSection, TestSection,
ImportSection, ExportSection - each tab only renders what it needs
- Add loading/disabled states to preset, import, export, clear buttons
- Persist search and group filter via URL searchParams (survives refresh)
- Remove dead getAuditHistory export from actions
- Fix testRankPermission - remove unnecessary revalidatePath with JSON result
- Clean up unused errors/count variables in bulkImportPermissions
- Add 'loading' translation key to housekeeping section (en/nl)