feat: initial commit - veille-reglementaire v1.0.0

This commit is contained in:
Manus Deploy
2026-04-13 12:05:29 -04:00
commit 347725def5
139 changed files with 27484 additions and 0 deletions

165
server/veille.test.ts Normal file
View File

@@ -0,0 +1,165 @@
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();
});
});
// ─── 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();
});
});