import { beforeEach, describe, expect, it, vi } from "vitest"; import { SystemRole } from "@capakraken/shared"; vi.mock("@capakraken/application", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, getDashboardBudgetForecast: vi.fn().mockResolvedValue([]), getDashboardPeakTimes: vi.fn().mockResolvedValue([]), listAssignmentBookings: vi.fn().mockResolvedValue([]), }; }); import { executeTool } from "../router/assistant-tools.js"; import { createToolContext } from "./assistant-tools-user-admin-test-helpers.js"; describe("assistant user admin tools resource linking", () => { beforeEach(() => { vi.clearAllMocks(); }); it("auto-links users by email for admin users and returns an invalidation action", async () => { const findMany = vi.fn().mockResolvedValue([ { id: "user_1", email: "alice@example.com" }, { id: "user_2", email: "bob@example.com" }, ]); const findFirst = vi.fn().mockResolvedValueOnce({ id: "resource_1" }).mockResolvedValueOnce(null); const update = vi.fn().mockResolvedValue(undefined); const ctx = createToolContext( { user: { findMany, }, resource: { findFirst, update, }, }, SystemRole.ADMIN, ); const result = await executeTool("auto_link_users_by_email", JSON.stringify({}), ctx); expect(result.action).toEqual({ type: "invalidate", scope: ["user", "resource"], }); expect(result.data).toMatchObject({ success: true, linked: 1, checked: 2, message: "Auto-linked 1 user(s) by email.", }); expect(findMany).toHaveBeenCalledWith({ where: { resource: null }, select: { id: true, email: true }, }); expect(findFirst).toHaveBeenNthCalledWith(1, { where: { email: "alice@example.com", userId: null }, select: { id: true }, }); expect(findFirst).toHaveBeenNthCalledWith(2, { where: { email: "bob@example.com", userId: null }, select: { id: true }, }); expect(update).toHaveBeenCalledWith({ where: { id: "resource_1" }, data: { userId: "user_1" }, }); }); });