92 lines
2.8 KiB
TypeScript
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();
|
|
});
|
|
});
|