import { describe, expect, it, vi, beforeEach } from "vitest"; import { appRouter } from "./routers"; import type { TrpcContext } from "./_core/context"; // ─── Helpers ────────────────────────────────────────────────────────────────── function makeUser(overrides: Partial = {}): NonNullable { return { id: 1, openId: "user-1", name: "Référent Test", email: "referent@test.fr", loginMethod: "manus", role: "user", sonumRole: "referent", cguAccepted: true, cguAcceptedAt: new Date(), createdAt: new Date(), updatedAt: new Date(), lastSignedIn: new Date(), ...overrides, }; } function makeGestionnaire(): NonNullable { return makeUser({ id: 2, openId: "gestionnaire-1", sonumRole: "gestionnaire", name: "Gestionnaire SONUM" }); } function makeCtx(user: NonNullable | null = null): TrpcContext { return { user, req: { protocol: "https", headers: {} } as TrpcContext["req"], res: { clearCookie: vi.fn(), } as unknown as TrpcContext["res"], }; } // ─── Tests Auth ─────────────────────────────────────────────────────────────── describe("auth.logout", () => { it("clears the session cookie and returns success", async () => { const ctx = makeCtx(makeUser()); const caller = appRouter.createCaller(ctx); const result = await caller.auth.logout(); expect(result).toEqual({ success: true }); }); it("works for unauthenticated users too (public procedure)", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); const result = await caller.auth.logout(); expect(result).toEqual({ success: true }); }); }); describe("auth.me", () => { it("returns null for unauthenticated user", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); const result = await caller.auth.me(); expect(result).toBeNull(); }); it("returns user for authenticated user", async () => { const user = makeUser(); const ctx = makeCtx(user); const caller = appRouter.createCaller(ctx); const result = await caller.auth.me(); expect(result?.id).toBe(1); expect(result?.sonumRole).toBe("referent"); }); }); // ─── Tests CGU ──────────────────────────────────────────────────────────────── describe("cgu.status", () => { it("throws UNAUTHORIZED for unauthenticated user", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); await expect(caller.cgu.status()).rejects.toThrow(); }); it("returns cgu status for authenticated user", async () => { const user = makeUser({ cguAccepted: true }); const ctx = makeCtx(user); const caller = appRouter.createCaller(ctx); const result = await caller.cgu.status(); expect(result.accepted).toBe(true); }); it("returns false when CGU not accepted", async () => { const user = makeUser({ cguAccepted: false, cguAcceptedAt: undefined }); const ctx = makeCtx(user); const caller = appRouter.createCaller(ctx); const result = await caller.cgu.status(); expect(result.accepted).toBe(false); }); }); // ─── Tests Gestion des rôles ────────────────────────────────────────────────── describe("admin.users (gestionnaire only)", () => { it("throws FORBIDDEN for a referent", async () => { const ctx = makeCtx(makeUser()); const caller = appRouter.createCaller(ctx); await expect(caller.admin.users()).rejects.toMatchObject({ code: "FORBIDDEN" }); }); it("throws UNAUTHORIZED for unauthenticated user", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); await expect(caller.admin.users()).rejects.toThrow(); }); }); describe("contact.toutesLesDemandes (gestionnaire only)", () => { it("throws FORBIDDEN for a referent", async () => { const ctx = makeCtx(makeUser()); const caller = appRouter.createCaller(ctx); await expect(caller.contact.toutesLesDemandes()).rejects.toMatchObject({ code: "FORBIDDEN" }); }); }); // ─── Tests Référentiel ──────────────────────────────────────────────────────── describe("referentiel.editeurs", () => { it("is accessible as a public procedure", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); // Should not throw (may return empty array if DB not available) const result = await caller.referentiel.editeurs(); expect(Array.isArray(result)).toBe(true); }); }); describe("referentiel.blocsFonctionnels", () => { it("is accessible as a public procedure", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); const result = await caller.referentiel.blocsFonctionnels(); expect(Array.isArray(result)).toBe(true); }); }); // ─── Tests Traçabilité ──────────────────────────────────────────────────────── describe("tracabilite.compteur", () => { it("throws UNAUTHORIZED for unauthenticated user", async () => { const ctx = makeCtx(null); const caller = appRouter.createCaller(ctx); await expect(caller.tracabilite.compteur({ etablissementId: 1 })).rejects.toThrow(); }); });