import { QueryClientProvider } from "@tanstack/react-query"; import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { MemoryRouter } from "react-router"; import { afterEach, describe, expect, it, vi } from "vitest"; import App from "../src/App"; import type { AuthSession } from "../src/lib/api"; import { createQueryClient } from "../src/lib/queryClient"; const session: AuthSession = { user: { username: "nicolas" }, csrfToken: "csrf-token", csrfHeader: "x-csrf-token", sessionExpiresAt: new Date(Date.now() + 3_600_000).toISOString(), }; function jsonResponse(body: unknown, status = 200): Response { return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json" }, }); } function mockApi(handler: (url: string, init?: RequestInit) => Response) { vi.stubGlobal( "fetch", vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => handler(String(input), init)), ); } function renderApp(path: string) { return render( , ); } afterEach(() => { vi.unstubAllGlobals(); }); describe("smoke front", () => { it("rend le formulaire de login", () => { mockApi(() => jsonResponse({})); renderApp("/login"); expect(screen.getByLabelText(/nom d'utilisateur/i)).toBeInTheDocument(); expect(screen.getByLabelText(/mot de passe/i)).toBeInTheDocument(); expect(screen.getByRole("button", { name: /se connecter/i })).toBeInTheDocument(); }); it("redirige vers /login sans session valide", async () => { mockApi((url) => url.includes("/auth/session") ? jsonResponse({ error: "not_authenticated" }, 401) : jsonResponse({}, 404), ); renderApp("/"); await waitFor(() => { expect(screen.getByRole("button", { name: /se connecter/i })).toBeInTheDocument(); }); }); it("connecte l'utilisateur et affiche le dashboard", async () => { mockApi((url, init) => url.includes("/auth/login") && init?.method === "POST" ? jsonResponse(session) : jsonResponse({ error: "not_authenticated" }, 401), ); renderApp("/login"); fireEvent.change(screen.getByLabelText(/nom d'utilisateur/i), { target: { value: "nicolas" }, }); fireEvent.change(screen.getByLabelText(/mot de passe/i), { target: { value: "secret" }, }); const form = screen .getByRole("button", { name: /se connecter/i }) .closest("form") as HTMLFormElement; fireEvent.submit(form); await waitFor(() => { expect(screen.getByText(/tableau de bord/i)).toBeInTheDocument(); }); expect(screen.getByText("nicolas")).toBeInTheDocument(); }); });