const UserController = require('../../../src/api/controllers/UserController'); const GetMeQuery = require('../../../src/application/user/queries/GetMeQuery'); const GetAllUsersQuery = require('../../../src/application/user/queries/GetAllUsersQuery'); const GetUserByIdQuery = require('../../../src/application/user/queries/GetUserByIdQuery'); const UpdateUserProfileCommand = require('../../../src/application/user/commands/UpdateUserProfileCommand'); describe('UserController', () => { let controller; let mockGetMeHandler; let mockGetAllUsersHandler; let mockGetUserByIdHandler; let mockUpdateProfileHandler; let mockReq; let mockRes; beforeEach(() => { // Mock handlers mockGetMeHandler = { handle: jest.fn() }; mockGetAllUsersHandler = { handle: jest.fn() }; mockGetUserByIdHandler = { handle: jest.fn() }; mockUpdateProfileHandler = { handle: jest.fn() }; controller = new UserController( mockGetMeHandler, mockGetAllUsersHandler, mockGetUserByIdHandler, mockUpdateProfileHandler ); // Mock Express req/res mockReq = { user: { userId: 1 }, // Set by authMiddleware body: {}, params: {} }; mockRes = { status: jest.fn().mockReturnThis(), json: jest.fn() }; // Reset all mocks jest.clearAllMocks(); }); describe('getMe', () => { it('should return current user successfully', async () => { // Arrange const mockUser = { id: 1, name: 'John Doe', email: 'john@example.com' }; mockGetMeHandler.handle.mockResolvedValue(mockUser); // Act await controller.getMe(mockReq, mockRes); // Assert expect(mockGetMeHandler.handle).toHaveBeenCalledWith( expect.any(GetMeQuery) ); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ message: 'User retrieved successfully', data: mockUser }); }); it('should return 404 if user not found', async () => { // Arrange mockGetMeHandler.handle.mockRejectedValue(new Error('User not found')); // Act await controller.getMe(mockReq, mockRes); // Assert expect(mockRes.status).toHaveBeenCalledWith(404); expect(mockRes.json).toHaveBeenCalledWith({ error: 'User not found' }); }); }); describe('getAll', () => { it('should return all users successfully', async () => { // Arrange const mockUsers = [ { id: 1, name: 'John Doe', email: 'john@example.com' }, { id: 2, name: 'Jane Doe', email: 'jane@example.com' } ]; mockGetAllUsersHandler.handle.mockResolvedValue(mockUsers); // Act await controller.getAll(mockReq, mockRes); // Assert expect(mockGetAllUsersHandler.handle).toHaveBeenCalledWith( expect.any(GetAllUsersQuery) ); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ message: 'Users retrieved successfully', data: mockUsers, count: 2 }); }); it('should return empty array if no users exist', async () => { // Arrange mockGetAllUsersHandler.handle.mockResolvedValue([]); // Act await controller.getAll(mockReq, mockRes); // Assert expect(mockRes.json).toHaveBeenCalledWith({ message: 'Users retrieved successfully', data: [], count: 0 }); }); }); describe('getById', () => { it('should return user by ID successfully', async () => { // Arrange mockReq.params = { id: '2' }; const mockUser = { id: 2, name: 'Jane Doe', email: 'jane@example.com' }; mockGetUserByIdHandler.handle.mockResolvedValue(mockUser); // Act await controller.getById(mockReq, mockRes); // Assert expect(mockGetUserByIdHandler.handle).toHaveBeenCalledWith( expect.any(GetUserByIdQuery) ); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ message: 'User retrieved successfully', data: mockUser }); }); it('should return 400 for invalid user ID', async () => { // Arrange mockReq.params = { id: 'invalid' }; // Act await controller.getById(mockReq, mockRes); // Assert expect(mockRes.status).toHaveBeenCalledWith(400); expect(mockRes.json).toHaveBeenCalledWith({ error: 'Invalid user ID' }); }); it('should return 404 if user not found', async () => { // Arrange mockReq.params = { id: '999' }; mockGetUserByIdHandler.handle.mockRejectedValue(new Error('User not found')); // Act await controller.getById(mockReq, mockRes); // Assert expect(mockRes.status).toHaveBeenCalledWith(404); expect(mockRes.json).toHaveBeenCalledWith({ error: 'User not found' }); }); }); describe('updateMe', () => { it('should update user profile successfully', async () => { // Arrange mockReq.body = { name: 'John Updated' }; const mockUpdatedUser = { id: 1, name: 'John Updated', email: 'john@example.com' }; mockUpdateProfileHandler.handle.mockResolvedValue(mockUpdatedUser); // Act await controller.updateMe(mockReq, mockRes); // Assert expect(mockUpdateProfileHandler.handle).toHaveBeenCalledWith( expect.any(UpdateUserProfileCommand) ); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ message: 'Profile updated successfully', data: mockUpdatedUser }); }); it('should return 400 if name is missing', async () => { // Arrange mockReq.body = { name: '' }; mockUpdateProfileHandler.handle.mockRejectedValue(new Error('Name is required')); // Act await controller.updateMe(mockReq, mockRes); // Assert expect(mockRes.status).toHaveBeenCalledWith(400); expect(mockRes.json).toHaveBeenCalledWith({ error: 'Name is required' }); }); }); });