import { describe, it, expect, beforeAll, afterAll } from "vitest"; import prisma from "../config/database"; import { updateProject } from "../services/projects.service"; /** * Pinning tests for audit finding M6: updateProject must pre-validate FK ids * (customer_id, responsible_user_id, quotation_id, order_id) and return clean * Czech 400s like createProject does — a dangling id otherwise raises P2003 * at Prisma and surfaces as a generic 500. */ const N = "prj_fk_"; let projectId: number; async function cleanup() { await prisma.projects.deleteMany({ where: { name: { startsWith: N } } }); } beforeAll(async () => { await cleanup(); const project = await prisma.projects.create({ data: { name: `${N}project`, status: "active" }, }); projectId = project.id; }); afterAll(async () => { await cleanup(); await prisma.$disconnect(); }); function isError(r: unknown): r is { error: string; status: number } { return typeof r === "object" && r !== null && "error" in r; } describe("updateProject FK existence checks (audit M6)", () => { it.each([ ["customer_id", "Zákazník nenalezen"], ["responsible_user_id", "Zodpovědná osoba nenalezena"], ["quotation_id", "Nabídka nenalezena"], ["order_id", "Zakázka nenalezena"], ])("returns a Czech 400 for a dangling %s", async (field, message) => { const result = await updateProject(projectId, { [field]: 99999999 }); expect(isError(result)).toBe(true); if (isError(result)) { expect(result.status).toBe(400); expect(result.error).toBe(message); } // Nothing was written. const fresh = await prisma.projects.findUnique({ where: { id: projectId }, }); expect(fresh?.[field as "customer_id"]).toBeNull(); }); it("still allows clearing an FK with null", async () => { const result = await updateProject(projectId, { customer_id: null }); expect(isError(result)).toBe(false); }); it("still allows setting a valid FK", async () => { const user = await prisma.users.findFirst({ select: { id: true } }); expect(user).not.toBeNull(); const result = await updateProject(projectId, { responsible_user_id: user!.id, }); expect(isError(result)).toBe(false); const fresh = await prisma.projects.findUnique({ where: { id: projectId }, }); expect(fresh?.responsible_user_id).toBe(user!.id); }); });