From 24b5e601694cbfa6e255449cacbe3cda919d107c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Tue, 31 Mar 2026 23:49:33 +0200 Subject: [PATCH] test(api): cover isolated dashboard skill gap detail --- .../assistant-tools-dashboard-detail.test.ts | 44 +++++++++++++++++++ .../dashboard-procedure-support.test.ts | 29 ++++++++++++ 2 files changed, 73 insertions(+) diff --git a/packages/api/src/__tests__/assistant-tools-dashboard-detail.test.ts b/packages/api/src/__tests__/assistant-tools-dashboard-detail.test.ts index edb5d15..8c65b53 100644 --- a/packages/api/src/__tests__/assistant-tools-dashboard-detail.test.ts +++ b/packages/api/src/__tests__/assistant-tools-dashboard-detail.test.ts @@ -417,4 +417,48 @@ describe("assistant dashboard tools detail aggregation", () => { }, }); }); + + it("routes the isolated skill gap detail section without unrelated dashboard reads", async () => { + vi.mocked(getDashboardSkillGapSummary).mockResolvedValue({ + roleGaps: [ + { role: "Pipeline TD", needed: 4, filled: 1, gap: 3, fillRate: 25 }, + ], + totalOpenPositions: 3, + skillSupplyTop10: [{ skill: "houdini", resourceCount: 5 }], + resourcesByRole: [{ role: "Pipeline TD", count: 2 }], + }); + + const ctx = createToolContext( + { + systemSettings: { + findUnique: vi.fn().mockResolvedValue(null), + }, + }, + { userRole: SystemRole.CONTROLLER }, + ); + + const result = await executeTool( + "get_dashboard_detail", + JSON.stringify({ section: "skill_gaps" }), + ctx, + ); + + expect(JSON.parse(result.content)).toEqual({ + skillGaps: { + totalOpenPositions: 3, + roleGaps: [ + { role: "Pipeline TD", gap: 3, needed: 4, filled: 1, fillRate: 25 }, + ], + topSkillsInSupply: [{ skill: "houdini", resourceCount: 5 }], + resourcesByRole: [{ role: "Pipeline TD", count: 2 }], + }, + }); + expect(getDashboardSkillGapSummary).toHaveBeenCalledTimes(1); + expect(getDashboardOverview).not.toHaveBeenCalled(); + expect(getDashboardPeakTimes).not.toHaveBeenCalled(); + expect(getDashboardDemand).not.toHaveBeenCalled(); + expect(getDashboardProjectHealth).not.toHaveBeenCalled(); + expect(getDashboardChargeabilityOverview).not.toHaveBeenCalled(); + expect(getDashboardTopValueResources).not.toHaveBeenCalled(); + }); }); diff --git a/packages/api/src/__tests__/dashboard-procedure-support.test.ts b/packages/api/src/__tests__/dashboard-procedure-support.test.ts index 2a4c07e..8699a38 100644 --- a/packages/api/src/__tests__/dashboard-procedure-support.test.ts +++ b/packages/api/src/__tests__/dashboard-procedure-support.test.ts @@ -127,6 +127,35 @@ describe("dashboard procedure support", () => { }); }); + it("builds the isolated skill gap detail section without overview reads", async () => { + vi.mocked(getDashboardSkillGapSummary).mockResolvedValue({ + roleGaps: [ + { role: "Pipeline TD", needed: 4, filled: 1, gap: 3, fillRate: 25 }, + ], + totalOpenPositions: 3, + skillSupplyTop10: [{ skill: "houdini", resourceCount: 5 }], + resourcesByRole: [{ role: "Pipeline TD", count: 2 }], + }); + + const result = await getDashboardDetail(createContext(), { section: "skill_gaps" }); + + expect(result).toEqual({ + skillGaps: { + totalOpenPositions: 3, + roleGaps: [ + { role: "Pipeline TD", gap: 3, needed: 4, filled: 1, fillRate: 25 }, + ], + topSkillsInSupply: [{ skill: "houdini", resourceCount: 5 }], + resourcesByRole: [{ role: "Pipeline TD", count: 2 }], + }, + }); + expect(getDashboardSkillGapSummary).toHaveBeenCalledTimes(1); + expect(getDashboardOverview).not.toHaveBeenCalled(); + expect(getDashboardPeakTimes).not.toHaveBeenCalled(); + expect(getDashboardDemand).not.toHaveBeenCalled(); + expect(getDashboardProjectHealth).not.toHaveBeenCalled(); + }); + it("builds the assistant-facing dashboard detail payload", async () => { vi.useFakeTimers(); vi.setSystemTime(new Date("2026-03-15T00:00:00.000Z"));