diff --git a/src/screens/UserPortal/Volunteer/Groups/Groups.test.tsx b/src/screens/UserPortal/Volunteer/Groups/Groups.spec.tsx similarity index 76% rename from src/screens/UserPortal/Volunteer/Groups/Groups.test.tsx rename to src/screens/UserPortal/Volunteer/Groups/Groups.spec.tsx index bc0a4993b9..b9bf6c29c0 100644 --- a/src/screens/UserPortal/Volunteer/Groups/Groups.test.tsx +++ b/src/screens/UserPortal/Volunteer/Groups/Groups.spec.tsx @@ -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'; @@ -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(); @@ -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 => { await act(() => { return new Promise((resolve) => { @@ -39,6 +53,11 @@ const debounceWait = async (ms = 300): Promise => { }); }; +/** + * 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( @@ -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( @@ -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'); @@ -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'); @@ -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'); @@ -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); @@ -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); @@ -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); @@ -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);