Skip to content

Commit

Permalink
Merge pull request #188 from SELab-2/frontend-tests
Browse files Browse the repository at this point in the history
Frontend tests
  • Loading branch information
PJDeSmijter authored May 23, 2024
2 parents da7ba2d + f66e1d5 commit 2b4d681
Show file tree
Hide file tree
Showing 27 changed files with 1,022 additions and 73 deletions.
11 changes: 11 additions & 0 deletions frontend/__test__/AddButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {fireEvent, render, screen} from "@testing-library/react";
import React from "react";
import AddButton from "@app/[locale]/components/AddButton";

describe("AddButton", () => {
it("render", async () => {
render(<AddButton translationkey={"key"} href={"/home"}/>);
const backButton = screen.getByText(/key/i);
fireEvent.click(backButton);
});
});
21 changes: 21 additions & 0 deletions frontend/__test__/CourseControls.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {render, screen} from "@testing-library/react";
import React from "react";
import CourseControls from "@app/[locale]/components/CourseControls";
import {APIError, fetchUserData, UserData} from "@lib/api";

jest.mock('../lib/api', () => ({
fetchUserData: jest.fn(),
}));
describe("CourseControls", () => {
it("render coursecontrols", async () => {
const mockOnYearChange = jest.fn();
render(<CourseControls selectedYear={2024} onYearChange={mockOnYearChange}/>);

expect(screen.getByText(/all_courses/i)).toBeInTheDocument();

expect(screen.getByText(/create_course/i)).toBeInTheDocument();

expect(screen.getByText(/view_archive/i)).toBeInTheDocument();

});
});
26 changes: 26 additions & 0 deletions frontend/__test__/CourseDetails.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {render, screen} from "@testing-library/react";
import React from "react";
import CourseDetails from "@app/[locale]/components/CourseDetails";

// mock copyclipboardbutton component
jest.mock("../app/[locale]/components/CopyToClipboardButton", () => ({
__esModule: true,
default: jest.fn(() => <div>Mocked CopyToClipboardButton</div>), // Mock rendering
}));

jest.mock('../lib/api', () => ({
getCourse: jest.fn(),
Course: jest.fn(),
UserData: jest.fn(),
getUserData: jest.fn(),
}));
describe("CourseDetails", () => {
it("render CourseDetails", async () => {
render(<CourseDetails course_id={1}/>);

expect(screen.getByText("no_description")).toBeInTheDocument();

expect(screen.getByText("description")).toBeInTheDocument();

});
});
20 changes: 20 additions & 0 deletions frontend/__test__/CoursesGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {render, screen} from "@testing-library/react";
import React from "react";
import CoursesGrid from "@app/[locale]/components/CoursesGrid";


jest.mock("../app/[locale]/components/CourseCard", () => ({
__esModule: true,
default: jest.fn(() => <div>Mocked CourseCard</div>), // Mock rendering
}));


jest.mock('../lib/api', () => ({
getCoursesForUser: jest.fn(),
}));

describe("CourseDetails", () => {
it("render CourseDetails", async () => {
render(<CoursesGrid selectedYear={"2023-2024"}/>);
});
});
71 changes: 71 additions & 0 deletions frontend/__test__/EditUserForm.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import EditUserForm from '../app/[locale]/components/EditUserForm';
import { getUser, updateUserData } from '@lib/api';

jest.mock('../lib/api', () => ({
getUser: jest.fn(),
updateUserData: jest.fn(),
}));

jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key) => key,
}),
}));

