Files
veille-reglementaire/server/veille.test.ts

172 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it, vi, beforeEach } from "vitest";
import { appRouter } from "./routers";
import type { TrpcContext } from "./_core/context";
// ─── Helpers ─────────────────────────────────────────────────────────────────
function makeAdminCtx(): TrpcContext {
return {
user: {
id: 1,
openId: "admin-test",
email: "admin@itinova.fr",
name: "Admin Test",
loginMethod: "local",
role: "admin",
createdAt: new Date(),
updatedAt: new Date(),
lastSignedIn: new Date(),
},
req: { protocol: "https", headers: {} } as TrpcContext["req"],
res: {
clearCookie: vi.fn(),
cookie: vi.fn(),
} as unknown as TrpcContext["res"],
};
}
function makeUserCtx(): TrpcContext {
return {
user: {
id: 2,
openId: "user-test",
email: "user@itinova.fr",
name: "User Test",
loginMethod: "local",
role: "user",
createdAt: new Date(),
updatedAt: new Date(),
lastSignedIn: new Date(),
},
req: { protocol: "https", headers: {} } as TrpcContext["req"],
res: {
clearCookie: vi.fn(),
cookie: vi.fn(),
} as unknown as TrpcContext["res"],
};
}
function makeAnonCtx(): TrpcContext {
return {
user: null,
req: { protocol: "https", headers: {} } as TrpcContext["req"],
res: {
clearCookie: vi.fn(),
cookie: vi.fn(),
} as unknown as TrpcContext["res"],
};
}
// ─── Tests Auth ───────────────────────────────────────────────────────────────
describe("auth.logout", () => {
it("efface le cookie de session et retourne success", async () => {
const { ctx } = { ctx: makeAdminCtx() };
const clearedCookies: string[] = [];
ctx.res.clearCookie = (name: string) => { clearedCookies.push(name); };
const caller = appRouter.createCaller(ctx);
const result = await caller.auth.logout();
expect(result.success).toBe(true);
expect(clearedCookies.length).toBeGreaterThan(0);
});
it("retourne l'utilisateur connecté via auth.me", async () => {
const ctx = makeAdminCtx();
const caller = appRouter.createCaller(ctx);
const user = await caller.auth.me();
expect(user).not.toBeNull();
expect(user?.email).toBe("admin@itinova.fr");
});
it("retourne null pour un utilisateur non connecté", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
const user = await caller.auth.me();
expect(user).toBeNull();
});
});
// ─── Tests protection admin ───────────────────────────────────────────────────
describe("protection admin", () => {
it("refuse l'accès aux logs pour un utilisateur non admin", async () => {
const ctx = makeUserCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.import.logs({ page: 1, pageSize: 10 })).rejects.toThrow();
});
it("refuse l'accès aux paramètres pour un utilisateur non admin", async () => {
const ctx = makeUserCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.settings.get()).rejects.toThrow();
});
it("refuse la gestion des utilisateurs pour un non admin", async () => {
const ctx = makeUserCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.users.list()).rejects.toThrow();
});
it("refuse le rapport derreurs de classification pour un non admin", async () => {
const ctx = makeUserCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.rss.classificationErrors({ page: 1, pageSize: 25 })).rejects.toThrow();
});
});
// ─── Tests accès public ───────────────────────────────────────────────────────
describe("accès public", () => {
it("veille.list est accessible sans authentification", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
// Ne devrait pas lever d'erreur UNAUTHORIZED
const result = await caller.veille.list({ page: 1, pageSize: 10 });
expect(result).toHaveProperty("items");
expect(result).toHaveProperty("total");
});
it("aap.list est accessible sans authentification", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
const result = await caller.aap.list({ page: 1, pageSize: 10 });
expect(result).toHaveProperty("items");
expect(result).toHaveProperty("total");
});
it("veille.filters est accessible sans authentification", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
const result = await caller.veille.filters();
expect(result).toHaveProperty("categories");
expect(result).toHaveProperty("niveaux");
expect(result).toHaveProperty("territoires");
});
it("aap.filters est accessible sans authentification", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
const result = await caller.aap.filters();
expect(result).toHaveProperty("regions");
expect(result).toHaveProperty("departements");
});
});
// ─── Tests import (admin seulement) ──────────────────────────────────────────
describe("import.run protection", () => {
it("refuse l'import pour un utilisateur non authentifié", async () => {
const ctx = makeAnonCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.import.run({ type: "all" })).rejects.toThrow();
});
it("refuse l'import pour un utilisateur standard", async () => {
const ctx = makeUserCtx();
const caller = appRouter.createCaller(ctx);
await expect(caller.import.run({ type: "all" })).rejects.toThrow();
});
});