Files
CapaKraken/packages/application/src/__tests__/assignment-bookings.test.ts
T
Hartmut a83edb2f9d feat: timeline UI overhaul with project/resource panel redesign, quick filters, and API improvements
Redesigned timeline project and resource panels with expanded detail views,
added quick filter toolbar, improved drag handling, and enhanced vacation/entitlement
router logic. Includes e2e test updates and minor API fixes.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-15 09:28:59 +01:00

218 lines
5.5 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { listAssignmentBookings } from "../index.js";
describe("listAssignmentBookings", () => {
it("returns assignments with cost metadata", async () => {
const db = {
assignment: {
findMany: vi.fn().mockResolvedValue([
{
id: "asn_1",
projectId: "proj_1",
resourceId: "res_1",
startDate: new Date("2026-03-01T00:00:00.000Z"),
endDate: new Date("2026-03-02T00:00:00.000Z"),
hoursPerDay: 6,
dailyCostCents: 900,
status: "CONFIRMED",
project: {
id: "proj_1",
name: "Alpha",
shortCode: "ALPHA",
status: "ACTIVE",
orderType: "CHARGEABLE",
dynamicFields: null,
},
resource: {
id: "res_1",
displayName: "Alice",
chapter: "CGI",
},
},
{
id: "asn_2",
projectId: "proj_2",
resourceId: "res_2",
startDate: new Date("2026-03-03T00:00:00.000Z"),
endDate: new Date("2026-03-03T00:00:00.000Z"),
hoursPerDay: 4,
dailyCostCents: 500,
status: "PROPOSED",
project: {
id: "proj_2",
name: "Bravo",
shortCode: "BRAVO",
status: "DRAFT",
orderType: "INTERNAL",
dynamicFields: null,
},
resource: {
id: "res_2",
displayName: "Bob",
chapter: "Lighting",
},
},
]),
},
};
const result = await listAssignmentBookings(db as never, {
startDate: new Date("2026-03-01T00:00:00.000Z"),
endDate: new Date("2026-03-31T00:00:00.000Z"),
});
expect(result).toEqual([
{
id: "asn_1",
projectId: "proj_1",
resourceId: "res_1",
startDate: new Date("2026-03-01T00:00:00.000Z"),
endDate: new Date("2026-03-02T00:00:00.000Z"),
hoursPerDay: 6,
dailyCostCents: 900,
status: "CONFIRMED",
project: {
id: "proj_1",
name: "Alpha",
shortCode: "ALPHA",
status: "ACTIVE",
orderType: "CHARGEABLE",
dynamicFields: null,
},
resource: {
id: "res_1",
displayName: "Alice",
chapter: "CGI",
},
},
{
id: "asn_2",
projectId: "proj_2",
resourceId: "res_2",
startDate: new Date("2026-03-03T00:00:00.000Z"),
endDate: new Date("2026-03-03T00:00:00.000Z"),
hoursPerDay: 4,
dailyCostCents: 500,
status: "PROPOSED",
project: {
id: "proj_2",
name: "Bravo",
shortCode: "BRAVO",
status: "DRAFT",
orderType: "INTERNAL",
dynamicFields: null,
},
resource: {
id: "res_2",
displayName: "Bob",
chapter: "Lighting",
},
},
]);
});
it("supports unbounded resource context queries when no date window is provided", async () => {
const db = {
assignment: {
findMany: vi.fn().mockResolvedValue([]),
},
};
await listAssignmentBookings(db as never, {
resourceIds: ["res_1", "res_2"],
});
expect(db.assignment.findMany).toHaveBeenCalledWith({
where: {
status: { not: "CANCELLED" },
resourceId: { in: ["res_1", "res_2"] },
},
select: {
id: true,
projectId: true,
resourceId: true,
startDate: true,
endDate: true,
hoursPerDay: true,
dailyCostCents: true,
status: true,
project: {
select: {
id: true,
name: true,
shortCode: true,
status: true,
orderType: true,
clientId: true,
dynamicFields: true,
},
},
resource: {
select: { id: true, displayName: true, chapter: true },
},
},
});
});
it("rejects partial date bounds", async () => {
const db = {
assignment: {
findMany: vi.fn(),
},
};
await expect(
listAssignmentBookings(db as never, {
startDate: new Date("2026-03-01T00:00:00.000Z"),
}),
).rejects.toThrow("startDate and endDate must be provided together");
expect(db.assignment.findMany).not.toHaveBeenCalled();
});
it("supports excluding explicit assignment ids", async () => {
const db = {
assignment: {
findMany: vi.fn().mockResolvedValue([]),
},
};
await listAssignmentBookings(db as never, {
resourceIds: ["res_1"],
excludeAssignmentIds: ["asn_1"],
});
expect(db.assignment.findMany).toHaveBeenCalledWith({
where: {
status: { not: "CANCELLED" },
resourceId: { in: ["res_1"] },
id: { notIn: ["asn_1"] },
},
select: {
id: true,
projectId: true,
resourceId: true,
startDate: true,
endDate: true,
hoursPerDay: true,
dailyCostCents: true,
status: true,
project: {
select: {
id: true,
name: true,
shortCode: true,
status: true,
orderType: true,
clientId: true,
dynamicFields: true,
},
},
resource: {
select: { id: true, displayName: true, chapter: true },
},
},
});
});
});