refactor(api): extract timeline project context procedures

This commit is contained in:
2026-03-31 18:48:48 +02:00
parent 973c909e3d
commit 850ea864f4
5 changed files with 223 additions and 204 deletions
@@ -1,23 +1,9 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("../lib/anonymization.js", () => ({
getAnonymizationDirectory: vi.fn(),
}));
vi.mock("../router/timeline-project-load-support.js", () => ({
loadTimelineProjectContext: vi.fn(),
previewTimelineProjectShift: vi.fn(),
}));
vi.mock("../router/timeline-project-context-support.js", () => ({
loadTimelineProjectContextDetailArtifacts: vi.fn(),
}));
vi.mock("../router/timeline-project-context-response-support.js", () => ({
buildTimelineProjectContextResponse: vi.fn(),
buildTimelineProjectContextDetailResponse: vi.fn(),
}));
vi.mock("@capakraken/application", () => ({
listAssignmentBookings: vi.fn(),
}));
@@ -40,16 +26,7 @@ vi.mock("../router/timeline-project-read-support.js", () => ({
import { listAssignmentBookings } from "@capakraken/application";
import { computeBudgetStatus } from "@capakraken/engine";
import { getAnonymizationDirectory } from "../lib/anonymization.js";
import {
loadTimelineProjectContextDetailArtifacts,
} from "../router/timeline-project-context-support.js";
import {
buildTimelineProjectContextDetailResponse,
buildTimelineProjectContextResponse,
} from "../router/timeline-project-context-response-support.js";
import {
loadTimelineProjectContext,
previewTimelineProjectShift,
} from "../router/timeline-project-load-support.js";
import {
@@ -64,17 +41,10 @@ import {
} from "../router/timeline-project-query-support.js";
import {
readTimelineProjectBudgetStatusResponse,
readTimelineProjectContextDetailResponse,
readTimelineProjectContextResponse,
readTimelineProjectShiftPreviewDetail,
} from "../router/timeline-project-procedure-support.js";
const getAnonymizationDirectoryMock = vi.mocked(getAnonymizationDirectory);
const loadTimelineProjectContextMock = vi.mocked(loadTimelineProjectContext);
const previewTimelineProjectShiftMock = vi.mocked(previewTimelineProjectShift);
const loadTimelineProjectContextDetailArtifactsMock = vi.mocked(loadTimelineProjectContextDetailArtifacts);
const buildTimelineProjectContextResponseMock = vi.mocked(buildTimelineProjectContextResponse);
const buildTimelineProjectContextDetailResponseMock = vi.mocked(buildTimelineProjectContextDetailResponse);
const listAssignmentBookingsMock = vi.mocked(listAssignmentBookings);
const computeBudgetStatusMock = vi.mocked(computeBudgetStatus);
const findTimelineProjectOrThrowMock = vi.mocked(findTimelineProjectOrThrow);
@@ -87,102 +57,6 @@ describe("timeline project procedure support", () => {
vi.clearAllMocks();
});
it("builds project context responses from loaded context and anonymization directory", async () => {
loadTimelineProjectContextMock.mockResolvedValueOnce({
project: { id: "project_1" },
allocations: [{ id: "allocation_1" }],
demands: [{ id: "demand_1" }],
assignments: [{ id: "assignment_1" }],
allResourceAllocations: [{ id: "booking_1" }],
resourceIds: ["resource_1"],
} as never);
getAnonymizationDirectoryMock.mockResolvedValueOnce({ enabled: true } as never);
buildTimelineProjectContextResponseMock.mockReturnValueOnce({ ok: true } as never);
await expect(readTimelineProjectContextResponse({} as never, "project_1")).resolves.toEqual({
ok: true,
});
expect(loadTimelineProjectContextMock).toHaveBeenCalledWith({}, "project_1");
expect(getAnonymizationDirectoryMock).toHaveBeenCalledWith({});
expect(buildTimelineProjectContextResponseMock).toHaveBeenCalledWith({
project: { id: "project_1" },
allocations: [{ id: "allocation_1" }],
demands: [{ id: "demand_1" }],
assignments: [{ id: "assignment_1" }],
allResourceAllocations: [{ id: "booking_1" }],
resourceIds: ["resource_1"],
directory: { enabled: true },
});
});
it("builds project context detail responses from loaded artifacts", async () => {
loadTimelineProjectContextMock.mockResolvedValueOnce({
project: {
id: "project_1",
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
},
allocations: [{ id: "allocation_1" }],
demands: [{ id: "demand_1", startDate: new Date("2026-04-01T00:00:00.000Z") }],
assignments: [{ id: "assignment_1", startDate: new Date("2026-04-02T00:00:00.000Z") }],
allResourceAllocations: [{ id: "booking_1" }],
resourceIds: ["resource_1"],
} as never);
getAnonymizationDirectoryMock.mockResolvedValueOnce({ enabled: true } as never);
loadTimelineProjectContextDetailArtifactsMock.mockResolvedValueOnce({
period: {
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
},
holidayOverlays: [{ id: "overlay_1" }],
assignmentConflicts: [{ assignmentId: "assignment_1" }],
} as never);
buildTimelineProjectContextDetailResponseMock.mockReturnValueOnce({ detail: true } as never);
await expect(
readTimelineProjectContextDetailResponse({} as never, {
projectId: "project_1",
startDate: "2026-04-03",
endDate: "2026-04-12",
durationDays: 10,
}),
).resolves.toEqual({ detail: true });
expect(loadTimelineProjectContextDetailArtifactsMock).toHaveBeenCalledWith({}, {
projectId: "project_1",
requestedStartDate: "2026-04-03",
requestedEndDate: "2026-04-12",
durationDays: 10,
projectStartDate: new Date("2026-04-01T00:00:00.000Z"),
projectEndDate: new Date("2026-04-10T00:00:00.000Z"),
firstAssignmentStartDate: new Date("2026-04-02T00:00:00.000Z"),
firstDemandStartDate: new Date("2026-04-01T00:00:00.000Z"),
assignments: [{ id: "assignment_1", startDate: new Date("2026-04-02T00:00:00.000Z") }],
allResourceAllocations: [{ id: "booking_1" }],
resourceIds: ["resource_1"],
});
expect(buildTimelineProjectContextDetailResponseMock).toHaveBeenCalledWith({
project: {
id: "project_1",
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
},
period: {
startDate: new Date("2026-04-01T00:00:00.000Z"),
endDate: new Date("2026-04-10T00:00:00.000Z"),
},
allocations: [{ id: "allocation_1" }],
demands: [{ id: "demand_1", startDate: new Date("2026-04-01T00:00:00.000Z") }],
assignments: [{ id: "assignment_1", startDate: new Date("2026-04-02T00:00:00.000Z") }],
allResourceAllocations: [{ id: "booking_1" }],
resourceIds: ["resource_1"],
assignmentConflicts: [{ assignmentId: "assignment_1" }],
holidayOverlays: [{ id: "overlay_1" }],
directory: { enabled: true },
});
});
it("builds shift preview detail responses", async () => {
findTimelineProjectOrThrowMock.mockResolvedValueOnce({ id: "project_1" } as never);
previewTimelineProjectShiftMock.mockResolvedValueOnce({ valid: true } as never);