From 248973c87d2bf8f99d84de8a24b6ed520e777396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Wed, 1 Apr 2026 00:38:15 +0200 Subject: [PATCH] test(api): cover assistant estimate version status errors --- ...ols-estimate-version-status-errors.test.ts | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 packages/api/src/__tests__/assistant-tools-estimate-version-status-errors.test.ts diff --git a/packages/api/src/__tests__/assistant-tools-estimate-version-status-errors.test.ts b/packages/api/src/__tests__/assistant-tools-estimate-version-status-errors.test.ts new file mode 100644 index 0000000..6869276 --- /dev/null +++ b/packages/api/src/__tests__/assistant-tools-estimate-version-status-errors.test.ts @@ -0,0 +1,138 @@ +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 { approveEstimateVersion, submitEstimateVersion } from "@capakraken/application"; + +import { executeTool } from "../router/assistant-tools.js"; +import { + createToolContext, + resetEstimateToolMocks, +} from "./assistant-tools-estimate-test-helpers.js"; + +describe("assistant estimate version status mutation errors", () => { + beforeEach(() => { + resetEstimateToolMocks(); + }); + + it("returns stable assistant errors for submit_estimate_version mutations", async () => { + const cases = [ + { + payload: { estimateId: "est_1", versionId: "ver_missing" }, + setup: () => vi.mocked(submitEstimateVersion).mockRejectedValueOnce(new Error("Estimate version not found")), + expected: "Estimate version not found with the given criteria.", + }, + { + payload: { estimateId: "est_1", versionId: "ver_deleted" }, + setup: () => + vi.mocked(submitEstimateVersion).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", versionId: "ver_deleted_generic" }, + setup: () => + vi.mocked(submitEstimateVersion).mockRejectedValueOnce( + Object.assign(new Error("Record to update not found"), { + code: "P2025", + }), + ), + expected: "Estimate version not found with the given criteria.", + }, + { + payload: { estimateId: "est_1" }, + setup: () => vi.mocked(submitEstimateVersion).mockRejectedValueOnce(new Error("Estimate has no working version")), + expected: "Estimate has no working version.", + }, + { + payload: { estimateId: "est_1" }, + setup: () => vi.mocked(submitEstimateVersion).mockRejectedValueOnce(new Error("Only working versions can be submitted")), + expected: "Only working versions can be submitted.", + }, + ] as const; + + for (const testCase of cases) { + testCase.setup(); + const ctx = createToolContext({}, { + userRole: SystemRole.MANAGER, + permissions: [PermissionKey.MANAGE_PROJECTS], + }); + + const result = await executeTool( + "submit_estimate_version", + JSON.stringify(testCase.payload), + ctx, + ); + + expect(JSON.parse(result.content)).toEqual({ error: testCase.expected }); + } + }); + + it("returns stable assistant errors for approve_estimate_version mutations", async () => { + const cases = [ + { + payload: { estimateId: "est_1", versionId: "ver_missing" }, + setup: () => vi.mocked(approveEstimateVersion).mockRejectedValueOnce(new Error("Estimate version not found")), + expected: "Estimate version not found with the given criteria.", + }, + { + payload: { estimateId: "est_1", versionId: "ver_deleted" }, + setup: () => + vi.mocked(approveEstimateVersion).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" }, + setup: () => vi.mocked(approveEstimateVersion).mockRejectedValueOnce(new Error("Estimate has no submitted version")), + expected: "Estimate has no submitted version.", + }, + { + payload: { estimateId: "est_1" }, + setup: () => vi.mocked(approveEstimateVersion).mockRejectedValueOnce(new Error("Only submitted versions can be approved")), + expected: "Only submitted versions can be approved.", + }, + ] as const; + + for (const testCase of cases) { + testCase.setup(); + const ctx = createToolContext({}, { + userRole: SystemRole.MANAGER, + permissions: [PermissionKey.MANAGE_PROJECTS], + }); + + const result = await executeTool( + "approve_estimate_version", + JSON.stringify(testCase.payload), + ctx, + ); + + expect(JSON.parse(result.content)).toEqual({ error: testCase.expected }); + } + }); +});