import { beforeEach, describe, expect, it, vi } from "vitest"; import { PermissionKey, SystemRole } from "@capakraken/shared"; vi.mock("@capakraken/application", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, approveEstimateVersion: vi.fn(), cloneEstimate: vi.fn(), commitDispoImportBatch: vi.fn(), countPlanningEntries: vi.fn().mockResolvedValue({ countsByRoleId: new Map() }), createEstimateExport: vi.fn(), createEstimatePlanningHandoff: vi.fn(), createEstimateRevision: vi.fn(), assessDispoImportReadiness: vi.fn(), loadResourceDailyAvailabilityContexts: vi.fn().mockResolvedValue(new Map()), getDashboardDemand: vi.fn().mockResolvedValue([]), getDashboardBudgetForecast: vi.fn().mockResolvedValue([]), getDashboardOverview: vi.fn(), getDashboardSkillGapSummary: vi.fn().mockResolvedValue({ roleGaps: [], totalOpenPositions: 0, skillSupplyTop10: [], resourcesByRole: [], }), getDashboardProjectHealth: vi.fn().mockResolvedValue([]), getDashboardPeakTimes: vi.fn().mockResolvedValue([]), getDashboardTopValueResources: vi.fn().mockResolvedValue([]), getEstimateById: vi.fn(), listAssignmentBookings: vi.fn().mockResolvedValue([]), stageDispoImportBatch: vi.fn(), submitEstimateVersion: vi.fn(), updateEstimateDraft: vi.fn(), }; }); import { executeTool } from "../router/assistant-tools.js"; import { createToolContext } from "./assistant-tools-allocation-planning-test-helpers.js"; describe("assistant allocation create tools", () => { beforeEach(() => { vi.clearAllMocks(); }); it("routes allocation creation through the real allocation router path", async () => { const auditCreate = vi.fn().mockResolvedValue({ id: "audit_1" }); const assignmentCreate = vi.fn().mockResolvedValue({ id: "assignment_1", demandRequirementId: null, resourceId: "resource_1", projectId: "project_1", startDate: new Date("2026-06-01T00:00:00.000Z"), endDate: new Date("2026-06-05T00:00:00.000Z"), hoursPerDay: 6, percentage: 75, role: "Designer", roleId: null, dailyCostCents: 42000, status: "PROPOSED", metadata: {}, createdAt: new Date("2026-03-29T00:00:00.000Z"), updatedAt: new Date("2026-03-29T00:00:00.000Z"), resource: { id: "resource_1", displayName: "Carol Danvers", eid: "EMP-001", lcrCents: 7000, }, project: { id: "project_1", name: "Project One", shortCode: "PROJ-1" }, roleEntity: null, demandRequirement: null, }); const tx = { project: { findUnique: vi.fn().mockResolvedValue({ id: "project_1" }), }, resource: { findUnique: vi.fn().mockResolvedValue({ id: "resource_1", lcrCents: 7000, availability: { monday: 8, tuesday: 8, wednesday: 8, thursday: 8, friday: 8, saturday: 0, sunday: 0, }, }), }, assignment: { findMany: vi.fn().mockResolvedValue([]), create: assignmentCreate, }, vacation: { findMany: vi.fn().mockResolvedValue([]), }, auditLog: { create: auditCreate, }, }; const transaction = vi .fn() .mockImplementation(async (callback: (inner: typeof tx) => Promise) => callback(tx)); const ctx = createToolContext( { resource: { findUnique: vi.fn().mockResolvedValue({ id: "resource_1", displayName: "Carol Danvers", eid: "EMP-001", lcrCents: 7000, }), findFirst: vi.fn().mockResolvedValue(null), }, project: { findUnique: vi.fn().mockResolvedValue({ id: "project_1", name: "Project One", shortCode: "PROJ-1", status: "ACTIVE", responsiblePerson: "Peter Parker", budgetCents: 0, }), findFirst: vi.fn().mockResolvedValue(null), }, assignment: { findMany: vi.fn().mockResolvedValue([]), findUnique: vi.fn().mockResolvedValue(null), }, $transaction: transaction, }, { userRole: SystemRole.ADMIN, permissions: [PermissionKey.MANAGE_ALLOCATIONS], }, ); const result = await executeTool( "create_allocation", JSON.stringify({ resourceId: "resource_1", projectId: "project_1", startDate: "2026-06-01", endDate: "2026-06-05", hoursPerDay: 6, role: "Designer", }), ctx, ); expect(JSON.parse(result.content)).toEqual( expect.objectContaining({ success: true, message: "Created allocation: Carol Danvers → Project One (PROJ-1), 6h/day, 2026-06-01 to 2026-06-05", allocationId: "assignment_1", status: "PROPOSED", }), ); expect(ctx.db.resource.findUnique).toHaveBeenCalledWith({ where: { id: "resource_1" }, select: { id: true, displayName: true, eid: true, chapter: true, isActive: true, }, }); expect(ctx.db.project.findUnique).toHaveBeenCalledWith({ where: { id: "project_1" }, select: expect.objectContaining({ id: true, shortCode: true, name: true, }), }); expect(ctx.db.assignment.findMany).toHaveBeenCalledWith( expect.objectContaining({ where: { resourceId: "resource_1", projectId: "project_1", }, orderBy: { startDate: "asc" }, include: expect.objectContaining({ resource: { select: expect.objectContaining({ id: true, displayName: true, eid: true, chapter: true, lcrCents: true, }), }, project: { select: expect.objectContaining({ id: true, name: true, shortCode: true, status: true, }), }, }), }), ); expect(assignmentCreate).toHaveBeenCalledTimes(1); expect(auditCreate).toHaveBeenCalledTimes(1); }); });