test(ui): cover app.runs mapping helpers and SavedViews - #8777
Conversation
app.runs.tsx's mapSignalFidelity, mapAgentRunKind, and mapAgentRunBundle helpers and the SavedViews save/apply/remove flow had zero direct test coverage. Export the three helpers and the SavedViews component from the route module, unit-test every mapping branch (all four data-quality statuses, all four kind mappings plus the null/unknown default, the four-level repo fallback chain, the surface-to-source/boundary mapping, the scoring-snapshot and created_at fallbacks, string-only recommendation filtering, and object-only snapshot-replay construction with non-array counterfactual pooling), and add render tests that save a named view, assert it persists to localStorage, apply it back through onApply, and remove it. The sonner mock becomes callable to match SavedViews' bare toast(...) removal announcement.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-26 04:25:29 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Visual previewClick any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. Scroll preview
A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|









Closes #8701
What
apps/loopover-ui/src/routes/app.runs.tsx's pure mapping helpers —mapSignalFidelity,mapAgentRunKind,mapAgentRunBundle(including its four-level repo fallback chain and the counterfactuals-pooling / snapshot-replay construction) — and theSavedViewssave/apply/remove flow had zero direct test coverage:app.runs.test.tsxonly covered the drawer's copy buttons and the filter-bar reset control.How
The three helpers and the
SavedViewscomponent gain anexportkeyword — no behavior change, no signature change — so the test file can exercise them directly. The file's sonner mock becomes a callable base (Object.assign(vi.fn(), { success, error })) becauseSavedViews' remove flow announces through baretoast(...), which the previous{ success, error }-only mock could not represent; the existing copy-button assertions are untouched.app.runs.test.tsxgrows four suites (25 tests in the file total, all passing):mapSignalFidelity— all 4 branches:complete→ ready,degraded→ degraded,blocked→ blocked, and theunknowndefault → stale.mapAgentRunKind— all 4 branches:preflight_branch,prepare_pr_packet, bothexplain_blockersandexplain_branch_blockers→explain-blockers, and the default (nulland unrecognized strings) →plan-next-work.mapAgentRunBundle— each level of the repo fallback chain (targetRepoFullNamepresent; blank/absent →payload.repoFullName; absent →payload.input.repoFullName;inputnot even a record →"unknown"), plus: surface → source/boundary mapping for all three surfaces (github_comment→github-command/public,mcp→ private-mcp,api→ private-api), kind and data-quality routing through the two helpers above, thescoringModelId→decisionPackVersion→"live"ruleset-snapshot fallback, thecreatedAt→updatedAt→ fresh-timestamp fallback, string-only recommendation filtering withranked_actionscounting, and snapshot-replay construction that keeps only object-shapedrecommendationSnapshots (string/array/absent are dropped) while a non-arraycounterfactualReasonspayload is ignored rather than crashing the pooling.SavedViews— a full render flow: save a named view (open the naming form, type, submit), assert the chip appears, the empty state clears,toast.successannounces it, and it persists tolocalStorage["loopover.runs.views"]; apply it and assertonApplyreceives the saved{status, kind, q}; remove it and assert the chip disappears, the bare-toastannouncement fires, and storage empties. Companion tests pin the disabled save affordance when no filter is active and the blank-name no-op.Deliverables (all in this one PR)
mapSignalFidelitytested for all 4 branches, including the default/fallthrough case.mapAgentRunKindtested for all 4 branches.mapAgentRunBundletested exercising each level of the repo-fallback chain (targetRepoFullNamepresent, absent-falls-to-payload.repoFullName, absent-falls-to-input?.repoFullName, all absent-falls-to-"unknown").SavedViewsrender test: save a view, confirm it appears in the list, apply it, remove it.Validation
app.runs.test.tsx: 25 tests, all passing (10 pre-existing + 15 new).@loopover/uisuite: 88 test files, 600 tests, all passing;@loopover/ui-minersuite (37 files, 393 tests) also green (npm run ui:test).npm run ui:typecheckgreen.prettier --checkandeslintclean on both changed files (0 errors).apps/**is excluded fromcodecov/patch; the app's own vitest suite gates locally.)UI Evidence
This PR is test-only plus an
exportkeyword on four existing symbols — it intentionally changes no rendered pixels, so each row's Before and After captures are identical, taken from the same build. Captured on/app/runsserved locally (vite dev, local preview session per the contributor skill), with/v1/auth/sessionand/v1/agent/runsanswered at the network boundary by fixtures shaped like the new tests' bundles (other private endpoints answer 500). The rendered list ismapAgentRunBundle's output end-to-end: the READYpreflight-branchrun from anmcpsurface resolvingJSONbored/loopoverthroughtargetRepoFullName, the DEGRADEDplan-next-workrun whosegithub_commentsurface renders asgithub-command, and a BLOCKEDexplain-blockersrun falling back through the repo chain — with theSavedViews"Views" row above the list. The UI is a dark-mode-only build, so the Light and Dark rows (captured under emulatedprefers-color-scheme) render identically by design. Viewports: 1280×800 / 768×1024 / 375×812.