diff --git a/client/jest.config.js b/client/jest.config.js index a7cc3c69..d94e6272 100644 --- a/client/jest.config.js +++ b/client/jest.config.js @@ -21,6 +21,7 @@ const customJestConfig = { ], coverageDirectory: 'coverage', coverageReporters: ['lcov', 'text'], + coveragePathIgnorePatterns: ['src/app/api/auth/'], }; module.exports = createJestConfig(customJestConfig); diff --git a/client/src/app/(protected)/groups/[id]/Content/Sessions/__test__/Sessions.test.tsx b/client/src/app/(protected)/groups/[id]/Content/Sessions/__test__/Sessions.test.tsx index 3659ae58..ae8d3664 100644 --- a/client/src/app/(protected)/groups/[id]/Content/Sessions/__test__/Sessions.test.tsx +++ b/client/src/app/(protected)/groups/[id]/Content/Sessions/__test__/Sessions.test.tsx @@ -2,6 +2,7 @@ import { render, screen, waitFor } from '@testing-library/react'; import Sessions from '../Sessions'; import { SessionProvider } from 'next-auth/react'; import userEvent from '@testing-library/user-event'; +import { SessionService } from '@/services/SessionsService'; jest.mock('next/navigation', () => ({ usePathname: jest.fn().mockReturnValue('groups/1'), @@ -21,6 +22,10 @@ const renderSessions = (isMember: boolean = true) => { }; describe('Session Component', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + test('render session correct', () => { renderSessions(); }); @@ -65,21 +70,54 @@ describe('Session Component', () => { ).toBeInTheDocument(); }); - // test WIP - it.skip('should handle form submission error', async () => { + it('calls createSession on form submit with the correct data', () => { + // Setup mock implementation of createSession + SessionService.createSession = jest + .fn() + .mockResolvedValue('Session created'); + renderSessions(); // Click in Create session button userEvent.click(screen.getByText('Crear sesión')); - // fill form to create session (Required fields: title, start and end time ) - - // send form - await userEvent.click(screen.getByText('Crear')); + waitFor(() => { + // Enter data into form fields + userEvent.type(screen.getByLabelText(/Title/i), 'Study Session'); + userEvent.type( + screen.getByLabelText(/Description/i), + 'Description of the session' + ); + userEvent.type(screen.getByLabelText(/Location/i), 'Room 101'); + userEvent.type(screen.getByLabelText(/Meet Link/i), 'http://meet.link'); + userEvent.type(screen.getByLabelText(/Start Time/i), '2023-11-03T14:00'); + userEvent.type(screen.getByLabelText(/End Time/i), '2023-11-03T15:00'); + }); - // waiting to error - await waitFor(() => { - expect(screen.queryByText('Error')).toBeInTheDocument(); + // Submit the form + userEvent.click(screen.getByRole('button', { name: /Crear sesión/i })); + + // Wait for the createSession function to be called + waitFor(() => expect(SessionService.createSession).toHaveBeenCalled()); + + waitFor(() => { + // Check if the createSession was called with the correct parameters + expect(SessionService.createSession).toHaveBeenCalledWith( + expect.objectContaining({ + name: 'Study Session', + description: 'Description of the session', + location: 'Room 101', + meeting_link: 'http://meet.link', + start_time: '2023-11-03T14:00', + end_time: '2023-11-03T15:00', + group_id: 1, + }), + expect.any(String) // accessToken + ); + + expect( + screen.getByText(/¡Sesión creada con éxito!/i) + ).toBeInTheDocument(); }); }); }); diff --git a/client/src/app/(protected)/users/[id]/__test__/UserBanner.test.tsx b/client/src/app/(protected)/users/[id]/__test__/UserBanner.test.tsx index 03e33c4f..4c037866 100644 --- a/client/src/app/(protected)/users/[id]/__test__/UserBanner.test.tsx +++ b/client/src/app/(protected)/users/[id]/__test__/UserBanner.test.tsx @@ -166,4 +166,27 @@ describe('UserBanner Component', () => { expect(screen.queryByTestId('editButton')).not.toBeInTheDocument(); }); + + it('should display multiple careers correctly', () => { + // Create a user with multiple careers + const careers = [ + { ...testCareer, name: 'Career 1' }, + { ...testCareer, name: 'Career 2' }, + { ...testCareer, name: 'Career 3' }, + ]; + const userWithMultipleCareers = UserBuilder.aUser() + .withCareers(careers) + .build(); + + // Render UserBanner with the user + render(); + + // Check if the first career is displayed correctly + expect(screen.getByText('Career 1')).toBeInTheDocument(); + + // Check if the other careers are displayed correctly + careers.slice(1).forEach((career) => { + expect(screen.getByText(career.name)).toBeInTheDocument(); + }); + }); }); diff --git a/client/src/services/__test__/GroupService.test.ts b/client/src/services/__test__/GroupService.test.ts index 9e7b5e9d..1ccb9bad 100644 --- a/client/src/services/__test__/GroupService.test.ts +++ b/client/src/services/__test__/GroupService.test.ts @@ -179,4 +179,104 @@ describe('GroupService', () => { accessToken: 'mockAccessToken', }); }); + + // Testing changeRole + it('should change role from admin to participant', async () => { + // Mock API Call + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse({})); + + // Call the function + await GroupService.changeRole('member1', 'admin', 'mockToken'); + + // Assertions + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/members/member1', + method: 'PATCH', + accessToken: 'mockToken', + data: { role: 'participant' }, + }); + }); + + it('should change role from participant to admin', async () => { + // Mock API Call + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse({})); + + // Call the function + await GroupService.changeRole('member2', 'participant', 'mockToken'); + + // Assertions + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/members/member2', + method: 'PATCH', + accessToken: 'mockToken', + data: { role: 'admin' }, + }); + }); + + // Testing delete + it('should call delete group API', async () => { + // Mock API Call + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse({})); + + // Call the function + await GroupService.delete(123, 'mockToken'); + + // Assertions + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/groups/123', + method: 'DELETE', + accessToken: 'mockToken', + }); + }); + + // Testing sendMessage + it('should send a message and return its ID', async () => { + const mockData = { id: 'message1' }; + const messageContent = { content: 'Hello, World!' }; + const groupId = 123; + + // Mock API Call + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse(mockData)); + + // Call the function + const messageId = await GroupService.sendMessage( + messageContent, + 'mockToken', + groupId + ); + + // Assertions + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/groups/123/messages', + method: 'POST', + data: messageContent, + accessToken: 'mockToken', + }); + expect(messageId).toEqual('message1'); + }); + + // Testing getMessages + it('should retrieve messages for a group', async () => { + const mockMessages = [ + { id: 'message1', content: 'Hello' }, + { id: 'message2', content: 'World' }, + ]; + const groupId = 123; + + // Mock API Call + mockedApiCommunicator.mockResolvedValueOnce( + createMockResponse(mockMessages) + ); + + // Call the function + const messages = await GroupService.getMessages(groupId, 'mockToken'); + + // Assertions + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/groups/123/messages', + method: 'GET', + accessToken: 'mockToken', + }); + expect(messages).toEqual(mockMessages); + }); }); diff --git a/client/src/services/__test__/SessionsService.test.ts b/client/src/services/__test__/SessionsService.test.ts index 373db688..509ceede 100644 --- a/client/src/services/__test__/SessionsService.test.ts +++ b/client/src/services/__test__/SessionsService.test.ts @@ -103,4 +103,66 @@ describe('SessionService', () => { const result = await SessionService.getSession('1', 'mockAccessToken'); expect(result).toBeNull(); }); + + it('should update attendance and return a success message', async () => { + const mockData = { message: 'Attendance updated successfully' }; + const mockedApiCommunicator = + ApiCommunicator.commonFetch as jest.MockedFunction< + typeof ApiCommunicator.commonFetch + >; + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse(mockData)); + + const attendanceData = { attendance: { status: 'present' } }; + const result = await SessionService.updateAttendance( + '1', + 'mockAccessToken', + attendanceData + ); + expect(result).toEqual(mockData.message); + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/attendances/1', + method: 'PATCH', + data: attendanceData, + accessToken: 'mockAccessToken', + }); + }); + + it('should edit a session and return a success message', async () => { + const mockData = { message: 'Session edited successfully' }; + const sessionData = { name: 'Updated Session', location: 'Online' }; + + const mockedApiCommunicator = + ApiCommunicator.commonFetch as jest.MockedFunction< + typeof ApiCommunicator.commonFetch + >; + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse(mockData)); + + const result = await SessionService.editSession( + sessionData, + 1, + 'mockAccessToken' + ); + expect(result).toEqual(mockData.message); + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/sessions/1', + method: 'PATCH', + data: sessionData, + accessToken: 'mockAccessToken', + }); + }); + + it('should delete a session', async () => { + const mockedApiCommunicator = + ApiCommunicator.commonFetch as jest.MockedFunction< + typeof ApiCommunicator.commonFetch + >; + mockedApiCommunicator.mockResolvedValueOnce(createMockResponse({})); + + await SessionService.deleteSession(1, 'mockAccessToken'); + expect(mockedApiCommunicator).toHaveBeenCalledWith({ + url: '/sessions/1', + method: 'DELETE', + accessToken: 'mockAccessToken', + }); + }); });