155 lines
5.8 KiB
TypeScript
155 lines
5.8 KiB
TypeScript
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
import { appRouter } from "./routers";
|
|
import type { TrpcContext } from "./_core/context";
|
|
|
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
|
|
function makeUser(overrides: Partial<TrpcContext["user"]> = {}): NonNullable<TrpcContext["user"]> {
|
|
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<TrpcContext["user"]> {
|
|
return makeUser({ id: 2, openId: "gestionnaire-1", sonumRole: "gestionnaire", name: "Gestionnaire SONUM" });
|
|
}
|
|
|
|
function makeCtx(user: NonNullable<TrpcContext["user"]> | 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();
|
|
});
|
|
});
|