import { INestApplication } from "@nestjs/common"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { agent, bearer, closeTestApp, createTestApp, loginSuperAdmin, type AuthedTokens } from "./setup.js"; /** * Protects the global ValidationPipe wiring itself * (whitelist: true, forbidNonWhitelisted: true โ€” apps/api/src/main.ts, * mirrored in test/setup.ts's createTestApp). Master Prompt ยง12: the * server never trusts a client-supplied field it didn't ask for. This * doesn't test any one DTO's specific fields so much as prove the pipe * is actually reaching these routes and actually configured to reject * (not silently strip) unknown fields. * * No fixtures are created โ€” every request here is expected to be * rejected by the pipe *before* the controller/service runs, so nothing * ever reaches the database. No cleanup needed. */ describe("mass-assignment โ€” unexpected fields are rejected, not silently dropped", () => { let app: INestApplication; let admin: AuthedTokens; beforeAll(async () => { app = await createTestApp(); admin = await loginSuperAdmin(app); }); afterAll(async () => { await closeTestApp(app); }); it("POST /v1/companies rejects an unexpected 'id' field", async () => { await agent(app) .post("/api/v1/companies") .set(...bearer(admin.accessToken)) .send({ companyName: "qa-test- mass assignment id", id: "11111111-1111-1111-1111-111111111111" }) .expect(400); }); it("POST /v1/companies rejects an unexpected 'isActive' field (not part of CreateCompanyDto)", async () => { await agent(app) .post("/api/v1/companies") .set(...bearer(admin.accessToken)) .send({ companyName: "qa-test- mass assignment isActive", isActive: false }) .expect(400); }); it("POST /v1/products rejects an unexpected 'createdBy' field", async () => { await agent(app) .post("/api/v1/products") .set(...bearer(admin.accessToken)) .send({ name: "qa-test- mass assignment product", productTypeId: "11111111-1111-1111-1111-111111111111", unitId: "11111111-1111-1111-1111-111111111111", createdBy: "11111111-1111-1111-1111-111111111111", }) .expect(400); }); });