From c65ae132d313f7a0168c96c60c07176e3575d806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Wed, 1 Apr 2026 00:38:10 +0200 Subject: [PATCH] test(api): cover assistant estimate revision export errors --- ...ls-estimate-revision-export-errors.test.ts | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 packages/api/src/__tests__/assistant-tools-estimate-revision-export-errors.test.ts diff --git a/packages/api/src/__tests__/assistant-tools-estimate-revision-export-errors.test.ts b/packages/api/src/__tests__/assistant-tools-estimate-revision-export-errors.test.ts new file mode 100644 index 0000000..5d671f7 --- /dev/null +++ b/packages/api/src/__tests__/assistant-tools-estimate-revision-export-errors.test.ts @@ -0,0 +1,121 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { PermissionKey, SystemRole } from "@capakraken/shared"; + +vi.mock("@capakraken/application", async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + approveEstimateVersion: vi.fn(), + cloneEstimate: vi.fn(), + createEstimateExport: vi.fn(), + createEstimatePlanningHandoff: vi.fn(), + createEstimateRevision: vi.fn(), + getDashboardBudgetForecast: vi.fn().mockResolvedValue([]), + getDashboardPeakTimes: vi.fn().mockResolvedValue([]), + getEstimateById: vi.fn(), + listAssignmentBookings: vi.fn().mockResolvedValue([]), + submitEstimateVersion: vi.fn(), + updateEstimateDraft: vi.fn(), + }; +}); + +import { createEstimateExport, createEstimateRevision } from "@capakraken/application"; + +import { executeTool } from "../router/assistant-tools.js"; +import { + createToolContext, + resetEstimateToolMocks, +} from "./assistant-tools-estimate-test-helpers.js"; + +describe("assistant estimate revision and export mutation errors", () => { + beforeEach(() => { + resetEstimateToolMocks(); + }); + + it("returns stable assistant errors for create_estimate_revision mutations", async () => { + const cases = [ + { + payload: { estimateId: "est_1" }, + setup: () => vi.mocked(createEstimateRevision).mockRejectedValueOnce(new Error("Estimate already has a working version")), + expected: "Estimate already has a working version.", + }, + { + payload: { estimateId: "est_1", sourceVersionId: "ver_deleted" }, + setup: () => + vi.mocked(createEstimateRevision).mockRejectedValueOnce( + Object.assign(new Error("Record to update not found"), { + code: "P2025", + meta: { modelName: "EstimateVersion" }, + }), + ), + expected: "Estimate version not found with the given criteria.", + }, + { + payload: { estimateId: "est_1", sourceVersionId: "ver_1" }, + setup: () => + vi.mocked(createEstimateRevision).mockRejectedValueOnce( + new Error("Source version must be locked before creating a revision"), + ), + expected: "Source version must be locked before creating a revision.", + }, + { + payload: { estimateId: "est_1" }, + setup: () => vi.mocked(createEstimateRevision).mockRejectedValueOnce(new Error("Estimate has no locked version to revise")), + expected: "Estimate has no locked version to revise.", + }, + ] as const; + + for (const testCase of cases) { + testCase.setup(); + const ctx = createToolContext({}, { + userRole: SystemRole.MANAGER, + permissions: [PermissionKey.MANAGE_PROJECTS], + }); + + const result = await executeTool( + "create_estimate_revision", + JSON.stringify(testCase.payload), + ctx, + ); + + expect(JSON.parse(result.content)).toEqual({ error: testCase.expected }); + } + }); + + it("returns stable assistant errors for create_estimate_export mutations", async () => { + const cases = [ + { + payload: { estimateId: "est_1", versionId: "ver_missing", format: "XLSX" }, + setup: () => vi.mocked(createEstimateExport).mockRejectedValueOnce(new Error("Estimate version not found")), + expected: "Estimate version not found with the given criteria.", + }, + { + payload: { estimateId: "est_1", versionId: "ver_deleted", format: "XLSX" }, + setup: () => + vi.mocked(createEstimateExport).mockRejectedValueOnce( + Object.assign(new Error("Record to update not found"), { + code: "P2025", + meta: { modelName: "EstimateVersion" }, + }), + ), + expected: "Estimate version not found with the given criteria.", + }, + ] as const; + + for (const testCase of cases) { + testCase.setup(); + const ctx = createToolContext({}, { + userRole: SystemRole.MANAGER, + permissions: [PermissionKey.MANAGE_PROJECTS], + }); + + const result = await executeTool( + "create_estimate_export", + JSON.stringify(testCase.payload), + ctx, + ); + + expect(JSON.parse(result.content)).toEqual({ error: testCase.expected }); + } + }); +});