test(frontend): MSW server + renderWithProviders harness

This commit is contained in:
Claude
2026-08-28 16:07:14 +00:00
parent a28d34a48c
commit e1632f1272
3 changed files with 44 additions and 0 deletions

View File

@@ -1 +1,7 @@
import "@testing-library/jest-dom/vitest";
import { afterAll, afterEach, beforeAll } from "vitest";
import { mswServer } from "./testing/msw";
beforeAll(() => mswServer.listen({ onUnhandledRequest: "error" }));
afterEach(() => mswServer.resetHandlers());
afterAll(() => mswServer.close());

View File

@@ -0,0 +1,12 @@
import { setupServer } from "msw/node";
import { http, HttpResponse } from "msw";
// Component tests override these per case with `server.use(...)`.
// Defaults simulate "logged out" so any suite that forgets to override gets a
// clear signal instead of silent 200s.
const defaultHandlers = [
http.get("/api/session/me", () => new HttpResponse(null, { status: 401 })),
];
export const mswServer = setupServer(...defaultHandlers);
export { http, HttpResponse };

View File

@@ -0,0 +1,26 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, type RenderOptions, type RenderResult } from "@testing-library/react";
import { MemoryRouter, type MemoryRouterProps } from "react-router-dom";
import type { PropsWithChildren, ReactElement } from "react";
interface Options extends Omit<RenderOptions, "wrapper"> {
route?: string;
routerProps?: MemoryRouterProps;
}
export function renderWithProviders(ui: ReactElement, opts: Options = {}): RenderResult & { queryClient: QueryClient } {
const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false, gcTime: 0, staleTime: 0 },
mutations: { retry: false },
},
});
const Wrapper = ({ children }: PropsWithChildren) => (
<QueryClientProvider client={queryClient}>
<MemoryRouter initialEntries={[opts.route ?? "/"]} {...opts.routerProps}>
{children}
</MemoryRouter>
</QueryClientProvider>
);
return { ...render(ui, { ...opts, wrapper: Wrapper }), queryClient };
}