/** * Tests for the Auth Service * @jest-environment jsdom */ import { authService } from '@/services/auth.service'; import { api } from '@/services/api'; import { API_ENDPOINTS } from '@/utils/constants'; // Mock the api module jest.mock('@/services/api', () => ({ api: { get: jest.fn(), post: jest.fn(), put: jest.fn(), patch: jest.fn(), delete: jest.fn(), }, ApiError: class ApiError extends Error { constructor(public status: number, message: string, public data?: unknown) { super(message); this.name = 'ApiError'; } }, })); describe('Auth Service', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('login', () => { it('should login with valid credentials', async () => { const mockResponse = { success: true, token: 'jwt-token-123', user: { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe', role: 'CLIENT', }, }; (api.post as jest.Mock).mockResolvedValueOnce(mockResponse); const result = await authService.login({ email: 'test@test.com', password: 'password123', }); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.LOGIN, { email: 'test@test.com', password: 'password123' } ); expect(result).toEqual({ token: 'jwt-token-123', user: mockResponse.user, }); }); it('should throw error on invalid credentials', async () => { (api.post as jest.Mock).mockRejectedValueOnce(new Error('Invalid credentials')); await expect( authService.login({ email: 'test@test.com', password: 'wrong' }) ).rejects.toThrow('Invalid credentials'); }); }); describe('register', () => { it('should register a new user', async () => { const mockResponse = { success: true, token: 'jwt-token-new', user: { id: '2', email: 'new@test.com', firstName: 'Jane', lastName: 'Doe', role: 'CLIENT', }, }; (api.post as jest.Mock).mockResolvedValueOnce(mockResponse); const registerData = { email: 'new@test.com', password: 'password123', firstName: 'Jane', lastName: 'Doe', }; const result = await authService.register(registerData); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.REGISTER, registerData ); expect(result.token).toBe('jwt-token-new'); expect(result.user.email).toBe('new@test.com'); }); it('should throw error if email already exists', async () => { (api.post as jest.Mock).mockRejectedValueOnce(new Error('Email already exists')); await expect( authService.register({ email: 'existing@test.com', password: 'password', firstName: 'Test', lastName: 'User', }) ).rejects.toThrow('Email already exists'); }); }); describe('logout', () => { it('should call logout endpoint', async () => { (api.post as jest.Mock).mockResolvedValueOnce({ success: true }); await authService.logout(); expect(api.post).toHaveBeenCalledWith(API_ENDPOINTS.AUTH.LOGOUT); }); }); describe('getCurrentUser', () => { it('should return user data from response.data', async () => { const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe', role: 'CLIENT', }; (api.get as jest.Mock).mockResolvedValueOnce({ success: true, data: mockUser, }); const result = await authService.getCurrentUser(); expect(api.get).toHaveBeenCalledWith(API_ENDPOINTS.AUTH.ME); expect(result).toEqual(mockUser); }); it('should return user data from response.user', async () => { const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe', role: 'CLIENT', }; (api.get as jest.Mock).mockResolvedValueOnce({ success: true, user: mockUser, }); const result = await authService.getCurrentUser(); expect(result).toEqual(mockUser); }); it('should return response directly if no data or user field', async () => { const mockUser = { id: '1', email: 'test@test.com', firstName: 'John', lastName: 'Doe', role: 'CLIENT', }; (api.get as jest.Mock).mockResolvedValueOnce(mockUser); const result = await authService.getCurrentUser(); expect(result).toEqual(mockUser); }); }); describe('googleLogin', () => { it('should login with Google token', async () => { const mockResponse = { success: true, token: 'jwt-google-token', user: { id: '3', email: 'google@test.com', firstName: 'Google', lastName: 'User', role: 'CLIENT', }, }; (api.post as jest.Mock).mockResolvedValueOnce(mockResponse); const result = await authService.googleLogin('google-oauth-token'); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.GOOGLE, { token: 'google-oauth-token' } ); expect(result.token).toBe('jwt-google-token'); }); }); describe('facebookLogin', () => { it('should login with Facebook token', async () => { const mockResponse = { success: true, token: 'jwt-facebook-token', user: { id: '4', email: 'facebook@test.com', firstName: 'Facebook', lastName: 'User', role: 'CLIENT', }, }; (api.post as jest.Mock).mockResolvedValueOnce(mockResponse); const result = await authService.facebookLogin('facebook-oauth-token'); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.FACEBOOK, { token: 'facebook-oauth-token' } ); expect(result.token).toBe('jwt-facebook-token'); }); }); describe('verifyEmail', () => { it('should verify email with token', async () => { (api.post as jest.Mock).mockResolvedValueOnce({ success: true }); await authService.verifyEmail('verification-token'); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.VERIFY_EMAIL, { token: 'verification-token' } ); }); }); describe('forgotPassword', () => { it('should send forgot password request', async () => { (api.post as jest.Mock).mockResolvedValueOnce({ success: true }); await authService.forgotPassword('test@test.com'); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.FORGOT_PASSWORD, { email: 'test@test.com' } ); }); }); describe('resetPassword', () => { it('should reset password with token', async () => { (api.post as jest.Mock).mockResolvedValueOnce({ success: true }); await authService.resetPassword('reset-token', 'newPassword123'); expect(api.post).toHaveBeenCalledWith( API_ENDPOINTS.AUTH.RESET_PASSWORD, { token: 'reset-token', password: 'newPassword123' } ); }); }); });