describe('EditUserForm', () => {
const mockUser = {
first_name: 'John',
last_name: 'Doe',
role: 2,
email: 'john.doe@example.com',
};

beforeEach(() => {
jest.resetAllMocks();
getUser.mockResolvedValue(mockUser);
updateUserData.mockResolvedValue({});
});

it('fetches and displays user data correctly', async () => {
render(<EditUserForm userId={1} />);

await waitFor(() => {
expect(screen.getByText('email')).toBeInTheDocument();
expect(screen.getByText('john.doe@example.com')).toBeInTheDocument();
expect(screen.getByDisplayValue('John')).toBeInTheDocument();
expect(screen.getByDisplayValue('Doe')).toBeInTheDocument();
expect(screen.getByText('teacher')).toBeInTheDocument();
});
});

it('updates user data correctly', async () => {
render(<EditUserForm userId={1} />);

// Wait for the user data to be fetched and displayed
await waitFor(() => {
expect(screen.getByDisplayValue('John')).toBeInTheDocument();
});

// Change the first name
fireEvent.change(screen.getByDisplayValue('John'), {
target: { value: 'Jane' },
});

// Submit the form
fireEvent.submit(screen.getByRole('button', { name: 'save changes' }));

// Check if the updateUserData was called with the updated data
await waitFor(() => {
expect(updateUserData).toHaveBeenCalledWith(1, expect.any(FormData));
});

const formData = updateUserData.mock.calls[0][1];
expect(formData.get('first_name')).toBe('Jane');
expect(formData.get('last_name')).toBe('Doe');
expect(formData.get('role')).toBe('2');
expect(formData.get('email')).toBe('john.doe@example.com');
});
});
15 changes: 15 additions & 0 deletions frontend/__test__/GroupSubmissionList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {render} from "@testing-library/react";
import React from "react";
import GroupSubmissionList from "@app/[locale]/components/GroupSubmissionList";


jest.mock("../app/[locale]/components/ListView", () => ({
__esModule: true,
default: jest.fn(() => <div>Mocked ListView</div>), // Mock rendering
}));

describe("CourseDetails", () => {
it("render CourseDetails", async () => {
render(<GroupSubmissionList page_size={5} project_id={1} search={"test"}/>);
});
});
10 changes: 6 additions & 4 deletions frontend/__test__/ListView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,17 @@ const mockLastSubmission = {
output_test: 'output',
};

