fix(e24): review round 4 — a test that pinned nothing, and prose still ahead of the code
Round 4 reviewed round 3's commit. Nothing in production behaviour was wrong; what was wrong was the round's own test and its comments, which is the failure class this loop keeps finding. - The new NavigationProvider case named after the `&& !channelViewRef.current` clause never reached it. With storage cleared and a bare URL the provider lands on "home" (E24's own default), not "feed", so asking for "feed" was an ordinary page change and the guard's first conjunct short-circuited. Deleting the clause left all 828 tests green — a dead nav control (the rail's own module stops closing an open channel page) with no red anywhere. The test now asserts the precondition and calls `setPage` with the page that IS current. - Both new Home cases rejected a promise and then asserted after one fixed macrotask. React-query notifies through `notifyManager`'s own `setTimeout(0)`, registered after any timer the test schedules, so the assertion raced it; two reviewers measured intermittent reds. They poll for a signal that the rejection LANDED instead — the reroll button releasing, which is also the honest one for the empty-answer case, where the empty state is already on screen while the press is in flight and asserting it early would pass either way. - `buryUnder`'s comment still opened with "one rule for both entry points" ten lines above the paragraph saying the rule is complete only for one of them, listed the non-reporting palette rows without `openChannel` — which has its own `replaceState` no-push branch and is reached from PlayerModal too — and pointed at a ROADMAP.md this repository does not contain. - `history.dom.test.ts`'s header claimed its layers close by genuine Backs only, which two of its own tests contradict; and `CommandPalette.ordering.dom.test.tsx` still claimed to be "the only assertion in the suite" doing what the file corrected in round 3 also does. Round 3's message said that pair was handled and only one side had been. The provider test was re-mutation-checked (dropping the clause now goes red), and both hardened Home tests still go red against their own reverts. Seven consecutive full runs green. Gate: ruff, ruff format, 3x tsc, eslint (0 errors), prettier, knip, vitest 828, pytest 1005.
This commit is contained in:
@@ -430,11 +430,11 @@ describe("Home", () => {
|
||||
await screen.findByText("Hero v1");
|
||||
fireEvent.click(screen.getByText("home.hero.reroll"));
|
||||
await waitFor(() => expect(discoverPick).toHaveBeenCalledTimes(1));
|
||||
await act(async () => {
|
||||
failPick(new Error("boom"));
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
});
|
||||
expect(rerollBtn().disabled).toBe(false); // the failure itself releases the button
|
||||
// `waitFor`, not a fixed tick: react-query hands the rejection to the observer through
|
||||
// `notifyManager`'s own `setTimeout(0)`, registered AFTER any timer this test schedules, so
|
||||
// "await one macrotask then assert" races it. Round 4 measured that race as an intermittent red.
|
||||
failPick(new Error("boom"));
|
||||
await waitFor(() => expect(rerollBtn().disabled).toBe(false)); // the failure releases the button
|
||||
|
||||
// Now an unrelated action refetches that errored key in the background.
|
||||
discoverPick.mockReturnValue(new Promise(() => {}));
|
||||
@@ -475,12 +475,18 @@ describe("Home", () => {
|
||||
failPick = reject;
|
||||
}),
|
||||
);
|
||||
const rerollBtn = () =>
|
||||
screen.getByText("home.hero.reroll").closest("button") as HTMLButtonElement;
|
||||
fireEvent.click(screen.getByText("home.hero.reroll"));
|
||||
await waitFor(() => expect(discoverPick).toHaveBeenCalledTimes(2));
|
||||
await act(async () => {
|
||||
failPick(new Error("boom"));
|
||||
await new Promise((r) => setTimeout(r, 0));
|
||||
});
|
||||
expect(rerollBtn().disabled).toBe(true); // the press is outstanding
|
||||
|
||||
failPick(new Error("boom"));
|
||||
// Wait for a signal that the REJECTION has landed, not for a fixed tick: react-query notifies
|
||||
// the observer through its own `setTimeout(0)`, and the empty state is already on screen while
|
||||
// the press is in flight — so asserting it straight away would pass with or without the fix.
|
||||
// The button releasing is that signal (`isFetched` flips once the key settles, error included).
|
||||
await waitFor(() => expect(rerollBtn().disabled).toBe(false));
|
||||
expect(screen.getByText("home.hero.emptyBudget")).toBeTruthy();
|
||||
expect(screen.queryByText("Hero v1")).toBeNull();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user