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

Refactor: test from jest to vitest #2688

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { MockedProvider } from '@apollo/react-testing';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import type { RenderResult } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import {
cleanup,
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
Expand All @@ -15,6 +21,7 @@ import Groups from './Groups';
import type { ApolloLink } from '@apollo/client';
import { MOCKS, EMPTY_MOCKS, ERROR_MOCKS } from './Groups.mocks';
import useLocalStorage from 'utils/useLocalstorage';
import { vi } from 'vitest';

const { setItem } = useLocalStorage();

Expand All @@ -31,6 +38,13 @@ const t = {
...JSON.parse(JSON.stringify(i18n.getDataByLanguage('en')?.errors ?? {})),
};

/**
* Introduces a delay for the specified duration.
* This is primarily used to simulate debounce behavior in tests.
* @param ms - The duration to delay in milliseconds. Defaults to 300ms.
* @returns A Promise that resolves after the specified duration.
*/

const debounceWait = async (ms = 300): Promise<void> => {
await act(() => {
return new Promise((resolve) => {
Expand All @@ -39,6 +53,11 @@ const debounceWait = async (ms = 300): Promise<void> => {
});
};

/**
* Renders the Groups component using a specific Apollo link.
* @param link - The ApolloLink instance to use for mocking GraphQL requests.
* @returns The rendered component wrapped in test utilities.
*/
const renderGroups = (link: ApolloLink): RenderResult => {
return render(
<MockedProvider addTypename={false} link={link}>
Expand All @@ -61,22 +80,33 @@ const renderGroups = (link: ApolloLink): RenderResult => {
);
};

/**
* Describes the testing suite for the Groups screen.
*/
describe('Testing Groups Screen', () => {
beforeAll(() => {
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ orgId: 'orgId' }),
}));
vi.mock('react-router-dom', async () => {
const actual = await vi.importActual('react-router-dom');
return {
...actual,
useParams: () => ({ orgId: 'orgId' }),
};
});
});

beforeEach(() => {
setItem('userId', 'userId');
});

afterAll(() => {
jest.clearAllMocks();
afterEach(() => {
vi.resetAllMocks();
cleanup(); // from @testing-library/react
});

/**
* Tests redirection to the fallback URL when required URL parameters are missing.
* Ensures the "paramsError" element is displayed.
*/
it('should redirect to fallback URL if URL params are undefined', async () => {
setItem('userId', null);
render(
Expand All @@ -102,12 +132,23 @@ describe('Testing Groups Screen', () => {
});
});

/**
* Checks if the Groups screen renders correctly with the expected elements.
*/
it('should render Groups screen', async () => {
renderGroups(link1);
const searchInput = await screen.findByTestId('searchBy');
expect(searchInput).toBeInTheDocument();
// Verify other critical UI elements
expect(await screen.findByTestId('sort')).toBeInTheDocument();
expect(await screen.findByTestId('searchByToggle')).toBeInTheDocument();
const groupElements = await screen.findAllByTestId('groupName');
expect(groupElements.length).toBeGreaterThan(0);
});

/**
* Verifies the sorting functionality of the Groups screen.
*/
it('Check Sorting Functionality', async () => {
renderGroups(link1);
const searchInput = await screen.findByTestId('searchBy');
Expand Down Expand Up @@ -137,6 +178,9 @@ describe('Testing Groups Screen', () => {
expect(groupName[0]).toHaveTextContent('Group 2');
});

/**
* Verifies the search by group functionality of the Groups screen.
*/
it('Search by Groups', async () => {
renderGroups(link1);
const searchInput = await screen.findByTestId('searchBy');
Expand All @@ -157,6 +201,9 @@ describe('Testing Groups Screen', () => {
expect(groupName[0]).toHaveTextContent('Group 1');
});

/**
* Verifies the search by leader functionality of the Groups screen.
*/
it('Search by Leader', async () => {
renderGroups(link1);
const searchInput = await screen.findByTestId('searchBy');
Expand All @@ -178,6 +225,9 @@ describe('Testing Groups Screen', () => {
expect(groupName[0]).toHaveTextContent('Group 1');
});

/**
* Verifies the behavior when there are no groups to display.
*/
it('should render screen with No Groups', async () => {
renderGroups(link3);

Expand All @@ -187,6 +237,9 @@ describe('Testing Groups Screen', () => {
});
});

/**
* Verifies the error handling when there is an issue fetching groups data.
*/
it('Error while fetching groups data', async () => {
renderGroups(link2);

Expand All @@ -195,6 +248,9 @@ describe('Testing Groups Screen', () => {
});
});

/**
* Verifies the functionality of opening and closing the ViewModal.
*/
it('Open and close ViewModal', async () => {
renderGroups(link1);

Expand All @@ -205,6 +261,9 @@ describe('Testing Groups Screen', () => {
userEvent.click(await screen.findByTestId('volunteerViewModalCloseBtn'));
});

/**
* Verifies the functionality of opening and closing the GroupModal.
*/
it('Open and close GroupModal', async () => {
renderGroups(link1);

Expand Down
Loading