Files
seiche/web/tests/smoke.test.tsx

92 lines
2.8 KiB
TypeScript

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(
<QueryClientProvider client={createQueryClient()}>
<MemoryRouter initialEntries={[path]}>
<App />
</MemoryRouter>
</QueryClientProvider>,
);
}
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();
});
});