Skip to content

Cover the admin Releases page end to end - #990

Merged
selfcontained merged 1 commit into
mainfrom
agt_96e109566247/job-test-enforcer-9baa5337
Aug 22, 2026
Merged

Cover the admin Releases page end to end#990
selfcontained merged 1 commit into
mainfrom
agt_96e109566247/job-test-enforcer-9baa5337

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

What

release-admin.tsx and the five modules #970 split out of it — release-admin-banners.tsx, release-admin-create.tsx, release-admin-list.tsx, release-admin-unreleased.tsx, and use-release-admin-data.ts — had no test coverage at all. release-utils.ts and OperationTakeover were already covered (release-utils.test.ts, PR #982), so this file is scoped to the admin-only surfaces.

One test file mounts the real ReleasesAdmin with a fake EventSource for the release stream and a URL-routed fetch, so the props wiring between the shell, the four panes, and the data hook is exercised together rather than mocked apart.

What it pins

  • Unreleased changes — the ternary ladder in priority order: an unreleased-fetch error outranks a missing ref, which outranks the commit count. Plus the commit list, the +N more overflow line, and the singular/plural wording.
  • useReleaseAdminData — both mount fetches, the x-dispatch-release-client-id header that lets the server push info-progress back over the stream, refresh() hitting both endpoints, and the promote mutation: request body, the row flipping to stable on success, and a failed promote surfacing a cleaned error while the confirmation collapses so the operator gets the button back.
  • Promote confirm flow — scoped to the row the operator actually clicked, not every prerelease.
  • Create release — the render gate (hidden at a zero count, shown when the ref is missing), the bumped-tag previews taking the newest GitHub release over the deployed tag, the confirm dialog, the POST method and body, and the switch into the progress takeover. A rejected request shows the error and stays on the page.
  • Banners — in-flight, failed, and the watchedRelease guard that stops a stale done snapshot from claiming a release just finished, plus the refresh-once-per-run behaviour when one really does.

Validation

  • pnpm run check, pnpm run format, pnpm run lint:web (0 errors), pnpm run finalize:web — all clean
  • pnpm run test — server 164 files/2808 tests, web 72/1090 (1064 → 1090, +26), extension 9/60
  • pnpm run test:e2e — 181 passed / 12 skipped
  • pnpm run test:e2e:live — 11 passed in 20.8s, no stray e2e-* tmux sessions or leaked containers
  • Mutation battery: 45 mutants across the six modules, 45 killed. Three initial survivors were diagnosed rather than worked around — a promote confirmation that stayed open after a failed request, a failed release also reading as in-flight, and the non-create job-type filter — and each was killed by sharpening or adding an assertion.

A review pass over the diff found six items, all applied: the job fixture now uses the real Extract<ReleaseJob, { jobType: "create" }> wire type (a typo'd phase previously type-checked and silently gutted a test), four structurally-unfailable negative assertions on sibling ternary branches were deleted, and the client-id lookup got a guard so a missing call fails readably.

Test-only change; no product code touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dqcng3rgYPEToKrksY3FZk

`release-admin.tsx` and the five modules #970 split out of it
(`release-admin-banners`, `-create`, `-list`, `-unreleased`, and
`use-release-admin-data`) had no tests at all. This adds one file that
mounts the real `ReleasesAdmin` — a fake `EventSource` for the release
stream and a URL-routed `fetch` — so the props wiring between the shell,
the panes, and the data hook is exercised together rather than mocked
apart.
What it pins:
- the `UnreleasedChanges` ternary ladder, in priority order: an
unreleased-fetch error outranks a missing ref, which outranks the
commit count; plus the commit list, the `+N more` overflow line, and
the singular/plural wording
- `useReleaseAdminData`: both mount fetches, the client-id header that
lets the server push info-progress back over the stream, `refresh()`
hitting both endpoints, and the promote mutation — request body,
the row flipping to stable, and a failed promote surfacing a cleaned
error while the confirmation collapses
- the promote confirm flow scoped to the row the operator clicked
- the create section's render gate, the bumped-tag previews (newest
GitHub release wins over the deployed tag), the confirm dialog, the
POST body, and the switch into the progress takeover
- the banner set: in-flight, failed, and the `watchedRelease` guard that
keeps a stale done snapshot from claiming a release just finished,
plus the refresh-once-per-run behaviour when one really does
Mutation battery: 45 mutants against the six modules, 45 killed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dqcng3rgYPEToKrksY3FZk
@selfcontained
selfcontained merged commit f4ef1ae into mainAug 22, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_96e109566247/job-test-enforcer-9baa5337 branch August 22, 2026 02:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@selfcontained