Update task documentation and test fixes

- Update Tasks.md with current progress and status
- Fix useListData hook tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-25 19:34:16 +02:00
parent 6490e9d3df
commit 3b527244aa
2 changed files with 33 additions and 20 deletions

View File

@@ -1,23 +1,3 @@
### T-16 · Centralise `PAGE_SIZE` frontend constants
**Where found:** `frontend/src/hooks/useBans.ts:14` (`PAGE_SIZE = 100`); `frontend/src/pages/HistoryPage.tsx:45` (`PAGE_SIZE = 50`)
**Why this is needed:** Page sizes can silently diverge from backend defaults. If the backend changes `_DEFAULT_PAGE_SIZE`, the frontend won't know. Having multiple files define the same concept differently is also misleading.
**Goal:** All pagination constants in `frontend/src/utils/constants.ts`.
**What to do:**
1. Add `BAN_PAGE_SIZE = 100`, `HISTORY_PAGE_SIZE = 50` to `frontend/src/utils/constants.ts` (create it if it doesn't exist).
2. Replace local `const PAGE_SIZE = ...` in each hook/page with imports.
**Possible traps and issues:** Trivial. Verify test snapshots don't hard-code the old inline constant.
**Docs changes needed:** None.
**Doc references:** `frontend/src/utils/constants.ts`
---
### T-17 · `useHistory` is missing abort-signal guards — stale state update bug
**Where found:** `frontend/src/hooks/useHistory.ts``.then()`, `.catch()`, `.finally()` callbacks update state without checking `abortRef.current.signal.aborted`

View File

@@ -76,4 +76,37 @@ describe("useListData", () => {
expect(fetcher).toHaveBeenCalledTimes(2);
expect(result.current.items).toEqual(["second"]);
});
it("does not update state when signal is aborted before resolution", async () => {
const abortedSignals: AbortSignal[] = [];
const fetcher = vi.fn().mockImplementation(async (signal: AbortSignal) => {
abortedSignals.push(signal);
// Simulate a delay
await new Promise((resolve) => setTimeout(resolve, 50));
return { items: ["late"] };
});
const selector = vi.fn((response: { items: string[] }) => response.items);
const { result, unmount } = renderHook(() =>
useListData({
fetcher,
selector,
errorMessage: "Failed to load",
})
);
// Unmount immediately to trigger abort
await act(async () => {
await Promise.resolve();
});
unmount();
// Verify at least one signal was collected and it was aborted
expect(abortedSignals.length).toBeGreaterThan(0);
const lastSignal = abortedSignals[abortedSignals.length - 1];
expect(lastSignal != null && lastSignal.aborted).toBe(true);
// Items should not be updated after abort
expect(result.current.items).toEqual([]);
});
});