import { PermissionKey } from "@capakraken/shared"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { applyScenario, getProjectScenarioBaseline, ScenarioSimulationInputSchema, simulateScenario, } from "../router/scenario-procedure-support.js"; const { readProjectScenarioBaseline, simulateProjectScenario, applyProjectScenario, } = vi.hoisted(() => ({ readProjectScenarioBaseline: vi.fn(), simulateProjectScenario: vi.fn(), applyProjectScenario: vi.fn(), })); vi.mock("../router/scenario-baseline.js", () => ({ readProjectScenarioBaseline, })); vi.mock("../router/scenario-simulation.js", () => ({ simulateProjectScenario, })); vi.mock("../router/scenario-apply.js", () => ({ applyProjectScenario, })); describe("scenario procedure support", () => { beforeEach(() => { readProjectScenarioBaseline.mockReset(); simulateProjectScenario.mockReset(); applyProjectScenario.mockReset(); }); it("enforces at least one scenario change at the schema boundary", () => { expect(() => ScenarioSimulationInputSchema.parse({ projectId: "project_1", changes: [], })).toThrowError(/at least 1 element/i); }); it("reads the project baseline only after cost permission is present", async () => { readProjectScenarioBaseline.mockResolvedValue({ project: { id: "project_1" } }); const result = await getProjectScenarioBaseline({ db: { project: {} } as never, dbUser: { id: "user_1", systemRole: "USER", permissionOverrides: null }, permissions: new Set([PermissionKey.VIEW_COSTS]), }, { projectId: "project_1", }); expect(result).toEqual({ project: { id: "project_1" } }); expect(readProjectScenarioBaseline).toHaveBeenCalledWith(expect.anything(), "project_1"); }); it("delegates pure simulation to the shared simulation service", async () => { simulateProjectScenario.mockResolvedValue({ warnings: [] }); const ctx = { db: { project: {} } }; const input = { projectId: "project_1", changes: [{ resourceId: "resource_1", startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-02T00:00:00.000Z"), hoursPerDay: 8, }], }; const result = await simulateScenario(ctx as never, input); expect(result).toEqual({ warnings: [] }); expect(simulateProjectScenario).toHaveBeenCalledWith(ctx.db, input); }); it("passes the acting user id through when applying a scenario", async () => { applyProjectScenario.mockResolvedValue({ appliedCount: 2 }); const ctx = { db: { assignment: {} }, dbUser: { id: "user_1", systemRole: "CONTROLLER", permissionOverrides: null }, }; const input = { projectId: "project_1", changes: [{ assignmentId: "assignment_1", startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-03T00:00:00.000Z"), hoursPerDay: 6, }], }; const result = await applyScenario(ctx as never, input); expect(result).toEqual({ appliedCount: 2 }); expect(applyProjectScenario).toHaveBeenCalledWith(ctx.db, { ...input, userId: "user_1", }); }); });