Jiahan Chen 6fb22bb311
test(frontend): migrate unit tests to rstest (#3703)
* test(frontend): migrate unit tests to rstest

* docs: updates AGENTS.md

* test(frontend): fix rstest lint formatting
2026-06-22 16:12:49 +08:00

85 lines
2.3 KiB
TypeScript

import { beforeEach, describe, expect, it, rs } from "@rstest/core";
import { QueryClient } from "@tanstack/react-query";
rs.mock("@/core/api/fetcher", () => ({
fetch: rs.fn(),
}));
import { fetch } from "@/core/api/fetcher";
import { MCPConfigRequestError, loadMCPConfig } from "@/core/mcp/api";
const mockedFetch = rs.mocked(fetch);
function makeClient() {
return new QueryClient({
defaultOptions: {
queries: {
retryDelay: 0,
},
},
});
}
describe("useMCPConfig retry policy", () => {
beforeEach(() => {
mockedFetch.mockReset();
});
it("does not retry when loadMCPConfig throws MCPConfigRequestError (403)", async () => {
mockedFetch.mockResolvedValue({
ok: false,
status: 403,
json: async () => ({ detail: "Forbidden" }),
} as Response);
const client = makeClient();
await expect(
client.fetchQuery({
queryKey: ["mcpConfig"],
queryFn: () => loadMCPConfig(),
retry: (count, error) =>
!(error instanceof MCPConfigRequestError) && count < 3,
}),
).rejects.toBeInstanceOf(MCPConfigRequestError);
expect(mockedFetch).toHaveBeenCalledTimes(1);
});
it("retries up to 3 times on generic errors", async () => {
mockedFetch.mockRejectedValue(new Error("network down"));
const client = makeClient();
await expect(
client.fetchQuery({
queryKey: ["mcpConfig"],
queryFn: () => loadMCPConfig(),
retry: (count, error) =>
!(error instanceof MCPConfigRequestError) && count < 3,
}),
).rejects.toThrow("network down");
// initial + 3 retries = 4 calls
expect(mockedFetch).toHaveBeenCalledTimes(4);
});
it("does not retry on MCPConfigRequestError 5xx either (deterministic typed error)", async () => {
mockedFetch.mockResolvedValue({
ok: false,
status: 500,
json: async () => ({ detail: "Boom" }),
} as Response);
const client = makeClient();
await expect(
client.fetchQuery({
queryKey: ["mcpConfig"],
queryFn: () => loadMCPConfig(),
retry: (count, error) =>
!(error instanceof MCPConfigRequestError) && count < 3,
}),
).rejects.toBeInstanceOf(MCPConfigRequestError);
expect(mockedFetch).toHaveBeenCalledTimes(1);
});
});