From 01e5f273c64df4857a322e0b979c3a7dd7caba03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hartmut=20N=C3=B6renberg?= Date: Mon, 30 Mar 2026 13:15:16 +0200 Subject: [PATCH] test(resource): cover self-service linked resource access --- .../__tests__/resource-router-auth.test.ts | 81 ++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/packages/api/src/__tests__/resource-router-auth.test.ts b/packages/api/src/__tests__/resource-router-auth.test.ts index 369388c..52009ca 100644 --- a/packages/api/src/__tests__/resource-router-auth.test.ts +++ b/packages/api/src/__tests__/resource-router-auth.test.ts @@ -1,5 +1,15 @@ import { SystemRole } from "@capakraken/shared"; -import { describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +vi.mock("../lib/anonymization.js", () => ({ + anonymizeResource: vi.fn((resource: Record) => resource), + anonymizeResources: vi.fn((resources: unknown[]) => resources), + anonymizeSearchMatches: vi.fn((matches: unknown[]) => matches), + getAnonymizationDirectory: vi.fn().mockResolvedValue(null), + resolveResourceIdsByDisplayedEids: vi.fn().mockResolvedValue(new Map()), +})); + +import { anonymizeResource, getAnonymizationDirectory } from "../lib/anonymization.js"; import { resourceRouter } from "../router/resource.js"; import { createCallerFactory } from "../trpc.js"; @@ -33,6 +43,10 @@ function createContext( } describe("resource router authorization", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + it("requires authentication for chapter lookups", async () => { const findMany = vi.fn(); const caller = createCaller(createContext({ @@ -93,4 +107,69 @@ describe("resource router authorization", () => { expect(findUnique).not.toHaveBeenCalled(); expect(update).not.toHaveBeenCalled(); }); + + it("requires authentication for self-service resource lookups", async () => { + const findUnique = vi.fn(); + const caller = createCaller(createContext({ + user: { + findUnique, + }, + }, { session: false })); + + await expect(caller.getMyResource()).rejects.toMatchObject({ + code: "UNAUTHORIZED", + message: "Authentication required", + }); + + expect(findUnique).not.toHaveBeenCalled(); + }); + + it("returns null when the authenticated user has no linked resource", async () => { + const findUnique = vi.fn().mockResolvedValue({ resource: null }); + const caller = createCaller(createContext({ + user: { + findUnique, + }, + })); + + const result = await caller.getMyResource(); + + expect(result).toBeNull(); + expect(findUnique).toHaveBeenCalledWith({ + where: { email: "user@example.com" }, + select: { + resource: { + select: { + id: true, + displayName: true, + eid: true, + chapter: true, + }, + }, + }, + }); + expect(getAnonymizationDirectory).toHaveBeenCalledOnce(); + expect(anonymizeResource).not.toHaveBeenCalled(); + }); + + it("returns the linked resource for authenticated self-service callers", async () => { + const resource = { + id: "res_1", + displayName: "Alice Example", + eid: "E-001", + chapter: "CGI", + }; + const findUnique = vi.fn().mockResolvedValue({ resource }); + const caller = createCaller(createContext({ + user: { + findUnique, + }, + })); + + const result = await caller.getMyResource(); + + expect(result).toEqual(resource); + expect(getAnonymizationDirectory).toHaveBeenCalledOnce(); + expect(anonymizeResource).toHaveBeenCalledWith(resource, null); + }); });