The gap
store/admin has zero tests — and as of 66fcc23 (#38/#41) it holds the most destructive controls in the product: suspend a user, unpublish or delete an agent, cancel an instance, change roles, revoke keys.
This needs no new infrastructure. vitest.config.ts already globs store/*/src/**/*.test.ts in its UNIT_TESTS project, with a comment noting the console was once missing from that glob so anything added there "would have passed locally and never run in CI". The harness is there; admin simply has nothing to run.
store/console shows the established pattern: 9 test files, all .test.ts (never .tsx), all pure logic extracted into lib/*.ts — surfaces, workInFlight, identity, triggerSchedule, teamwork. Zero render any component.
What to test
Follow that pattern — extract the decisions out of JSX into pure modules, then test the modules:
- Runtime status derivation. Four states, not two: live (relay socket) / offline / unknown (the list's fan-out budget returns
null past 50) / no-runner-ever-registered. The bug this prevents is rendering null as offline — the DB's instance_runtime_nodes.status is never cleared on an unclean disconnect and already lies in the other direction, so a second wrong answer here is how an operator kills a healthy machine.
force is never sent on the first attempt. The 409 must be surfaced with its live-subscriber count before forcing is offered at all.
- Echo gates: delete requires the slug, key revoke requires an explicit provider, suspend requires the login. Assert that a mismatched or empty echo cannot produce a request.
- Key revoke is per-provider. An omitted provider must never widen to "all keys".
- Self-targeting is refused — self-suspend and self-demote both lock the only operator out.
- Filter + pagination state — the page and the
COUNT share one predicate server-side; assert the client can't send a filter to one and not the other.
Acceptance
Related: #38, #41. Sibling gap for JSX-resident logic: see the component-testing issue.
The gap
store/adminhas zero tests — and as of66fcc23(#38/#41) it holds the most destructive controls in the product: suspend a user, unpublish or delete an agent, cancel an instance, change roles, revoke keys.This needs no new infrastructure.
vitest.config.tsalready globsstore/*/src/**/*.test.tsin itsUNIT_TESTSproject, with a comment noting the console was once missing from that glob so anything added there "would have passed locally and never run in CI". The harness is there; admin simply has nothing to run.store/consoleshows the established pattern: 9 test files, all.test.ts(never.tsx), all pure logic extracted intolib/*.ts—surfaces,workInFlight,identity,triggerSchedule,teamwork. Zero render any component.What to test
Follow that pattern — extract the decisions out of JSX into pure modules, then test the modules:
nullpast 50) / no-runner-ever-registered. The bug this prevents is renderingnullas offline — the DB'sinstance_runtime_nodes.statusis never cleared on an unclean disconnect and already lies in the other direction, so a second wrong answer here is how an operator kills a healthy machine.forceis never sent on the first attempt. The 409 must be surfaced with its live-subscriber count before forcing is offered at all.COUNTshare one predicate server-side; assert the client can't send a filter to one and not the other.Acceptance
src/lib/*.tsrather than tested through a component.Related: #38, #41. Sibling gap for JSX-resident logic: see the component-testing issue.