import { SystemRole } from "@capakraken/shared"; import { describe, expect, it, vi } from "vitest"; import { userRouter } from "../router/user.js"; import { createCallerFactory } from "../trpc.js"; const createCaller = createCallerFactory(userRouter); function createAdminCaller(db: Record) { return createCaller({ session: { user: { email: "admin@example.com", name: "Admin", image: null }, expires: "2099-01-01T00:00:00.000Z", }, db: db as never, dbUser: { id: "user_admin", systemRole: SystemRole.ADMIN, permissionOverrides: null, }, roleDefaults: null, }); } describe("user.linkResource", () => { it("returns NOT_FOUND when the target user does not exist", async () => { const userFindUnique = vi.fn().mockResolvedValue(null); const resourceFindUnique = vi.fn(); const updateMany = vi.fn(); const update = vi.fn(); const caller = createAdminCaller({ user: { findUnique: userFindUnique, }, resource: { findUnique: resourceFindUnique, updateMany, update, }, }); await expect(caller.linkResource({ userId: "missing_user", resourceId: "resource_1", })).rejects.toMatchObject({ code: "NOT_FOUND", message: "User not found", }); expect(userFindUnique).toHaveBeenCalledWith({ where: { id: "missing_user" }, select: { id: true }, }); expect(resourceFindUnique).not.toHaveBeenCalled(); expect(updateMany).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled(); }); it("returns NOT_FOUND when the target resource does not exist", async () => { const userFindUnique = vi.fn().mockResolvedValue({ id: "user_1" }); const resourceFindUnique = vi.fn().mockResolvedValue(null); const updateMany = vi.fn(); const update = vi.fn(); const caller = createAdminCaller({ user: { findUnique: userFindUnique, }, resource: { findUnique: resourceFindUnique, updateMany, update, }, }); await expect(caller.linkResource({ userId: "user_1", resourceId: "missing_resource", })).rejects.toMatchObject({ code: "NOT_FOUND", message: "Resource not found", }); expect(resourceFindUnique).toHaveBeenCalledWith({ where: { id: "missing_resource" }, select: { id: true }, }); expect(updateMany).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled(); }); it("unlinks existing assignments before linking the requested resource", async () => { const userFindUnique = vi.fn().mockResolvedValue({ id: "user_1" }); const resourceFindUnique = vi.fn().mockResolvedValue({ id: "resource_1" }); const updateMany = vi.fn().mockResolvedValue({ count: 1 }); const update = vi.fn().mockResolvedValue({ id: "resource_1", userId: "user_1" }); const caller = createAdminCaller({ user: { findUnique: userFindUnique, }, resource: { findUnique: resourceFindUnique, updateMany, update, }, }); const result = await caller.linkResource({ userId: "user_1", resourceId: "resource_1", }); expect(result).toEqual({ success: true }); expect(updateMany).toHaveBeenCalledWith({ where: { userId: "user_1" }, data: { userId: null }, }); expect(update).toHaveBeenCalledWith({ where: { id: "resource_1" }, data: { userId: "user_1" }, }); }); });