const headers = ['name',
const headers1 = ['name',
<React.Fragment key="description"><NotesIcon
style={{fontSize: '20px', verticalAlign: 'middle', marginBottom: '3px'}}/>{" " + 'description'}
</React.Fragment>,
, 'open',
<React.Fragment key="joinleave"><MeetingRoomIcon
style={{fontSize: '20px', verticalAlign: 'middle', marginBottom: '3px'}}/>{" " + 'join_leave'}
</React.Fragment>];
const headers_backend = ['name', 'description', 'open', 'join/leave']
const headers_backend1 = ['name', 'description', 'open', 'join/leave']




describe('ListView', () => {
Expand Down Expand Up @@ -147,8 +149,8 @@ describe('ListView', () => {
act(() => {
render(<ListView
admin={true}
headers={headers}
headers_backend={headers_backend}
headers={headers1}
headers_backend={headers_backend1}
sortable={[true, true, true, true]}
get={'courses'}
search_text={"search_course"}
Expand Down
70 changes: 70 additions & 0 deletions frontend/__test__/ProjectTable.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import {render, screen, waitFor} from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import ProjectTable from '@app/[locale]/components/ProjectTable';
import {getProjectsFromCourse, getUserData} from '@lib/api';

jest.mock('../lib/api', () => ({
getProjectsFromCourse: jest.fn(),
getUserData: jest.fn(),
}));

describe('ProjectTable', () => {
const projects = [
{
project_id: 1,
name: 'Project 1',
deadline: '2024-06-01T12:00:00Z',
visible: true,
},
{
project_id: 2,
name: 'Project 2',
deadline: '2024-06-10T12:00:00Z',
visible: false,
},
];

const userData = { /* Mock user data */};

beforeEach(() => {
getProjectsFromCourse.mockResolvedValue(projects);
getUserData.mockResolvedValue(userData);
});

afterEach(() => {
jest.clearAllMocks();
});

it('renders project table with correct data', async () => {
render(<ProjectTable course_id={123}/>);

// Wait for async operations to complete
await waitFor(() => {
expect(screen.getByText('Project 1')).toBeInTheDocument();
expect(screen.getByText('Project 2')).toBeInTheDocument();
});
});

it('renders correct project data after sorting', async () => {
render(<ProjectTable course_id={123}/>);

// Wait for async operations to complete
await waitFor(() => {
expect(screen.getByText('Project 1')).toBeInTheDocument();
expect(screen.getByText('Project 2')).toBeInTheDocument();
});

// Sort the table by project name (descending)
const projectNameHeader = screen.getByText('Project Name');
projectNameHeader.click();
projectNameHeader.click();

// Wait for table to re-render with sorted data
await waitFor(() => {
expect(screen.getByText('Project 2')).toBeInTheDocument(); // Now Project 2 should appear first
expect(screen.getByText('Project 1')).toBeInTheDocument();
});
});

});
2 changes: 1 addition & 1 deletion frontend/__test__/ProjectTableTeacher.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import {render, screen, fireEvent, within} from '@testing-library/react';
import '@testing-library/jest-dom';
import ProjectTableTeacher from '@app/[locale]/components/ProjectTable'; // Adjust the import path as necessary
import ProjectTableTeacher from '@app/[locale]/components/ProjectTable';
import * as api from '@lib/api';

// Mocking the necessary modules
Expand Down
59 changes: 59 additions & 0 deletions frontend/__test__/StatusButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import StatusButton from '@app/[locale]/components/StatusButton';

jest.mock('@mui/icons-material/Check', () => () => <div data-testid="check-icon" />);
jest.mock('@mui/icons-material/HelpOutline', () => () => <div data-testid="help-icon" />);
describe('StatusButton', () => {
let files: any[];
let setFiles: jest.Mock;

beforeEach(() => {
files = ['+', '~', '-'];
setFiles = jest.fn((newFiles) => {
files = newFiles;
});
});

it('renders the initial status correctly', () => {
render(<StatusButton files={files} setFiles={setFiles} fileIndex={0} />);
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
});

it('cycles through statuses on click', () => {
render(<StatusButton files={files} setFiles={setFiles} fileIndex={0} />);

// Click to change status
fireEvent.click(screen.getByRole('button'));
expect(screen.getByTestId('help-icon')).toBeInTheDocument();
expect(setFiles).toHaveBeenCalledWith(['~', '~', '-']);

// Click to change status again
fireEvent.click(screen.getByRole('button'));
expect(setFiles).toHaveBeenCalledWith(['-', '~', '-']);

// Click to change status back to initial
fireEvent.click(screen.getByRole('button'));
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
expect(setFiles).toHaveBeenCalledWith(['+', '~', '-']);
});

it('renders correct status for fileIndex 1', () => {
render(<StatusButton files={files} setFiles={setFiles} fileIndex={1} />);
expect(screen.getByTestId('help-icon')).toBeInTheDocument();
});

it('renders correct status for fileIndex 2', () => {
render(<StatusButton files={files} setFiles={setFiles} fileIndex={2} />);
});

it('handles an empty file state correctly', () => {
files = ['', '~', '-'];
render(<StatusButton files={files} setFiles={setFiles} fileIndex={0} />);

fireEvent.click(screen.getByRole('button'));
expect(screen.getByTestId('check-icon')).toBeInTheDocument();
expect(setFiles).toHaveBeenCalledWith(['+', '~', '-']);
});
});
37 changes: 37 additions & 0 deletions frontend/__test__/SubmissionDetailsPage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import {render, screen, waitFor} from '@testing-library/react';
import SubmissionDetailsPage from '@app/[locale]/components/SubmissionDetailsPage';

jest.mock('../lib/api', () => ({
getSubmission: jest.fn().mockResolvedValue({
submission_nr: 1,
output_simple_test: false,
feedback_simple_test: {
'0': ['Feedback 1'],
'2': ['Feedback 2']
},
}),
getProjectFromSubmission: jest.fn().mockResolvedValue(456),
}));


describe('SubmissionDetailsPage', () => {
test('renders submission details correctly', async () => {
render(<SubmissionDetailsPage locale="en" submission_id={1}/>);

expect(screen.getByRole('progressbar')).toBeInTheDocument();

await waitFor(() => expect(screen.queryByRole('progressbar')).not.toBeInTheDocument());

// Ensure submission details are rendered
expect(screen.getByText(/submission #/i)).toBeInTheDocument();
expect(screen.getByText(/evaluation status/i)).toBeInTheDocument();
expect(screen.getByText(/uploaded_files/i)).toBeInTheDocument();
expect(screen.getByText(/feedback_simple_test_0/i)).toBeInTheDocument();
expect(screen.getByText(/Feedback 1/i)).toBeInTheDocument();

// Test the feedback for simple test "2"
expect(screen.getByText(/feedback_simple_test_2/i)).toBeInTheDocument();
expect(screen.getByText(/Feedback 2/i)).toBeInTheDocument();
});
});
Loading

0 comments on commit 2b4d681

Please sign in to comment.