import { AssistantApprovalStatus, type Prisma } from "@capakraken/db"; import { SystemRole } from "@capakraken/shared"; import { describe, expect, it, vi } from "vitest"; import { assistantRouter } from "../router/assistant.js"; import { createCallerFactory } from "../trpc.js"; const createCaller = createCallerFactory(assistantRouter); function createContext( db: Record, options: { role?: SystemRole; session?: boolean; } = {}, ) { const { role = SystemRole.USER, session = true } = options; return { session: session ? { user: { email: "user@example.com", name: "User", image: null }, expires: "2099-01-01T00:00:00.000Z", } : null, db: db as never, dbUser: session ? { id: role === SystemRole.ADMIN ? "user_admin" : "user_1", systemRole: role, permissionOverrides: null, } : null, }; } describe("assistant router authorization", () => { it("requires authentication for pending approval lists", async () => { const updateMany = vi.fn(); const findMany = vi.fn(); const caller = createCaller(createContext({ assistantApproval: { updateMany, findMany, }, }, { session: false })); await expect(caller.listPendingApprovals()).rejects.toMatchObject({ code: "UNAUTHORIZED", message: "Authentication required", }); expect(updateMany).not.toHaveBeenCalled(); expect(findMany).not.toHaveBeenCalled(); }); it("lists only pending approvals for the current user", async () => { const createdAt = new Date("2026-03-30T10:00:00.000Z"); const expiresAt = new Date("2026-03-30T10:15:00.000Z"); const updateMany = vi.fn().mockResolvedValue({ count: 0 }); const findMany = vi.fn().mockResolvedValue([ { id: "approval_1", userId: "user_1", conversationId: "conv_1", toolName: "create_project", toolArguments: "{\"name\":\"Apollo\"}", summary: "create project Apollo", status: AssistantApprovalStatus.PENDING, createdAt, expiresAt, }, ] satisfies Array>>); const caller = createCaller(createContext({ assistantApproval: { updateMany, findMany, }, })); const result = await caller.listPendingApprovals(); expect(result).toEqual([ { id: "approval_1", status: "pending", conversationId: "conv_1", toolName: "create_project", summary: "create project Apollo", createdAt: createdAt.toISOString(), expiresAt: expiresAt.toISOString(), }, ]); expect(updateMany).toHaveBeenCalledWith({ where: { userId: "user_1", status: AssistantApprovalStatus.PENDING, expiresAt: { lte: expect.any(Date) }, }, data: { status: AssistantApprovalStatus.EXPIRED, }, }); expect(findMany).toHaveBeenCalledWith({ where: { userId: "user_1", status: AssistantApprovalStatus.PENDING, expiresAt: { gt: expect.any(Date) }, }, orderBy: { createdAt: "desc" }, }); }); it("requires authentication before starting assistant chat", async () => { const findUnique = vi.fn(); const caller = createCaller(createContext({ systemSettings: { findUnique, }, }, { session: false })); await expect(caller.chat({ messages: [{ role: "user", content: "Hallo" }], })).rejects.toMatchObject({ code: "UNAUTHORIZED", message: "Authentication required", }); expect(findUnique).not.toHaveBeenCalled(); }); });