diff --git a/src/components/UserListCard/UserListCard.spec.tsx b/src/components/UserListCard/UserListCard.spec.tsx index 6a3b2d42d8..e278a4bcc3 100644 --- a/src/components/UserListCard/UserListCard.spec.tsx +++ b/src/components/UserListCard/UserListCard.spec.tsx @@ -1,21 +1,46 @@ import React from 'react'; -import { render, screen, act } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import { MockedProvider } from '@apollo/react-testing'; import userEvent from '@testing-library/user-event'; import { I18nextProvider } from 'react-i18next'; +import { toast } from 'react-toastify'; import UserListCard from './UserListCard'; import { ADD_ADMIN_MUTATION } from 'GraphQl/Mutations/mutations'; import i18nForTest from 'utils/i18nForTest'; import { BrowserRouter } from 'react-router-dom'; -import { StaticMockLink } from 'utils/StaticMockLink'; -import { vi, describe, it, beforeEach } from 'vitest'; +import { vi, describe, beforeEach, afterEach } from 'vitest'; + +// Test constants +const TEST_USER_ID = '456'; +const TEST_ORG_ID = '554'; +const TEST_SUCCESS_MESSAGE = 'User is added as admin.'; +const TEST_ERROR_MESSAGE = 'An error occurred'; +const DEFAULT_TIMEOUT = 2000; + +// Mock modules +vi.mock('react-toastify', () => ({ + toast: { + success: vi.fn(), + error: vi.fn(), + }, +})); + +vi.mock('react-router-dom', async () => { + const actual = await vi.importActual('react-router-dom'); + return { + ...actual, + useParams: () => ({ + orgId: TEST_ORG_ID, + }), + }; +}); const MOCKS = [ { request: { query: ADD_ADMIN_MUTATION, - variables: { userid: '784', orgid: '554' }, + variables: { userid: TEST_USER_ID, orgid: TEST_ORG_ID }, }, result: { data: { @@ -28,24 +53,41 @@ const MOCKS = [ }, }, ]; -const link = new StaticMockLink(MOCKS, true); -async function wait(ms = 100): Promise<void> { - await act(() => new Promise((resolve) => setTimeout(resolve, ms))); -} +const ERROR_MOCKS = [ + { + request: { + query: ADD_ADMIN_MUTATION, + variables: { userid: TEST_USER_ID, orgid: TEST_ORG_ID }, + }, + error: new Error(TEST_ERROR_MESSAGE), + }, +]; describe('Testing User List Card', () => { + const mockReload = vi.fn(); + beforeEach(() => { vi.spyOn(global, 'alert').mockImplementation(() => {}); + Object.defineProperty(window, 'location', { + value: { + reload: mockReload, + }, + writable: true, + }); + }); + + afterEach(() => { + vi.clearAllMocks(); }); - it('Should render props and text elements test for the page component', async () => { + test('Should show success toast and reload page after successful mutation', async () => { const props = { - id: '456', + id: TEST_USER_ID, }; render( - <MockedProvider addTypename={false} link={link}> + <MockedProvider addTypename={false} mocks={MOCKS}> <BrowserRouter> <I18nextProvider i18n={i18nForTest}> <UserListCard key={123} {...props} /> @@ -54,17 +96,31 @@ describe('Testing User List Card', () => { </MockedProvider>, ); - await wait(); - userEvent.click(screen.getByText(/Add Admin/i)); + const button = screen.getByText(/Add Admin/i); + await userEvent.click(button); + + await waitFor( + () => { + expect(toast.success).toHaveBeenCalledWith(TEST_SUCCESS_MESSAGE); + }, + { timeout: DEFAULT_TIMEOUT }, + ); + + await waitFor( + () => { + expect(mockReload).toHaveBeenCalled(); + }, + { timeout: DEFAULT_TIMEOUT }, + ); }); - it('Should render text elements when props value is not passed', async () => { + test('Should show error toast when mutation fails', async () => { const props = { - id: '456', + id: TEST_USER_ID, }; render( - <MockedProvider addTypename={false} link={link}> + <MockedProvider addTypename={false} mocks={ERROR_MOCKS}> <BrowserRouter> <I18nextProvider i18n={i18nForTest}> <UserListCard key={123} {...props} /> @@ -73,7 +129,63 @@ describe('Testing User List Card', () => { </MockedProvider>, ); - await wait(); - userEvent.click(screen.getByText(/Add Admin/i)); + const button = screen.getByText(/Add Admin/i); + await userEvent.click(button); + + await waitFor( + () => { + expect(toast.error).toHaveBeenCalled(); + }, + { timeout: DEFAULT_TIMEOUT }, + ); + }); + + test('Should render button with correct styling', () => { + const props = { + id: TEST_USER_ID, + key: 1, + }; + + render( + <MockedProvider mocks={[]} addTypename={false}> + <BrowserRouter> + <I18nextProvider i18n={i18nForTest}> + <UserListCard {...props} /> + </I18nextProvider> + </BrowserRouter> + </MockedProvider>, + ); + + const button = screen.getByRole('button', { name: /Add Admin/i }); + expect(button).toBeInTheDocument(); + expect(button.className).toContain('memberfontcreatedbtn'); + }); + + test('Should handle translations and URL parameters correctly', async () => { + const props = { + id: TEST_USER_ID, + }; + + render( + <MockedProvider addTypename={false} mocks={MOCKS}> + <BrowserRouter> + <I18nextProvider i18n={i18nForTest}> + <UserListCard key={123} {...props} /> + </I18nextProvider> + </BrowserRouter> + </MockedProvider>, + ); + + const button = screen.getByText(/Add Admin/i); + expect(button).toBeInTheDocument(); + + await userEvent.click(button); + + await waitFor( + () => { + expect(toast.success).toHaveBeenCalled(); + }, + { timeout: DEFAULT_TIMEOUT }, + ); }); }); diff --git a/src/components/UserListCard/UserListCard.tsx b/src/components/UserListCard/UserListCard.tsx index 157c18f404..fee79644c2 100644 --- a/src/components/UserListCard/UserListCard.tsx +++ b/src/components/UserListCard/UserListCard.tsx @@ -45,7 +45,6 @@ function userListCard(props: InterfaceUserListCardProps): JSX.Element { }, }); - /* istanbul ignore next */ if (data) { toast.success(t('addedAsAdmin') as string); setTimeout(() => { @@ -53,7 +52,6 @@ function userListCard(props: InterfaceUserListCardProps): JSX.Element { }, 2000); } } catch (error: unknown) { - /* istanbul ignore next */ errorHandler(t, error); } };