Sécurisation de l'API et refonte des tests backend
- helmet et express-rate-limit sur les routes d'authentification - CORS restreint aux origines de FRONTEND_URL - CSP désactivée uniquement sur /api-docs pour Swagger UI - ajout du test de tirage et simplification du test e2e - suppression de tests/setup.js devenu inutile Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
87
backend/tests/draw.test.js
Normal file
87
backend/tests/draw.test.js
Normal file
@@ -0,0 +1,87 @@
|
||||
const bcrypt = require("bcrypt");
|
||||
const prisma = require("../src/config/prisma");
|
||||
|
||||
// ------------------------
|
||||
// Vérifie que le pool de participants au tirage du gros lot ne compte
|
||||
// chaque client qu'une seule fois, quel que soit son nombre de
|
||||
// participations. On rejoue ici exactement la requête utilisée par
|
||||
// admin.controller.js::drawWinner, restreinte à des utilisateurs dédiés
|
||||
// pour ne pas dépendre des autres données déjà présentes en base
|
||||
// (et surtout ne jamais toucher aux vrais tickets du jeu-concours).
|
||||
// ------------------------
|
||||
|
||||
let userManyParticipations;
|
||||
let userOneParticipation;
|
||||
let ticketIds = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
const lot = await prisma.lot.findFirst();
|
||||
if (!lot) throw new Error("Aucun lot en base : lancez `npx prisma db seed` avant ce test.");
|
||||
|
||||
const hashed = await bcrypt.hash("Password123", 10);
|
||||
|
||||
userManyParticipations = await prisma.user.create({
|
||||
data: {
|
||||
firstname: "Draw",
|
||||
lastname: "MultiParticip",
|
||||
email: "draw-test-multi@test.com",
|
||||
password: hashed,
|
||||
role: "CLIENT",
|
||||
isEmailVerified: true,
|
||||
},
|
||||
});
|
||||
|
||||
userOneParticipation = await prisma.user.create({
|
||||
data: {
|
||||
firstname: "Draw",
|
||||
lastname: "SingleParticip",
|
||||
email: "draw-test-single@test.com",
|
||||
password: hashed,
|
||||
role: "CLIENT",
|
||||
isEmailVerified: true,
|
||||
},
|
||||
});
|
||||
|
||||
const codes = ["ZZDRAWTEST1", "ZZDRAWTEST2", "ZZDRAWTEST3", "ZZDRAWTEST4"];
|
||||
const owners = [
|
||||
userManyParticipations,
|
||||
userManyParticipations,
|
||||
userManyParticipations,
|
||||
userOneParticipation,
|
||||
];
|
||||
|
||||
for (let i = 0; i < codes.length; i++) {
|
||||
const ticket = await prisma.ticket.create({
|
||||
data: { code: codes[i], lotId: lot.id, isUsed: true, usedAt: new Date(), userId: owners[i].id },
|
||||
});
|
||||
ticketIds.push(ticket.id);
|
||||
await prisma.participation.create({
|
||||
data: { userId: owners[i].id, ticketId: ticket.id, lotId: lot.id },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await prisma.participation.deleteMany({ where: { ticketId: { in: ticketIds } } });
|
||||
await prisma.ticket.deleteMany({ where: { id: { in: ticketIds } } });
|
||||
await prisma.user.deleteMany({
|
||||
where: { id: { in: [userManyParticipations.id, userOneParticipation.id] } },
|
||||
});
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
|
||||
test("un client avec plusieurs participations ne compte qu'une fois dans le pool du tirage", async () => {
|
||||
const eligible = await prisma.user.findMany({
|
||||
where: {
|
||||
role: "CLIENT",
|
||||
id: { in: [userManyParticipations.id, userOneParticipation.id] },
|
||||
participations: { some: {} },
|
||||
},
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
expect(eligible).toHaveLength(2);
|
||||
expect(eligible.map((u) => u.id).sort()).toEqual(
|
||||
[userManyParticipations.id, userOneParticipation.id].sort()
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user