Repository navigation
test(server): pin api fallback guards; fix API-only banner (#281) - #285
Conversation
Relates to #281 - N1: lock the bare "/api" arm of apiRoutesShadowedByFallback with a late-route test (kills mutant D from the #266 re-review). - N2: lock getRouteHandler's self-dispatch guard with a direct unit test (kills mutant L); the HTTP-level suite can't observe this guard since the recursive call it would otherwise allow carries Method: GET and lands on byte-identical output. - N3: rename TestPostPacketsRemovedFallsThroughToSPAInProductionRouter to TestPostPacketsRemovedReturns405NotSPAInProductionRouter to match the 405 + Allow assertion it's pinned since #266. - N4: point the API-only banner at /api/docs instead of the now-404 bare /api/. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rapport — CS-MacBook PR#285 #281 — head f7acaf8Status: All four follow-ups done, local verification + full CI green, no open blockers. Requirements
Evidence legend: [T] automated Go test in the suite, [A] manual/live check run locally this session, [K] known/accepted gap. Additional live verification [A]Built Grepped every Scope / guardrails
CI (per job, GitHub Actions on this PR)
No failures in any job — the known-flaky #271 did not surface, so no rerun was needed. Local verification (this session, before pushing)
Rester (leftovers / out of scope)
|
Review — CS-Macmini PR#285 — head f7acaf8Dom: APPROVE med nits Independent read-only review. Verified on the merged tree Findings
Nothing blocking. All three follow-up fixes do what #281 asks, each with a test that is red on the corresponding mutant and green on the fix. Point-by-pointN1 — bare- N2 — self-dispatch guard in N3 — stale test name. Met. N4 — API-only banner. Met in the sense the issue asked for: the banner now names a path that resolves ( Scope. Clean. The diff is three files: two Go test files and one text literal. No behaviour change outside the banner string. Mutants I ran myself
Edge case I added and ranThe one in F3: a real So the bare- Tests I ranOn the merged tree (
Every line matches the author's report. [A]
CI — checked per job myselfRun
Neither of the known flakes (#256 Hash Stats sort, #267 backfill write-hold) surfaced; no rerun was needed. The PR body's "GitHub Actions CI on this PR has not been inspected from this session yet" is now stale — the later report comment has the per-job table and it matches what I see. Not verified
Evidence legend: [T] automated test I ran, [A] manual/live check I ran, [K] known/accepted gap. |
Relates to #281
Summary
Four small follow-ups from the round-2 re-review of #266 (merged as
81b13b20, review comment on #266):apiRoutesShadowedByFallback(cmd/server/api_fallback.go:147) flags a late/apiroute viatmpl == "/api" || strings.HasPrefix(tmpl, "/api/"). The existingTestAPIRoutesShadowedByFallbackReportsLateRoutesonly registers late routes under the prefix (/api/late,/api/late/{id}), so dropping thetmpl == "/api"arm left the suite green (mutant D). AddedTestAPIRoutesShadowedByFallbackReportsLateBareAPIRoute, which registers a late route at exactly/apiand asserts it's reported as shadowed.getRouteHandler's self-dispatch guard (cmd/server/api_fallback.go:123) returnsnilwhen the only route a GET would reach is the fallback itself. Removing it left the suite green (mutant L) because the recursive call it would otherwise allow carriesMethod: GET, which lands on the exact same 404/405 computation and produces byte-identical HTTP output — no black-box test can distinguish the two. AddedTestGetRouteHandlerSelfDispatchGuardReturnsNilForUnknownPath, a white-box unit test callinggetRouteHandlerdirectly and asserting it returns(nil, nil).TestPostPacketsRemovedFallsThroughToSPAInProductionRouterhas asserted 405 +Allowsince fix(server): JSON 404/405 for unknown /api paths and wrong methods #266 (the doc comment was already updated then; the name wasn't). Renamed toTestPostPacketsRemovedReturns405NotSPAInProductionRouter.cmd/server/main.go(served bynewHTTPRouterwhen the static/public directory doesn't exist) said "API available at/api/", which fix(server): JSON 404/405 for unknown /api paths and wrong methods #266 turned into a JSON 404. Checked what actually resolves:/api/docs(interactive Swagger UI,routes.go:430) and/api/spec(raw OpenAPI JSON,routes.go:429) both exist; picked/api/docsas the more useful human-facing pointer. AddedTestAPIOnlyBannerPointsToExistingEndpoint, which builds the production router with a missing public dir and asserts the banner text names/api/docsand that a GET to it actually returns 200.Not touched
cmd/serverstays read-only; no SQL added.map[string]interface{}outside tests.deploy.yml9,release-fast-path.yml1 (grepped, matches baseline).Tests
/apishadow-guard arm pinnedTestAPIRoutesShadowedByFallbackReportsLateBareAPIRoute(new)tmpl == "/api"arm →got [],want [/api]→ red. Confirmed, then reverted.TestGetRouteHandlerSelfDispatchGuardReturnsNilForUnknownPath(new)GetMethods()error-guard →getRouteHandlerreturned a non-nil handler instead of(nil, nil)→ red. Confirmed the rest of the HTTP-level suite (TestAPI*,TestPostPackets*) stays green under mutant L, matching the review's "harmless today, unpinned" finding. Reverted.TestAPIOnlyBannerPointsToExistingEndpoint(new)/api/→ test failed with "does not mention /api/docs" → red. Reverted the revert.Evidence legend: [T] automated Go test, [A] live/manual check, [K] known gap.
cmd/migratebinaries, migrated a copy oftest-fixtures/e2e-fixture.db, ran the server on port 13901 with a missing-publicdir:GET /→ banner text containsAPI available at /api/docs.GET /api/docs→200.GET /api(bare) →404 application/json.POST /api/packets→405,Allow: GET, HEAD.HEAD /api/this-path-does-not-exist→404 application/json(no recursion/hang).test-*.jsE2E files for any reference to the banner text or the renamed test name — none found, so no E2E test is affected by this change (it's a backend-test-only + banner-text change; the CI E2E jobs run with a realpublicdir, which never hits the API-only banner branch at all).CI (local, per job — not run through GitHub Actions UI from this session)
cd cmd/server && go build ./... && go vet ./...— clean.gofmt -lon all touched files — no output.go test ./...incmd/server— all passing (41.6s), no regressions.sh test-all.sh— 221/221 files passed.node test-frontend-helpers.js— 707/707 passed.scripts/check-xss-sinks.sh --diff origin/master— clean (nopublic/**/*.{js,html}changes).GitHub Actions CI on this PR has not been inspected from this session yet; will need a look once it runs. Known flake: #271 — rerun once if it's the only failure.
Rester (leftovers / out of scope)
None beyond what #266 already recorded (the plain-text
http.NotFoundhandlers inside some/api/*handlers, tracked as out of scope there too).