Nine of the round's ten surviving findings. The tenth (a failed shelf reorder leaving an order the server rejected on screen) is on ROADMAP.md: its obvious remedy reintroduces the overlapping-move defect the code already documents, so it wants a design, not a review edit. - `navigateOverOverlays` buried the live overlay entries before knowing whether the navigation pushed one. `setPage` no-ops when the page is already current and Home is the default landing page, so Shift+W over a player ON Home marked its entry buried under a push that never happened: the unmount consumed the mark instead of reclaiming the entry, and the next browser Back was a press that did nothing. `setPage` now reports whether it navigated, and one `buryUnder` rule serves both entry points — `closeThenNavigate` takes the same no-op navigation from a palette command for the page you are already on. - The hero could answer a new time budget with the previous one's pick. The chip row resets seed/seen/press but cannot reset an answer that already resolved, and `keepPreviousData` chained through the disabled seed-0 query — so a reroll under "10 perc" showed the film picked for "Bármennyi" while it loaded, and kept it if the request failed. `lastPick` now carries the server's own budget echo, and the placeholder is scoped to the budget. - The reroll button spun and swallowed clicks after mark-watched, bookmark, pin and shelf moves: the pick key sits under the invalidated `discover` prefix on purpose, so raw `isFetching` was true for background refetches. It now means "a press of mine is outstanding" — which still covers the first press, where there is no placeholder. - Failed writes on Home toasted the page's LOAD-failure string over a fully loaded page; they get their own key (HU+EN). The empty-state reroll had no `loading`, so the press was unacknowledged and a second click skipped a tier. `danger` moved into the shared unpin row so the same command is not red on the shelf and neutral in the rail below it. - Two comments claimed things the code does not do: the `exclude` cap guards no "unbounded scan" (it never reaches SQL), and the route test that named the cap sends three keys. Tests: the burial rule gets its own file (it is the one assertion that lets a reconcile issue a real programmatic back()); App's keymap wiring gets a source contract, because dropping it left all 818 tests green; `add_pin`'s IntegrityError arm was reached by nothing. Every new test mutation-checked red, both edges where the predicate has two. Gate: ruff, ruff format, 3x tsc, eslint (0 errors), prettier, knip, vitest 822, pytest 1005.
34 lines
1.8 KiB
TypeScript
34 lines
1.8 KiB
TypeScript
// The global Shift+W wiring, pinned at its call site.
|
|
//
|
|
// What this is: a source contract, the same idiom as uiBoundary.contract.test.ts — a structural rule
|
|
// asserted directly rather than left to prose. What it is NOT: a behaviour test. The behaviour lives
|
|
// in history.dom.test.ts and history.burial.dom.test.ts, which drive `navigateOverOverlays` against
|
|
// real overlay entries; the end-to-end gesture (Shift+W over an open player, then Back) is a browser
|
|
// check, because jsdom reproduces history ordering only as bookkeeping.
|
|
//
|
|
// It exists because the composition line itself was unpinned: App.tsx is the one module no test
|
|
// renders (main.tsx lazy-imports it and nothing else does), globalKeymap.dom.test.tsx drives the
|
|
// hook with its OWN handler, and history.dom.test.ts drives the helper with its own navigate — so
|
|
// dropping `navigateOverOverlays` from App left all 818 tests green while the user-visible bug came
|
|
// straight back (round 2, verified by running that revert).
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const APP = readFileSync(fileURLToPath(new URL("./App.tsx", import.meta.url)), "utf8");
|
|
|
|
describe("App · global keymap wiring", () => {
|
|
it("routes the global home shortcut through navigateOverOverlays", () => {
|
|
const call = /useGlobalKeymap\(([\s\S]*?)\);/.exec(APP)?.[1];
|
|
// A rename or a move is a legitimate change — but then this test is the thing that has to be
|
|
// updated deliberately, which is the whole point of pinning it.
|
|
expect(
|
|
call,
|
|
"App.tsx no longer calls useGlobalKeymap in a shape this test can read",
|
|
).toBeTypeOf("string");
|
|
expect(call).toContain("navigateOverOverlays");
|
|
expect(call).toContain('setPage("home")');
|
|
});
|
|
});
|