import { describe, it, expect, vi, beforeEach } from "vitest"; import { authOptions } from "../../app/api/auth/[...nextauth]/route"; import { PrismaClient } from "@prisma/client"; import bcrypt from "bcryptjs"; // Mock PrismaClient vi.mock("../../lib/prisma", () => ({ prisma: new PrismaClient(), })); // Mock bcryptjs vi.mock("bcryptjs", () => ({ default: { compare: vi.fn(), }, })); describe("NextAuth Credentials Provider authorize function", () => { let mockFindUnique: vi.Mock; let mockBcryptCompare: vi.Mock; beforeEach(() => { mockFindUnique = vi.fn(); // @ts-ignore prisma.user.findUnique = mockFindUnique; mockBcryptCompare = bcrypt.compare as vi.Mock; vi.clearAllMocks(); }); const authorize = authOptions.providers[0].authorize; it("should return null if email or password are not provided", async () => { // @ts-ignore const result1 = await authorize({ email: "test@example.com", password: "", }); expect(result1).toBeNull(); expect(mockFindUnique).not.toHaveBeenCalled(); // @ts-ignore const result2 = await authorize({ email: "", password: "password" }); expect(result2).toBeNull(); expect(mockFindUnique).not.toHaveBeenCalled(); }); it("should return null if user is not found", async () => { mockFindUnique.mockResolvedValue(null); // @ts-ignore const result = await authorize({ email: "nonexistent@example.com", password: "password", }); expect(result).toBeNull(); expect(mockFindUnique).toHaveBeenCalledWith({ where: { email: "nonexistent@example.com" }, }); expect(mockBcryptCompare).not.toHaveBeenCalled(); }); it("should return null if password does not match", async () => { const mockUser = { id: "user123", email: "test@example.com", password: "hashed_password", companyId: "company123", role: "USER", }; mockFindUnique.mockResolvedValue(mockUser); mockBcryptCompare.mockResolvedValue(false); // @ts-ignore const result = await authorize({ email: "test@example.com", password: "wrong_password", }); expect(result).toBeNull(); expect(mockFindUnique).toHaveBeenCalledWith({ where: { email: "test@example.com" }, }); expect(mockBcryptCompare).toHaveBeenCalledWith( "wrong_password", "hashed_password" ); }); it("should return user object if credentials are valid", async () => { const mockUser = { id: "user123", email: "test@example.com", password: "hashed_password", companyId: "company123", role: "USER", }; mockFindUnique.mockResolvedValue(mockUser); mockBcryptCompare.mockResolvedValue(true); // @ts-ignore const result = await authorize({ email: "test@example.com", password: "correct_password", }); expect(result).toEqual({ id: "user123", email: "test@example.com", companyId: "company123", role: "USER", }); expect(mockFindUnique).toHaveBeenCalledWith({ where: { email: "test@example.com" }, }); expect(mockBcryptCompare).toHaveBeenCalledWith( "correct_password", "hashed_password" ); }); });