Cover the SSE event dispatch table in use-sse - #959
Merged
Conversation
The reconnect state machine added in #921 was already well covered, but `handleSSEMessage` — the table that routes ~20 server push types into react-query cache writes — was not. Only `snapshot` was exercised, and only as a delivery vehicle for the backoff tests, with nothing asserted about what it does to the cache. Every realtime update in the app flows through this function. Adds 23 tests driving the real hook through the fake EventSource, so the routing itself is what gets pinned: which payload reaches which key, the `exact` scoping that keeps one agent's event from refetching every other agent's list, the review-detail invalidation predicate, the ack that must only fire when a notification was actually shown, and the tolerance of an unparseable or unrecognized frame. Also covers the connection gate — the stream must not open before authentication, including on the foreground path, which reopens without re-running the effect. Mutation battery: 50 mutants, 47 killed. The three survivors are provably unobservable rather than uncovered — `patchAgentHasStream`'s no-op guard and `media.seen`'s `!file.seen` guard are each redundant with react-query structural sharing, and `applyReviewCreated`'s null guard only ever skips an element-identical rewrite. An earlier draft asserted referential stability to chase the first two; those assertions were dropped because no change to use-sse.ts can fail them, which made them a test of react-query rather than of this hook. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Recurring Test Enforcer run for 2026-08-14.
Local suite: green on the first pass (27th consecutive)
pnpm run checkpnpm run format.prettierignorefix still holdingpnpm run testpnpm run test:e2epnpm run test:e2e:livee2e-*tmux sessions (18th consecutive)pnpm run finalize:webCI scan of the last 50 runs: 49 success. The single failure is the already-triaged Release-workflow guard (
origin/main advanced after smoke tests) aborting v0.33.12 during a merge race — working as designed, not a test failure. No new flakes; the Brain flakes list stays empty.No failures to triage, no flaky tests, and no product bugs found this run, so the effort went to the queued
next_focuscoverage gap.What this adds
use-sse.tshas two halves. The fatal-EventSource reconnect state machine from #921 was already well covered — 8 tests spanning fatal vs. transient errors, exponential backoff, theSTABLE_CONNECTION_MShealth gate, connection-age vs. instance-age across an internal retry, hidden-tab cancellation, and unmount.The other half,
handleSSEMessage, was not covered at all. It is the wiring hub for the whole realtime UI: ~20 server push types, each routed into a specific react-query cache mutation or invalidation. Onlysnapshotwas exercised, and only as a delivery vehicle for the backoff tests — nothing asserted what any event does to the cache.23 tests now drive the real hook through the fake
EventSource, so the routing itself is what gets pinned rather than any helper in isolation:exact: trueflags that stop one agent's event from refetching every other agent's media or message list, and the review-detail invalidation predicate, verified against matching and non-matching keys.Mutation battery
50 mutants against
use-sse.ts, 47 killed.The first pass killed 45/49 and surfaced one real weakness: the foreground path re-checks auth, but the original gating test never fired
visibilitychangewhile unauthenticated. Fixed and killed.The remaining three survivors were diagnosed rather than papered over, and are provably unobservable:
patchAgentHasStream'shasStream !== hasStreamguard andmedia.seen's!file.seenguard are each redundant with react-query's structural sharing.applyReviewCreated'sif (!reviewerAgentId) returnonly ever skips an element-identical rewrite.An earlier draft asserted referential stability to chase the first two. Review pointed out that no change to
use-sse.tscan make those assertions fail — only disablingstructuralSharingon theQueryClientcan — so they were testing react-query, not this hook. They were dropped, and the redundancy is recorded in the Brain backlog as a product-cleanup candidate instead.Review
One general review agent inspected this run's diff and returned four items. Three applied:
survives an ack request that rejectscould never fail — the entire dispatch runs insidetry/catch, sonot.toThrow()passed with.catch()deleted. Rewritten to assert the rejection handler is attached; this kills a mutant that previously survived.toEqualis kept for the job/template/brain case, where the order is the test's own emit sequence and is what proves each event maps to its own collection.Declined: deleting a pre-existing pure-helper test that the new integration test dominates. It is harmless, and removing existing passing coverage is out of scope for a test-health run.
🤖 Generated with Claude Code