mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 19:52:09 +01:00
- Add PostgreSQL-specific data types (@db.VarChar, @db.Text, @db.Timestamptz, @db.JsonB, @db.Inet) - Implement comprehensive database constraints via custom migration - Add detailed field-level documentation and enum descriptions - Optimize indexes for common query patterns and company-scoped data - Ensure data integrity with check constraints for positive values and logical time validation - Add partial indexes for performance optimization on failed/pending processing sessions
101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
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');
|
|
});
|
|
});
|