151 lines
4.5 KiB
TypeScript
151 lines
4.5 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
const { calculateAllocationMock } = vi.hoisted(() => ({
|
|
calculateAllocationMock: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@capakraken/engine", async (importOriginal) => {
|
|
const actual = await importOriginal<typeof import("@capakraken/engine")>();
|
|
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();
|
|
});
|
|
});
|