import { BlueprintTarget, FieldType, type BlueprintFieldDefinition } from "@capakraken/shared"; import { TRPCError } from "@trpc/server"; import { describe, expect, it, vi } from "vitest"; import { assertBlueprintDynamicFields } from "../router/blueprint-validation.js"; function createDbMock(result: { fieldDefs: unknown; target: BlueprintTarget } | null) { return { blueprint: { findUnique: vi.fn().mockResolvedValue(result), }, }; } describe("assertBlueprintDynamicFields", () => { it("returns early when no blueprint is set", async () => { const db = createDbMock(null); await expect( assertBlueprintDynamicFields({ db, blueprintId: undefined, dynamicFields: {}, target: BlueprintTarget.PROJECT, }), ).resolves.toBeUndefined(); expect(db.blueprint.findUnique).not.toHaveBeenCalled(); }); it("rejects a missing blueprint", async () => { const db = createDbMock(null); await expect( assertBlueprintDynamicFields({ db, blueprintId: "bp_missing", dynamicFields: {}, target: BlueprintTarget.PROJECT, }), ).rejects.toMatchObject({ code: "NOT_FOUND" } satisfies Partial); }); it("rejects a blueprint with the wrong target", async () => { const db = createDbMock({ fieldDefs: [], target: BlueprintTarget.RESOURCE }); await expect( assertBlueprintDynamicFields({ db, blueprintId: "bp_resource", dynamicFields: {}, target: BlueprintTarget.PROJECT, }), ).rejects.toMatchObject({ code: "BAD_REQUEST" } satisfies Partial); }); it("rejects invalid dynamic field values", async () => { const fieldDefs: BlueprintFieldDefinition[] = [ { id: "cost-center", key: "costCenter", label: "Cost Center", order: 0, type: FieldType.NUMBER, required: true, }, ]; const db = createDbMock({ fieldDefs, target: BlueprintTarget.PROJECT }); await expect( assertBlueprintDynamicFields({ db, blueprintId: "bp_project", dynamicFields: { costCenter: "abc" }, target: BlueprintTarget.PROJECT, }), ).rejects.toMatchObject({ code: "UNPROCESSABLE_CONTENT" } satisfies Partial); }); it("accepts valid dynamic field values", async () => { const fieldDefs: BlueprintFieldDefinition[] = [ { id: "cost-center", key: "costCenter", label: "Cost Center", order: 0, type: FieldType.NUMBER, required: true, }, ]; const db = createDbMock({ fieldDefs, target: BlueprintTarget.PROJECT }); await expect( assertBlueprintDynamicFields({ db, blueprintId: "bp_project", dynamicFields: { costCenter: 42 }, target: BlueprintTarget.PROJECT, }), ).resolves.toBeUndefined(); }); });