import { describe, it, expect, mock, beforeEach, afterEach } from "bun:test"; import { userService } from "./user.service"; // Define mock functions outside so we can control them in tests const mockFindFirst = mock(); const mockInsert = mock(); const mockUpdate = mock(); const mockDelete = mock(); const mockValues = mock(); const mockReturning = mock(); const mockSet = mock(); const mockWhere = mock(); // Chainable mock setup mockInsert.mockReturnValue({ values: mockValues }); mockValues.mockReturnValue({ returning: mockReturning }); mockUpdate.mockReturnValue({ set: mockSet }); mockSet.mockReturnValue({ where: mockWhere }); mockWhere.mockReturnValue({ returning: mockReturning }); // Mock DrizzleClient mock.module("@/lib/DrizzleClient", () => { return { DrizzleClient: { query: { users: { findFirst: mockFindFirst, }, }, insert: mockInsert, update: mockUpdate, delete: mockDelete, transaction: async (cb: any) => { // Pass the mock client itself as the transaction object // This simplifies things as we use the same structure for tx and client return cb({ query: { users: { findFirst: mockFindFirst, }, }, insert: mockInsert, update: mockUpdate, delete: mockDelete, }); } }, }; }); describe("userService", () => { beforeEach(() => { mockFindFirst.mockReset(); mockInsert.mockClear(); mockValues.mockClear(); mockReturning.mockClear(); }); describe("getUserById", () => { it("should return a user when found", async () => { const mockUser = { id: 123n, username: "testuser", class: null }; mockFindFirst.mockResolvedValue(mockUser); const result = await userService.getUserById("123"); expect(result).toEqual(mockUser as any); expect(mockFindFirst).toHaveBeenCalledTimes(1); }); it("should return undefined when user not found", async () => { mockFindFirst.mockResolvedValue(undefined); const result = await userService.getUserById("999"); expect(result).toBeUndefined(); expect(mockFindFirst).toHaveBeenCalledTimes(1); }); }); describe("createUser", () => { it("should create and return a new user", async () => { const newUser = { id: 456n, username: "newuser", classId: null }; mockReturning.mockResolvedValue([newUser]); const result = await userService.createUser("456", "newuser"); expect(result).toEqual(newUser as any); expect(mockInsert).toHaveBeenCalledTimes(1); expect(mockValues).toHaveBeenCalledWith({ id: 456n, username: "newuser", classId: undefined }); }); }); });