diff --git a/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_EMPTY.md b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_EMPTY.md new file mode 100644 index 0000000000..dc17afac1e --- /dev/null +++ b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_EMPTY.md @@ -0,0 +1,79 @@ +[Admin Docs](/) + +*** + +# Variable: MOCK\_EMPTY + +> `const` **MOCK\_EMPTY**: `object`[] + +Defined in: [src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:294](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts#L294) + +## Type declaration + +### request + +> **request**: `object` + +#### request.query + +> **query**: `DocumentNode` = `USER_TAGS_MEMBERS_TO_ASSIGN_TO` + +#### request.variables + +> **variables**: `object` + +#### request.variables.first + +> **first**: `number` = `TAGS_QUERY_DATA_CHUNK_SIZE` + +#### request.variables.id + +> **id**: `string` = `'1'` + +#### request.variables.where + +> **where**: `object` + +#### request.variables.where.firstName + +> **firstName**: `object` + +#### request.variables.where.firstName.starts\_with + +> **starts\_with**: `string` = `''` + +#### request.variables.where.lastName + +> **lastName**: `object` + +#### request.variables.where.lastName.starts\_with + +> **starts\_with**: `string` = `''` + +### result + +> **result**: `object` + +#### result.data + +> **data**: `object` + +#### result.data.getUsersToAssignTo + +> **getUsersToAssignTo**: `object` + +#### result.data.getUsersToAssignTo.usersToAssignTo + +> **usersToAssignTo**: `object` + +#### result.data.getUsersToAssignTo.usersToAssignTo.edges + +> **edges**: `any`[] = `[]` + +#### result.data.getUsersToAssignTo.usersToAssignTo.pageInfo + +> **pageInfo**: `object` + +#### result.data.getUsersToAssignTo.usersToAssignTo.pageInfo.hasNextPage + +> **hasNextPage**: `boolean` = `false` diff --git a/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NON_ERROR.md b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NON_ERROR.md new file mode 100644 index 0000000000..f2b5fdabb6 --- /dev/null +++ b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NON_ERROR.md @@ -0,0 +1,9 @@ +[Admin Docs](/) + +*** + +# Variable: MOCK\_NON\_ERROR + +> `const` **MOCK\_NON\_ERROR**: (\{ `error`: `undefined`; `request`: \{ `query`: `DocumentNode`; `variables`: \{ `first`: `number`; `id`: `string`; `tagId`: `undefined`; `userIds`: `undefined`; `where`: \{ `firstName`: \{ `starts_with`: `string`; \}; `lastName`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `getUsersToAssignTo`: \{ `usersToAssignTo`: \{ `edges`: `object`[]; `pageInfo`: \{ `endCursor`: `string`; `hasNextPage`: `boolean`; \}; \}; \}; \}; \}; \} \| \{ `error`: `Error`; `request`: \{ `query`: `DocumentNode`; `variables`: \{ `first`: `undefined`; `id`: `undefined`; `tagId`: `string`; `userIds`: `string`[]; `where`: `undefined`; \}; \}; `result`: `undefined`; \})[] + +Defined in: [src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:322](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts#L322) diff --git a/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NO_DATA.md b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NO_DATA.md new file mode 100644 index 0000000000..fa9241cdd6 --- /dev/null +++ b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NO_DATA.md @@ -0,0 +1,9 @@ +[Admin Docs](/) + +*** + +# Variable: MOCK\_NO\_DATA + +> `const` **MOCK\_NO\_DATA**: (\{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `first`: `number`; `id`: `string`; `tagId`: `undefined`; `userIds`: `undefined`; `where`: \{ `firstName`: \{ `starts_with`: `string`; \}; `lastName`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `getUsersToAssignTo`: \{ `usersToAssignTo`: \{ `edges`: `object`[]; `pageInfo`: \{ `endCursor`: `string`; `hasNextPage`: `boolean`; \}; \}; \}; \}; \}; \} \| \{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `first`: `undefined`; `id`: `undefined`; `tagId`: `string`; `userIds`: `string`[]; `where`: `undefined`; \}; \}; `result`: \{ `data`: `any`; \}; \})[] + +Defined in: [src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:413](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts#L413) diff --git a/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NULL_FETCH_MORE.md b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NULL_FETCH_MORE.md new file mode 100644 index 0000000000..296337df61 --- /dev/null +++ b/docs/docs/auto-docs/components/AddPeopleToTag/AddPeopleToTagsMocks/variables/MOCK_NULL_FETCH_MORE.md @@ -0,0 +1,9 @@ +[Admin Docs](/) + +*** + +# Variable: MOCK\_NULL\_FETCH\_MORE + +> `const` **MOCK\_NULL\_FETCH\_MORE**: (\{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `undefined`; `first`: `number`; `id`: `string`; `where`: \{ `firstName`: \{ `starts_with`: `string`; \}; `lastName`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `getUsersToAssignTo`: \{ `usersToAssignTo`: \{ `edges`: `object`[]; `pageInfo`: \{ `endCursor`: `string`; `hasNextPage`: `boolean`; \}; \}; \}; \}; \}; \} \| \{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `string`; `first`: `number`; `id`: `string`; `where`: \{ `firstName`: \{ `starts_with`: `string`; \}; `lastName`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: `any`; \}; \})[] + +Defined in: [src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts:362](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts#L362) diff --git a/src/components/AddPeopleToTag/AddPeopleToTag.spec.tsx b/src/components/AddPeopleToTag/AddPeopleToTag.spec.tsx index 8867335017..3c7f57ce33 100644 --- a/src/components/AddPeopleToTag/AddPeopleToTag.spec.tsx +++ b/src/components/AddPeopleToTag/AddPeopleToTag.spec.tsx @@ -8,6 +8,7 @@ import { fireEvent, cleanup, waitFor, + act, } from '@testing-library/react'; import { Provider } from 'react-redux'; import { MemoryRouter, Route, Routes } from 'react-router-dom'; @@ -22,7 +23,14 @@ import { InMemoryCache, type ApolloLink } from '@apollo/client'; import type { InterfaceAddPeopleToTagProps } from './AddPeopleToTag'; import AddPeopleToTag from './AddPeopleToTag'; import i18n from 'utils/i18nForTest'; -import { MOCKS, MOCKS_ERROR } from './AddPeopleToTagsMocks'; +import { + MOCK_EMPTY, + MOCK_NULL_FETCH_MORE, + MOCK_NO_DATA, + MOCK_NON_ERROR, + MOCKS, + MOCKS_ERROR, +} from './AddPeopleToTagsMocks'; import type { TFunction } from 'i18next'; const link = new StaticMockLink(MOCKS, true); @@ -50,6 +58,14 @@ const translations = { ...JSON.parse(JSON.stringify(i18n.getDataByLanguage('en')?.errors ?? {})), }; +const defaultProps: InterfaceAddPeopleToTagProps = { + addPeopleToTagModalIsOpen: false, + hideAddPeopleToTagModal: vi.fn(), + refetchAssignedMembersData: vi.fn(), + t: ((key: string) => key) as TFunction<'translation', 'manageTag'>, + tCommon: ((key: string) => key) as TFunction<'common', undefined>, +}; + const props: InterfaceAddPeopleToTagProps = { addPeopleToTagModalIsOpen: true, hideAddPeopleToTagModal: () => {}, @@ -113,6 +129,28 @@ const renderAddPeopleToTagModal = ( ); }; +const renderComponent = ( + customProps?: Partial, +): RenderResult => + render( + + + + + + + } + /> + + + + + , + ); + describe('Organisation Tags Page', () => { beforeEach(() => { // Mocking `react-router-dom` to return the actual module and override `useParams` @@ -320,4 +358,112 @@ describe('Organisation Tags Page', () => { ); }); }); + + it('Displays "no more members found" overlay when data is empty', async () => { + const link = new StaticMockLink(MOCK_EMPTY, true); + renderAddPeopleToTagModal(props, link); + + await waitFor(() => { + expect( + screen.queryByTestId('infiniteScrollLoader'), + ).not.toBeInTheDocument(); + }); + + expect( + screen.getByText(translations.noMoreMembersFound), + ).toBeInTheDocument(); + }); + + it('Resets the search state and refetches when the modal transitions from closed to open', async () => { + const { rerender } = renderComponent({ addPeopleToTagModalIsOpen: false }); + + act(() => { + rerender( + + + + + + + } + /> + + + + + , + ); + }); + + await waitFor(() => { + expect(screen.getByPlaceholderText('firstName')).toHaveValue(''); + expect(screen.getByPlaceholderText('lastName')).toHaveValue(''); + }); + }); + + it('displays the unknownError toast if a non-Error is thrown', async () => { + const linkWithNonError = new StaticMockLink(MOCK_NON_ERROR, true); + + const customProps = { + ...props, + addPeopleToTagModalIsOpen: true, + }; + + renderAddPeopleToTagModal(customProps, linkWithNonError); + + await waitFor(() => { + expect(screen.getAllByTestId('selectMemberBtn')).toHaveLength(1); + }); + + userEvent.click(screen.getAllByTestId('selectMemberBtn')[0]); + userEvent.click(screen.getByTestId('assignPeopleBtn')); + + await waitFor(() => { + expect(toast.error).toHaveBeenCalled(); + }); + }); + + it('returns prevResult if fetchMoreResult is null', async () => { + const linkWithNullFetchMore = new StaticMockLink( + MOCK_NULL_FETCH_MORE, + true, + ); + + renderAddPeopleToTagModal(props, linkWithNullFetchMore); + + await waitFor(() => { + expect(screen.getByText('member 1')).toBeInTheDocument(); + }); + + const scrollableDiv = screen.getByTestId('addPeopleToTagScrollableDiv'); + fireEvent.scroll(scrollableDiv, { + target: { scrollY: 99999 }, + }); + + await waitFor(() => { + expect(screen.getAllByTestId('memberName')).toHaveLength(1); + }); + }); + + it('skips the if(data) block when the mutation returns data = null', async () => { + const linkNoData = new StaticMockLink(MOCK_NO_DATA, true); + renderAddPeopleToTagModal(props, linkNoData); + + await waitFor(() => { + expect(screen.getAllByTestId('selectMemberBtn')).toHaveLength(1); + }); + + userEvent.click(screen.getAllByTestId('selectMemberBtn')[0]); + userEvent.click(screen.getByTestId('assignPeopleBtn')); + + await waitFor(() => { + expect(toast.success).not.toHaveBeenCalled(); + }); + }); }); diff --git a/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts b/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts index fbaf812186..1a0bf5a198 100644 --- a/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts +++ b/src/components/AddPeopleToTag/AddPeopleToTagsMocks.ts @@ -290,3 +290,162 @@ export const MOCKS_ERROR = [ error: new Error('Mock Graphql Error'), }, ]; + +export const MOCK_EMPTY = [ + { + request: { + query: USER_TAGS_MEMBERS_TO_ASSIGN_TO, + variables: { + id: '1', + first: TAGS_QUERY_DATA_CHUNK_SIZE, + where: { + firstName: { starts_with: '' }, + lastName: { starts_with: '' }, + }, + }, + }, + result: { + data: { + getUsersToAssignTo: { + usersToAssignTo: { + edges: [], // No data + pageInfo: { + hasNextPage: false, + }, + }, + }, + }, + }, + }, +]; + +export const MOCK_NON_ERROR = [ + { + request: { + query: USER_TAGS_MEMBERS_TO_ASSIGN_TO, + variables: { + id: '1', + first: TAGS_QUERY_DATA_CHUNK_SIZE, + where: { + firstName: { starts_with: '' }, + lastName: { starts_with: '' }, + }, + }, + }, + result: { + data: { + getUsersToAssignTo: { + usersToAssignTo: { + edges: [ + { + node: { _id: '1', firstName: 'Test', lastName: 'User' }, + cursor: 'cursor1', + }, + ], + pageInfo: { hasNextPage: false, endCursor: 'cursor1' }, + }, + }, + }, + }, + }, + { + request: { + query: ADD_PEOPLE_TO_TAG, + variables: { tagId: '1', userIds: ['1'] }, + }, + error: { + graphQLErrors: [{ message: 'Plain object' }], + } as unknown as Error, + }, +]; + +export const MOCK_NULL_FETCH_MORE = [ + { + request: { + query: USER_TAGS_MEMBERS_TO_ASSIGN_TO, + variables: { + id: '1', + first: TAGS_QUERY_DATA_CHUNK_SIZE, + where: { + firstName: { starts_with: '' }, + lastName: { starts_with: '' }, + }, + }, + }, + result: { + data: { + getUsersToAssignTo: { + usersToAssignTo: { + edges: [ + { + node: { _id: '1', firstName: 'member', lastName: '1' }, + cursor: '1', + }, + ], + pageInfo: { + hasNextPage: true, + endCursor: '1', + }, + }, + }, + }, + }, + }, + { + request: { + query: USER_TAGS_MEMBERS_TO_ASSIGN_TO, + variables: { + id: '1', + first: TAGS_QUERY_DATA_CHUNK_SIZE, + after: '1', + where: { + firstName: { starts_with: '' }, + lastName: { starts_with: '' }, + }, + }, + }, + result: { + data: null, + }, + }, +]; + +export const MOCK_NO_DATA = [ + { + request: { + query: USER_TAGS_MEMBERS_TO_ASSIGN_TO, + variables: { + id: '1', + first: TAGS_QUERY_DATA_CHUNK_SIZE, + where: { + firstName: { starts_with: '' }, + lastName: { starts_with: '' }, + }, + }, + }, + result: { + data: { + getUsersToAssignTo: { + usersToAssignTo: { + edges: [ + { + node: { _id: '1', firstName: 'NoData', lastName: 'Test' }, + cursor: 'cursor1', + }, + ], + pageInfo: { hasNextPage: false, endCursor: 'cursor1' }, + }, + }, + }, + }, + }, + { + request: { + query: ADD_PEOPLE_TO_TAG, + variables: { tagId: '1', userIds: ['1'] }, + }, + result: { + data: null, + }, + }, +];