test: remove timing races from screen-sync and route transition tests (#138)
This commit is contained in:
@@ -10,6 +10,9 @@ import { server } from "@/test/server";
|
||||
|
||||
import { useScreenSync } from "../index";
|
||||
|
||||
const TRANSPORT_ATTEMPTS = 3;
|
||||
const TRANSPORT_RECOVERY_MS = 3000;
|
||||
|
||||
function auth() {
|
||||
configureAuthClient({
|
||||
accessToken: () => "synthetic",
|
||||
@@ -28,11 +31,13 @@ describe("read-only screen synchronization", () => {
|
||||
gets += 1;
|
||||
syncModes.push(new URL(request.url).searchParams.get("sync"));
|
||||
|
||||
return gets === 1
|
||||
// The transport retries a transient read twice (1 s, 2 s) on its own.
|
||||
return gets <= TRANSPORT_ATTEMPTS
|
||||
? HttpResponse.json({ code: "TBANK_UNAVAILABLE" }, { status: 503 })
|
||||
: HttpResponse.json(resource([]));
|
||||
}),
|
||||
);
|
||||
vi.useFakeTimers();
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
@@ -46,12 +51,26 @@ describe("read-only screen synchronization", () => {
|
||||
{ wrapper: createQueryWrapper().wrapper },
|
||||
);
|
||||
|
||||
await waitFor(() => expect(gets).toBe(1));
|
||||
await act(async () => result.current.sync.retry());
|
||||
await waitFor(() => expect(result.current.accounts.data).toEqual([]));
|
||||
try {
|
||||
// Exhaust the transport back-off so the query settles in error.
|
||||
await vi.waitFor(async () => {
|
||||
await act(() => vi.advanceTimersByTimeAsync(TRANSPORT_RECOVERY_MS));
|
||||
expect(result.current.sync.transportError).toBe(true);
|
||||
});
|
||||
expect(gets).toBe(TRANSPORT_ATTEMPTS);
|
||||
|
||||
expect(gets).toBe(2);
|
||||
expect(syncModes).toEqual([null, null]);
|
||||
await act(async () => result.current.sync.retry());
|
||||
await vi.waitFor(async () => {
|
||||
await act(() => vi.advanceTimersByTimeAsync(0));
|
||||
expect(result.current.accounts.data).toEqual([]);
|
||||
});
|
||||
}
|
||||
finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
|
||||
expect(gets).toBe(TRANSPORT_ATTEMPTS + 1);
|
||||
expect(syncModes).toEqual(Array.from({ length: gets }, () => null));
|
||||
});
|
||||
|
||||
it("refreshes the currently open resources together", async () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "@testing-library/jest-dom/vitest";
|
||||
import { cleanup, configure } from "@testing-library/react";
|
||||
import { MotionGlobalConfig } from "motion/react";
|
||||
import { afterAll, afterEach, beforeAll, vi } from "vitest";
|
||||
|
||||
import { configureAuthClient } from "@/shared/api";
|
||||
@@ -10,6 +11,9 @@ import { server } from "./server";
|
||||
// Allow async UI updates on the slower CI runner; local waits stay unchanged.
|
||||
if (process.env.CI) configure({ asyncUtilTimeout: 5000 });
|
||||
|
||||
// Route fades start at opacity 0; under load toBeVisible can catch that frame.
|
||||
MotionGlobalConfig.skipAnimations = true;
|
||||
|
||||
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
|
||||
Reference in New Issue
Block a user