import { describe, expect, it, vi } from "vitest"; const { calculateAllocationMock } = vi.hoisted(() => ({ calculateAllocationMock: vi.fn(), })); vi.mock("@capakraken/engine", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, calculateAllocation: calculateAllocationMock, }; }); import { buildTimelineProjectDateRangeUpdate, buildTimelineProjectShiftAuditChanges, buildTimelineShiftedAssignmentUpdate, recalculateShiftedAssignmentDailyCost, } from "../router/timeline-shift-mutation-support.js"; describe("timeline shift mutation support", () => { it("builds shared date range updates for project and demand records", () => { expect( buildTimelineProjectDateRangeUpdate({ newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), }), ).toEqual({ startDate: new Date("2026-04-03T00:00:00.000Z"), endDate: new Date("2026-04-12T00:00:00.000Z"), }); }); it("builds assignment updates with optional recalculated daily cost", () => { expect( buildTimelineShiftedAssignmentUpdate({ newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), dailyCostCents: 54321, }), ).toEqual({ startDate: new Date("2026-04-03T00:00:00.000Z"), endDate: new Date("2026-04-12T00:00:00.000Z"), dailyCostCents: 54321, }); expect( buildTimelineShiftedAssignmentUpdate({ newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), dailyCostCents: undefined, }), ).toEqual({ startDate: new Date("2026-04-03T00:00:00.000Z"), endDate: new Date("2026-04-12T00:00:00.000Z"), }); }); it("builds project shift audit payloads", () => { expect( buildTimelineProjectShiftAuditChanges({ project: { id: "project_1", budgetCents: 200_000, winProbability: 80, startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-10T00:00:00.000Z"), }, newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), validation: { valid: true, errors: [], warnings: [], conflictDetails: [], costImpact: { currentTotalCents: 100_000, newTotalCents: 112_000, deltaCents: 12_000, budgetCents: 200_000, budgetUtilizationBefore: 50, budgetUtilizationAfter: 56, wouldExceedBudget: false, }, }, }), ).toEqual({ before: { startDate: new Date("2026-04-01T00:00:00.000Z"), endDate: new Date("2026-04-10T00:00:00.000Z"), }, after: { startDate: new Date("2026-04-03T00:00:00.000Z"), endDate: new Date("2026-04-12T00:00:00.000Z"), }, costImpact: { currentTotalCents: 100_000, newTotalCents: 112_000, deltaCents: 12_000, budgetCents: 200_000, budgetUtilizationBefore: 50, budgetUtilizationAfter: 56, wouldExceedBudget: false, }, }); }); it("recalculates daily cost only for staffed assignments", async () => { calculateAllocationMock.mockReturnValueOnce({ dailyCostCents: 54321 }); await expect( recalculateShiftedAssignmentDailyCost({ db: { vacation: { findMany: vi.fn().mockResolvedValue([]) }, calculationRule: { findMany: vi.fn().mockResolvedValue([{ id: "rule_1" }]) }, } as never, assignment: { resourceId: "resource_1", hoursPerDay: 8, metadata: { includeSaturday: true }, resource: { lcrCents: 5_000, availability: { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, }, }, } as never, newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), }), ).resolves.toBe(54321); await expect( recalculateShiftedAssignmentDailyCost({ db: {} as never, assignment: { resourceId: null, resource: null, } as never, newStartDate: new Date("2026-04-03T00:00:00.000Z"), newEndDate: new Date("2026-04-12T00:00:00.000Z"), }), ).resolves.toBeUndefined(); }); });