Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend tests #188

Merged
merged 11 commits into from
May 23, 2024
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
Loading