feat(auth): add unit tests for AuthService
This commit is contained in:
@@ -0,0 +1,125 @@
|
|||||||
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
|
import AuthService from '../AuthService';
|
||||||
|
import { FastifyInstance } from 'fastify';
|
||||||
|
|
||||||
|
// Mock Fastify instance
|
||||||
|
const mockFastify = {
|
||||||
|
jwt: {
|
||||||
|
sign: (payload: any) => JSON.stringify(payload),
|
||||||
|
verify: (token: string) => JSON.parse(token)
|
||||||
|
}
|
||||||
|
} as unknown as FastifyInstance;
|
||||||
|
|
||||||
|
describe('AuthService', () => {
|
||||||
|
let authService: AuthService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
authService = new AuthService(mockFastify);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('register', () => {
|
||||||
|
it('should create a user with hashed password', async () => {
|
||||||
|
const user = await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
expect(user).toHaveProperty('id');
|
||||||
|
expect(user.email).toBe('test@example.com');
|
||||||
|
expect(user.displayName).toBe('Test User');
|
||||||
|
expect(user).not.toHaveProperty('passwordHash');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if user already exists', async () => {
|
||||||
|
await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
await expect(authService.register('test@example.com', 'password123', 'Test User'))
|
||||||
|
.rejects.toThrow('User already exists');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('login', () => {
|
||||||
|
it('should return a JWT token for valid credentials', async () => {
|
||||||
|
await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
const token = await authService.login('test@example.com', 'password123');
|
||||||
|
|
||||||
|
expect(token).toBeDefined();
|
||||||
|
expect(typeof token).toBe('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error for invalid credentials', async () => {
|
||||||
|
await expect(authService.login('test@example.com', 'wrongpassword'))
|
||||||
|
.rejects.toThrow('Invalid credentials');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('logout', () => {
|
||||||
|
it('should invalidate the session', async () => {
|
||||||
|
await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
const token = await authService.login('test@example.com', 'password123');
|
||||||
|
|
||||||
|
await expect(authService.logout(token)).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error for invalid token', async () => {
|
||||||
|
await expect(authService.logout('invalid-token'))
|
||||||
|
.rejects.toThrow('Invalid token');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getMe', () => {
|
||||||
|
it('should return current user info', async () => {
|
||||||
|
const user = await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
const userInfo = await authService.getMe(user.id);
|
||||||
|
|
||||||
|
expect(userInfo).toEqual(user);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if user not found', async () => {
|
||||||
|
await expect(authService.getMe('non-existent-id'))
|
||||||
|
.rejects.toThrow('User not found');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('requestPasswordReset', () => {
|
||||||
|
it('should generate a reset token', async () => {
|
||||||
|
await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
// Mock console.log to verify it's called
|
||||||
|
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||||
|
|
||||||
|
await authService.requestPasswordReset('test@example.com');
|
||||||
|
|
||||||
|
expect(consoleSpy).toHaveBeenCalled();
|
||||||
|
|
||||||
|
consoleSpy.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('confirmPasswordReset', () => {
|
||||||
|
it('should reset password with valid token', async () => {
|
||||||
|
// Register user
|
||||||
|
const user = await authService.register('test@example.com', 'password123', 'Test User');
|
||||||
|
|
||||||
|
// Mock console.log to capture the reset token
|
||||||
|
let resetToken = '';
|
||||||
|
const consoleSpy = vi.spyOn(console, 'log').mockImplementation((msg) => {
|
||||||
|
if (msg.startsWith('Password reset token for')) {
|
||||||
|
resetToken = msg.split(': ')[1];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Request password reset
|
||||||
|
await authService.requestPasswordReset('test@example.com');
|
||||||
|
|
||||||
|
consoleSpy.mockRestore();
|
||||||
|
|
||||||
|
// Confirm password reset
|
||||||
|
await expect(authService.confirmPasswordReset(resetToken, 'newpassword123'))
|
||||||
|
.resolves.not.toThrow();
|
||||||
|
|
||||||
|
// Verify login with new password works
|
||||||
|
await expect(authService.login('test@example.com', 'newpassword123'))
|
||||||
|
.resolves.toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user