import { beforeEach, describe, expect, it, vi } from "vitest"; import { SystemRole } from "@capakraken/shared"; import { createToolContext, executeTool } from "./assistant-tools-project-test-helpers.js"; describe("assistant project detail tool", () => { beforeEach(() => { vi.clearAllMocks(); }); it("routes project detail reads through the project router path", async () => { const db = { project: { findUnique: vi.fn() .mockResolvedValueOnce(null) .mockResolvedValueOnce({ id: "project_1", shortCode: "GDM", name: "Gelddruckmaschine", status: "ACTIVE", startDate: new Date("2026-01-01T00:00:00.000Z"), endDate: new Date("2026-03-31T00:00:00.000Z"), }) .mockResolvedValueOnce({ id: "project_1", shortCode: "GDM", name: "Gelddruckmaschine", status: "ACTIVE", orderType: "CHARGEABLE", allocationType: "INT", budgetCents: 500_000, winProbability: 100, startDate: new Date("2026-01-01T00:00:00.000Z"), endDate: new Date("2026-03-31T00:00:00.000Z"), responsiblePerson: "Bruce Banner", client: { name: "Acme Mobility" }, utilizationCategory: { code: "BILL", name: "Billable" }, _count: { assignments: 3, estimates: 1 }, }), }, assignment: { findMany: vi.fn().mockResolvedValue([ { resource: { displayName: "Bruce Banner", eid: "EMP-001" }, role: "Lead", status: "ACTIVE", hoursPerDay: 8, startDate: new Date("2026-02-01T00:00:00.000Z"), endDate: new Date("2026-02-28T00:00:00.000Z"), }, ]), }, }; const ctx = createToolContext(db, { userRole: SystemRole.CONTROLLER }); const detailResult = await executeTool( "get_project", JSON.stringify({ identifier: "GDM" }), ctx, ); expect(db.project.findUnique).toHaveBeenNthCalledWith(1, { where: { id: "GDM" }, select: { id: true, shortCode: true, name: true, status: true, startDate: true, endDate: true, }, }); expect(db.project.findUnique).toHaveBeenNthCalledWith(2, { where: { shortCode: "GDM" }, select: { id: true, shortCode: true, name: true, status: true, startDate: true, endDate: true, }, }); expect(db.project.findUnique).toHaveBeenNthCalledWith(3, { where: { id: "project_1" }, select: { id: true, shortCode: true, name: true, status: true, orderType: true, allocationType: true, budgetCents: true, winProbability: true, startDate: true, endDate: true, responsiblePerson: true, client: { select: { name: true } }, utilizationCategory: { select: { code: true, name: true } }, _count: { select: { assignments: true, estimates: true } }, }, }); expect(db.assignment.findMany).toHaveBeenCalledWith({ where: { projectId: "project_1", status: { not: "CANCELLED" }, }, select: { resource: { select: { displayName: true, eid: true } }, role: true, status: true, hoursPerDay: true, startDate: true, endDate: true, }, take: 10, orderBy: { startDate: "desc" }, }); expect(JSON.parse(detailResult.content)).toEqual({ id: "project_1", code: "GDM", name: "Gelddruckmaschine", status: "ACTIVE", orderType: "CHARGEABLE", allocationType: "INT", budget: "5.000,00 EUR", budgetCents: 500000, winProbability: "100%", start: "2026-01-01", end: "2026-03-31", responsible: "Bruce Banner", client: "Acme Mobility", category: "Billable", assignmentCount: 3, estimateCount: 1, topAllocations: [ { resource: "Bruce Banner", eid: "EMP-001", role: "Lead", status: "ACTIVE", hoursPerDay: 8, start: "2026-02-01", end: "2026-02-28", }, ], }); }); });