From ceda26480e15ef584e1ca025772c763016634b50 Mon Sep 17 00:00:00 2001 From: Aad1tya27 Date: Tue, 24 Dec 2024 21:13:37 +0530 Subject: [PATCH] shifted to vitest and added some tests --- .../Users/{Users.test.tsx => Users.spec.tsx} | 198 ++++++++++++++++-- src/screens/Users/Users.tsx | 68 ++++-- 2 files changed, 225 insertions(+), 41 deletions(-) rename src/screens/Users/{Users.test.tsx => Users.spec.tsx} (77%) diff --git a/src/screens/Users/Users.test.tsx b/src/screens/Users/Users.spec.tsx similarity index 77% rename from src/screens/Users/Users.test.tsx rename to src/screens/Users/Users.spec.tsx index 3e4f6983c4..ae6ecce94f 100644 --- a/src/screens/Users/Users.test.tsx +++ b/src/screens/Users/Users.spec.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { MockedProvider } from '@apollo/react-testing'; import { act, fireEvent, render, screen } from '@testing-library/react'; -import 'jest-localstorage-mock'; -import 'jest-location-mock'; import { I18nextProvider } from 'react-i18next'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; @@ -14,6 +12,7 @@ import i18nForTest from 'utils/i18nForTest'; import Users from './Users'; import { EMPTY_MOCKS, MOCKS, MOCKS2 } from './UsersMocks'; import useLocalStorage from 'utils/useLocalstorage'; +import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; import { USER_LIST, @@ -301,11 +300,11 @@ beforeEach(() => { afterEach(() => { localStorage.clear(); - jest.clearAllMocks(); + vi.restoreAllMocks(); }); describe('Testing Users screen', () => { - test('Component should be rendered properly', async () => { + it('Component should be rendered properly', async () => { render( @@ -322,7 +321,7 @@ describe('Testing Users screen', () => { expect(screen.getByTestId('testcomp')).toBeInTheDocument(); }); - test(`Component should be rendered properly when user is not superAdmin + it(`Component should be rendered properly when user is not superAdmin and or userId does not exists in localstorage`, async () => { setItem('AdminFor', ['123']); removeItem('SuperAdmin'); @@ -342,7 +341,7 @@ describe('Testing Users screen', () => { await wait(); }); - test(`Component should be rendered properly when userId does not exists in localstorage`, async () => { + it(`Component should be rendered properly when userId does not exists in localstorage`, async () => { removeItem('AdminFor'); removeItem('SuperAdmin'); await wait(); @@ -361,7 +360,7 @@ describe('Testing Users screen', () => { await wait(); }); - test('Component should be rendered properly when user is superAdmin', async () => { + it('Component should be rendered properly when user is superAdmin', async () => { render( @@ -377,7 +376,7 @@ describe('Testing Users screen', () => { await wait(); }); - test('Testing seach by name functionality', async () => { + it('Testing seach by name functionality', async () => { render( @@ -416,7 +415,7 @@ describe('Testing Users screen', () => { await wait(); }); - test('testing search not found', async () => { + it('testing search not found', async () => { await act(async () => { render( @@ -446,7 +445,7 @@ describe('Testing Users screen', () => { expect(screen.queryByText(/No User Found/i)).toBeInTheDocument(); }); - test('Testing User data is not present', async () => { + it('Testing User data is not present', async () => { render( @@ -463,7 +462,7 @@ describe('Testing Users screen', () => { expect(screen.getByText(/No User Found/i)).toBeTruthy(); }); - test('Should render warning alert when there are no organizations', async () => { + it('Should render warning alert when there are no organizations', async () => { const { container } = render( @@ -483,7 +482,7 @@ describe('Testing Users screen', () => { ); }); - test('Should not render warning alert when there are organizations present', async () => { + it('Should not render warning alert when there are organizations present', async () => { const { container } = render( @@ -504,7 +503,7 @@ describe('Testing Users screen', () => { ); }); - test('Testing filter functionality', async () => { + it('Testing filter functionality', async () => { await act(async () => { render( @@ -577,7 +576,7 @@ describe('Testing Users screen', () => { expect(searchInput).toBeInTheDocument(); }); - test('check for rerendering', async () => { + it('check for rerendering', async () => { const { rerender } = render( @@ -607,7 +606,7 @@ describe('Testing Users screen', () => { await wait(); }); - test('should set hasMore to false if users length is less than perPageResult', async () => { + it('should set hasMore to false if users length is less than perPageResult', async () => { const link = new StaticMockLink(EMPTY_MOCKS, true); render( @@ -629,7 +628,7 @@ describe('Testing Users screen', () => { expect(screen.getByText(/No User Found/i)).toBeInTheDocument(); }); - test('should filter users correctly', async () => { + it('should filter users correctly', async () => { await act(async () => { render( @@ -658,7 +657,7 @@ describe('Testing Users screen', () => { fireEvent.click(filterAdmin); }); - await wait(); + // await wait(); expect(screen.getByText('Jane Doe')).toBeInTheDocument(); await act(async () => { @@ -671,7 +670,7 @@ describe('Testing Users screen', () => { fireEvent.click(filterSuperAdmin); }); - await wait(); + // await wait(); expect(screen.getByText('John Doe')).toBeInTheDocument(); await act(async () => { @@ -683,7 +682,7 @@ describe('Testing Users screen', () => { fireEvent.click(filterUser); }); - await wait(); + // await wait(); expect(screen.getByText('Jack Smith')).toBeInTheDocument(); await act(async () => { @@ -696,13 +695,13 @@ describe('Testing Users screen', () => { fireEvent.click(filterCancel); }); - await wait(); + // await wait(); expect(screen.getByText('John Doe')).toBeInTheDocument(); expect(screen.getByText('Jane Doe')).toBeInTheDocument(); expect(screen.getByText('Jack Smith')).toBeInTheDocument(); }); - test('Users should be sorted in newest order correctly', async () => { + it('Users should be sorted in newest order correctly', async () => { await act(async () => { render( @@ -739,7 +738,7 @@ describe('Testing Users screen', () => { expect(displayedUsers[2]).toHaveTextContent('John Doe'); }); - test('Check if pressing enter key triggers search', async () => { + it('Check if pressing enter key triggers search', async () => { await act(async () => { render( @@ -764,4 +763,159 @@ describe('Testing Users screen', () => { userEvent.type(searchInput, '{enter}'); }); }); + + it('Users should be sorted in oldest order correctly', async () => { + await act(async () => { + render( + + + + + + + + + + , + ); + }); + await wait(); + + const inputText = screen.getByTestId('sortUsers'); + + await act(async () => { + fireEvent.click(inputText); + }); + + const toggleTite = screen.getByTestId('oldest'); + + await act(async () => { + fireEvent.click(toggleTite); + }); + + // Verify the users are sorted by oldest + + const displayedUsers = screen.getAllByRole('row'); + await wait(); + expect(displayedUsers[1]).toHaveTextContent('Jack Smith'); + expect(displayedUsers[2]).toHaveTextContent('John Doe'); + }); + + it('Role filter should not update if selected role is already selected', async () => { + await act(async () => { + render( + + + + + + + + + + , + ); + }); + await wait(); + + const filterButton = screen.getByTestId('filterUsers'); + + await act(async () => { + fireEvent.click(filterButton); + }); + + const filterAdmin = screen.getByTestId('admin'); + + await act(async () => { + fireEvent.click(filterAdmin); + }); + + // await wait(); + expect(screen.getByText('Jane Doe')).toBeInTheDocument(); + + await act(async () => { + fireEvent.click(filterAdmin); + }); + + // await wait(); + expect(screen.getByText('Jane Doe')).toBeInTheDocument(); + }); + + it('Sort filter should not update if selected sort is already selected', async () => { + await act(async () => { + render( + + + + + + + + + + , + ); + }); + await wait(); + + const inputText = screen.getByTestId('sortUsers'); + + await act(async () => { + fireEvent.click(inputText); + }); + + const toggleTite = screen.getByTestId('newest'); + + await act(async () => { + fireEvent.click(toggleTite); + }); + + // Verify the users are sorted by newest + + const displayedUsers = screen.getAllByRole('row'); + await wait(); + expect(displayedUsers[1]).toHaveTextContent('Jane Doe'); + expect(displayedUsers[2]).toHaveTextContent('John Doe'); + + await act(async () => { + fireEvent.click(inputText); + }); + + const toggleTite2 = screen.getByTestId('newest'); + + await act(async () => { + fireEvent.click(toggleTite2); + }); + + // Verify the users are sorted by newest + + const displayedUsers2 = screen.getAllByRole('row'); + await wait(); + expect(displayedUsers2[1]).toHaveTextContent('Jane Doe'); + expect(displayedUsers2[2]).toHaveTextContent('John Doe'); + }); + + it('Reset and Refetch function should work when we search an empty string', async () => { + render( + + + + + + + + + , + ); + + await wait(); + const searchBtn = screen.getByTestId('searchButton'); + const search1 = ''; + userEvent.type(screen.getByTestId(/searchByName/i), search1); + userEvent.click(searchBtn); + await wait(); + expect(screen.queryByText(/Jane Doe/i)).toBeInTheDocument(); + expect(screen.queryByText(/John Doe/i)).toBeInTheDocument(); + expect(screen.queryByText(/Jack Smith/i)).toBeInTheDocument(); + }); }); diff --git a/src/screens/Users/Users.tsx b/src/screens/Users/Users.tsx index 74656fa4c0..2c0b38b08e 100644 --- a/src/screens/Users/Users.tsx +++ b/src/screens/Users/Users.tsx @@ -77,15 +77,19 @@ const Users = (): JSX.Element => { const [searchByName, setSearchByName] = useState(''); const [sortingOption, setSortingOption] = useState('newest'); const [filteringOption, setFilteringOption] = useState('cancel'); + const [loadUnqUsers, setLoadUnqUsers] = useState(0); const userType = getItem('SuperAdmin') ? 'SUPERADMIN' : getItem('AdminFor') ? 'ADMIN' : 'USER'; const loggedInUserId = getItem('id'); + const [usersData, setUsersData] = useState< + { users: InterfaceQueryUserListItem[] } | undefined + >(undefined); const { - data: usersData, + data, loading: loading, fetchMore, refetch: refetchUsers, @@ -114,6 +118,12 @@ const Users = (): JSX.Element => { notifyOnNetworkStatusChange: true, }); + useEffect(() => { + if (data) { + setUsersData(data); + } + }, [data, isLoading]); + const { data: dataOrgs } = useQuery(ORGANIZATION_CONNECTION_LIST); const [displayedUsers, setDisplayedUsers] = useState(usersData?.users || []); @@ -122,15 +132,13 @@ const Users = (): JSX.Element => { if (!usersData) { return; } - if (usersData && usersData.users) { - // console.log(sortingOption) - let newDisplayedUsers = sortUsers(usersData.users, sortingOption); - newDisplayedUsers = filterUsers(newDisplayedUsers, filteringOption); - setDisplayedUsers(newDisplayedUsers); - if (newDisplayedUsers.length < perPageResult) { - setHasMore(false); - } + + if (usersData.users.length < perPageResult) { + setHasMore(false); } + let newDisplayedUsers = sortUsers(usersData.users, sortingOption); + newDisplayedUsers = filterUsers(newDisplayedUsers, filteringOption); + setDisplayedUsers(newDisplayedUsers); }, [usersData, sortingOption, filteringOption]); // To clear the search when the component is unmounted @@ -167,6 +175,12 @@ const Users = (): JSX.Element => { } }, [loading]); + useEffect(() => { + if (loadUnqUsers > 0) { + loadMoreUsers(displayedUsers.length, loadUnqUsers); + } + }, [displayedUsers]); + const handleSearch = (value: string): void => { setSearchByName(value); if (value === '') { @@ -209,11 +223,12 @@ const Users = (): JSX.Element => { setHasMore(true); }; /* istanbul ignore next */ - const loadMoreUsers = (): void => { + const loadMoreUsers = (skipValue: number, limitVal: number): void => { setIsLoadingMore(true); fetchMore({ variables: { - skip: displayedUsers.length || 0, + first: limitVal + 2 * perPageResult || perPageResult, + skip: skipValue - perPageResult >= 0 ? skipValue - perPageResult : 0, filter: searchByName, order: sortingOption === 'newest' ? 'createdAt_DESC' : 'createdAt_ASC', }, @@ -227,14 +242,25 @@ const Users = (): JSX.Element => { ) => { setIsLoadingMore(false); if (!fetchMoreResult) return prev || { users: [] }; - if (fetchMoreResult.users.length < perPageResult) { - setHasMore(false); - } + const mergedUsers = [...(prev?.users || []), ...fetchMoreResult.users]; const uniqueUsers = Array.from( new Map(mergedUsers.map((user) => [user.user._id, user])).values(), ); + if (uniqueUsers.length < mergedUsers.length) { + setLoadUnqUsers(mergedUsers.length - uniqueUsers.length); + } else setLoadUnqUsers(0); + + if (prev?.users) { + if (uniqueUsers.length - prev?.users.length < perPageResult) { + setHasMore(false); + } + } else { + if (uniqueUsers.length < perPageResult) { + setHasMore(false); + } + } return { users: uniqueUsers }; }, @@ -247,7 +273,6 @@ const Users = (): JSX.Element => { } setHasMore(true); setSortingOption(option); - setDisplayedUsers([]); }; const sortUsers = ( @@ -276,7 +301,6 @@ const Users = (): JSX.Element => { if (option === filteringOption) { return; } - setDisplayedUsers([]); setFilteringOption(option); setHasMore(true); }; @@ -362,13 +386,17 @@ const Users = (): JSX.Element => { handleSorting('newest')} + onClick={(): void => { + handleSorting('newest'); + }} data-testid="newest" > {t('Newest')} handleSorting('oldest')} + onClick={(): void => { + handleSorting('oldest'); + }} data-testid="oldest" > {t('Oldest')} @@ -454,7 +482,9 @@ const Users = (): JSX.Element => { /* istanbul ignore next */ displayedUsers.length ?? 0 } - next={loadMoreUsers} + next={() => { + loadMoreUsers(displayedUsers.length, perPageResult); + }} loader={