import { describe, test, expect, mock, beforeEach } from "bun:test"; import { buildMockUser, buildMockConstants } from "../setup"; // --------------------------------------------------------------------------- // Stable mock factory // --------------------------------------------------------------------------- function createStablePrismaMock( overrides: Record> = {}, ) { return new Proxy( {}, { get(_target, model: string) { if (model === "$connect" || model === "$disconnect") return mock(() => Promise.resolve()); if (overrides[model]) return overrides[model]; return new Proxy({}, { get: () => mock(() => Promise.resolve(null)) }); }, }, ); } // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- describe("users manager", () => { beforeEach(() => { mock.restore(); }); // ------------------------------------------------------------------- // userExists // ------------------------------------------------------------------- describe("userExists()", () => { test("returns true when user exists", async () => { mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { findFirst: mock(() => Promise.resolve(buildMockUser())), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.userExists({ email: "test@example.com" }); expect(result).toBe(true); }); test("returns false when user does not exist", async () => { mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { findFirst: mock(() => Promise.resolve(null)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.userExists({ email: "nobody@example.com" }); expect(result).toBe(false); }); }); // ------------------------------------------------------------------- // fetchUser // ------------------------------------------------------------------- describe("fetchUser()", () => { test("returns UserController when found", async () => { const userData = { ...buildMockUser(), roles: [] }; mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { findFirst: mock(() => Promise.resolve(userData)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.fetchUser({ email: "test@example.com" }); expect(result).toBeDefined(); expect(result!.id).toBe("user-1"); }); test("returns null when not found", async () => { mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { findFirst: mock(() => Promise.resolve(null)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.fetchUser({ email: "nobody@test.com" }); expect(result).toBeNull(); }); test("returns null when identifier is empty", async () => { mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock(), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.fetchUser({}); expect(result).toBeNull(); }); }); // ------------------------------------------------------------------- // fetchAllUsers // ------------------------------------------------------------------- describe("fetchAllUsers()", () => { test("returns array of UserControllers", async () => { const allUsers = [ { ...buildMockUser(), roles: [] }, { ...buildMockUser({ id: "user-2", email: "user2@test.com" }), roles: [], }, ]; mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { findMany: mock(() => Promise.resolve(allUsers)), findFirst: mock(() => Promise.resolve(null)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.fetchAllUsers(); expect(result).toBeArrayOfSize(2); }); }); // ------------------------------------------------------------------- // deleteUser // ------------------------------------------------------------------- describe("deleteUser()", () => { test("deletes user by id", async () => { const deleteMock = mock(() => Promise.resolve({})); const emitMock = mock(); mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { delete: deleteMock, findFirst: mock(() => Promise.resolve(null)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: emitMock, on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve({})), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve(null)), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); await users.deleteUser("user-1"); expect(deleteMock).toHaveBeenCalledWith({ where: { id: "user-1" } }); expect(emitMock).toHaveBeenCalledWith("user:deleted", { id: "user-1" }); }); }); // ------------------------------------------------------------------- // createUser // ------------------------------------------------------------------- describe("createUser()", () => { test("creates user from Microsoft token", async () => { const msData = { id: "ms-uid-new", mail: "newuser@test.com", userPrincipalName: "newuser@test.com", givenName: "New", surname: "User", }; const newUserData = { ...buildMockUser({ id: "user-new", userId: "ms-uid-new", email: "newuser@test.com", }), roles: [], }; mock.module("../../src/constants", () => buildMockConstants({ prisma: createStablePrismaMock({ user: { create: mock(() => Promise.resolve(newUserData)), findFirst: mock(() => Promise.resolve(null)), }, }), }), ); mock.module("../../src/modules/globalEvents", () => ({ events: { emit: mock(), on: mock() }, setupEventDebugger: mock(), })); mock.module("../../src/modules/fetchMicrosoftUser", () => ({ fetchMicrosoftUser: mock(() => Promise.resolve(msData)), })); mock.module("../../src/modules/cw-utils/members/fetchAllMembers", () => ({ findCwIdentifierByEmail: mock(() => Promise.resolve("newuser")), })); mock.module("../../src/managers/sessions", () => ({ sessions: { create: mock(() => Promise.resolve({ accessToken: "mock-access", refreshToken: "mock-refresh", }), ), fetch: mock(() => Promise.resolve(null)), }, })); const { users } = await import("../../src/managers/users"); const result = await users.createUser("test-token"); expect(result).toBeDefined(); expect(result.id).toBe("user-new"); }); }); });