diff --git a/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/default.md b/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/default.md index 30289de648..26d7ee6965 100644 --- a/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/default.md +++ b/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/default.md @@ -6,7 +6,7 @@ > **default**(`__namedParameters`): `JSX.Element` -Defined in: [src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx:60](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx#L60) +Defined in: [src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx:136](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx#L136) ## Parameters diff --git a/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/handleCreateDirectChat.md b/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/handleCreateDirectChat.md new file mode 100644 index 0000000000..3110596695 --- /dev/null +++ b/docs/docs/auto-docs/components/UserPortal/CreateDirectChat/CreateDirectChat/functions/handleCreateDirectChat.md @@ -0,0 +1,47 @@ +[Admin Docs](/) + +*** + +# Function: handleCreateDirectChat() + +> **handleCreateDirectChat**(`id`, `chats`, `t`, `createChat`, `organizationId`, `userId`, `chatsListRefetch`, `toggleCreateDirectChatModal`): `Promise`\<`void`\> + +Defined in: [src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx:70](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx#L70) + +## Parameters + +### id + +`string` + +### chats + +[`Chat`](../../../../../screens/UserPortal/Chat/Chat/type-aliases/Chat.md)[] + +### t + +`TFunction`\<`"userChat"`\> + +### createChat + +(`options`?) => `Promise`\<`FetchResult`\<`unknown`\>\>(`arg0`) => `unknown` + +### organizationId + +`string` + +### userId + +`string` + +### chatsListRefetch + +(`variables`?) => `Promise`\<`ApolloQueryResult`\<`unknown`\>\>() => `Promise`\<`ApolloQueryResult`\<`unknown`\>\> + +### toggleCreateDirectChatModal + +() => `void`() => `void` + +## Returns + +`Promise`\<`void`\> diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_EMPTY.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_EMPTY.md new file mode 100644 index 0000000000..d56cf22f94 --- /dev/null +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_EMPTY.md @@ -0,0 +1,63 @@ +[Admin Docs](/) + +*** + +# Variable: MOCKS\_EMPTY + +> `const` **MOCKS\_EMPTY**: `object`[] + +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:344](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L344) + +## Type declaration + +### request + +> **request**: `object` + +#### request.query + +> **query**: `DocumentNode` = `ORGANIZATION_USER_TAGS_LIST` + +#### request.variables + +> **variables**: `object` + +#### request.variables.first + +> **first**: `number` = `TAGS_QUERY_DATA_CHUNK_SIZE` + +#### request.variables.id + +> **id**: `string` = `'orgId'` + +#### request.variables.sortedBy + +> **sortedBy**: `object` + +#### request.variables.sortedBy.id + +> **id**: `string` = `'DESCENDING'` + +#### request.variables.where + +> **where**: `object` + +#### request.variables.where.name + +> **name**: `object` + +#### request.variables.where.name.starts\_with + +> **starts\_with**: `string` = `''` + +### result + +> **result**: `object` + +#### result.data + +> **data**: `object` + +#### result.data.organizations + +> **organizations**: `object`[] diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR.md index 8c6c8edf5b..85692fe00e 100644 --- a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR.md +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR.md @@ -6,7 +6,7 @@ > `const` **MOCKS\_ERROR**: `object`[] -Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:413](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L413) +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:319](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L319) ## Type declaration @@ -32,7 +32,7 @@ Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:413](https:// #### request.variables.id -> **id**: `string` = `'orgId'` +> **id**: `string` = `'orgIdError'` #### request.variables.sortedBy diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR_ERROR_TAG.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR_ERROR_TAG.md new file mode 100644 index 0000000000..823edeaf2d --- /dev/null +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_ERROR_ERROR_TAG.md @@ -0,0 +1,35 @@ +[Admin Docs](/) + +*** + +# Variable: MOCKS\_ERROR\_ERROR\_TAG + +> `const` **MOCKS\_ERROR\_ERROR\_TAG**: `object`[] + +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:334](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L334) + +## Type declaration + +### error + +> **error**: `Error` + +### request + +> **request**: `object` + +#### request.query + +> **query**: `DocumentNode` = `CREATE_USER_TAG` + +#### request.variables + +> **variables**: `object` + +#### request.variables.name + +> **name**: `string` = `'userTagE'` + +#### request.variables.organizationId + +> **organizationId**: `string` = `'orgId'` diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NO_MORE_PAGES.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NO_MORE_PAGES.md new file mode 100644 index 0000000000..0004623929 --- /dev/null +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NO_MORE_PAGES.md @@ -0,0 +1,9 @@ +[Admin Docs](/) + +*** + +# Variable: MOCKS\_NO\_MORE\_PAGES + +> `const` **MOCKS\_NO\_MORE\_PAGES**: (\{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `undefined`; `first`: `number`; `id`: `string`; `sortedBy`: \{ `id`: `string`; \}; `where`: \{ `name`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `organizations`: `object`[]; \}; \}; \} \| \{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `string`; `first`: `number`; `id`: `string`; `sortedBy`: \{ `id`: `string`; \}; `where`: \{ `name`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: `any`; \}; \})[] + +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:477](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L477) diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NULL_END_CURSOR.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NULL_END_CURSOR.md new file mode 100644 index 0000000000..a4d9a79a7a --- /dev/null +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_NULL_END_CURSOR.md @@ -0,0 +1,9 @@ +[Admin Docs](/) + +*** + +# Variable: MOCKS\_NULL\_END\_CURSOR + +> `const` **MOCKS\_NULL\_END\_CURSOR**: (\{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `undefined`; `first`: `number`; `id`: `string`; `sortedBy`: \{ `id`: `string`; \}; `where`: \{ `name`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `organizations`: `object`[]; \}; \}; \} \| \{ `request`: \{ `query`: `DocumentNode`; `variables`: \{ `after`: `any`; `first`: `number`; `id`: `string`; `sortedBy`: \{ `id`: `string`; \}; `where`: \{ `name`: \{ `starts_with`: `string`; \}; \}; \}; \}; `result`: \{ `data`: \{ `organizations`: `object`[]; \}; \}; \})[] + +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:391](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L391) diff --git a/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_UNDEFINED_USER_TAGS.md b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_UNDEFINED_USER_TAGS.md new file mode 100644 index 0000000000..f41ce5d255 --- /dev/null +++ b/docs/docs/auto-docs/screens/OrganizationTags/OrganizationTagsMocks/variables/MOCKS_UNDEFINED_USER_TAGS.md @@ -0,0 +1,63 @@ +[Admin Docs](/) + +*** + +# Variable: MOCKS\_UNDEFINED\_USER\_TAGS + +> `const` **MOCKS\_UNDEFINED\_USER\_TAGS**: `object`[] + +Defined in: [src/screens/OrganizationTags/OrganizationTagsMocks.ts:376](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/OrganizationTags/OrganizationTagsMocks.ts#L376) + +## Type declaration + +### request + +> **request**: `object` + +#### request.query + +> **query**: `DocumentNode` = `ORGANIZATION_USER_TAGS_LIST` + +#### request.variables + +> **variables**: `object` + +#### request.variables.first + +> **first**: `number` = `TAGS_QUERY_DATA_CHUNK_SIZE` + +#### request.variables.id + +> **id**: `string` = `'orgId'` + +#### request.variables.sortedBy + +> **sortedBy**: `object` + +#### request.variables.sortedBy.id + +> **id**: `string` = `'DESCENDING'` + +#### request.variables.where + +> **where**: `object` + +#### request.variables.where.name + +> **name**: `object` + +#### request.variables.where.name.starts\_with + +> **starts\_with**: `string` = `''` + +### result + +> **result**: `object` + +#### result.data + +> **data**: `object` + +#### result.data.organizations + +> **organizations**: `object`[] diff --git a/docs/docs/auto-docs/screens/UserPortal/Chat/Chat/type-aliases/Chat.md b/docs/docs/auto-docs/screens/UserPortal/Chat/Chat/type-aliases/Chat.md new file mode 100644 index 0000000000..fbf0404818 --- /dev/null +++ b/docs/docs/auto-docs/screens/UserPortal/Chat/Chat/type-aliases/Chat.md @@ -0,0 +1,39 @@ +[Admin Docs](/) + +*** + +# Type Alias: Chat + +> **Chat**: `object` + +Defined in: [src/screens/UserPortal/Chat/Chat.tsx:87](https://github.com/PalisadoesFoundation/talawa-admin/blob/main/src/screens/UserPortal/Chat/Chat.tsx#L87) + +## Type declaration + +### \_id + +> **\_id**: `string` + +### image + +> **image**: `string` + +### isGroup + +> **isGroup**: `boolean` + +### messages + +> **messages**: `DirectMessage`[] + +### name + +> **name**: `string` + +### unseenMessagesByUsers + +> **unseenMessagesByUsers**: `string` + +### users + +> **users**: `object`[] diff --git a/src/components/UserPortal/CreateDirectChat/CreateDirectChat.spec.tsx b/src/components/UserPortal/CreateDirectChat/CreateDirectChat.spec.tsx index ccf23a882b..77f852c5b7 100644 --- a/src/components/UserPortal/CreateDirectChat/CreateDirectChat.spec.tsx +++ b/src/components/UserPortal/CreateDirectChat/CreateDirectChat.spec.tsx @@ -13,7 +13,8 @@ import { BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { store } from 'state/store'; import i18nForTest from 'utils/i18nForTest'; -import Chat from '../../../screens/UserPortal/Chat/Chat'; +import type { Chat } from '../../../screens/UserPortal/Chat/Chat'; +import ChatComp from '../../../screens/UserPortal/Chat/Chat'; import { CREATE_CHAT, MARK_CHAT_MESSAGES_AS_READ, @@ -27,6 +28,10 @@ import { } from 'GraphQl/Queries/PlugInQueries'; import useLocalStorage from 'utils/useLocalstorage'; import { vi } from 'vitest'; +import { handleCreateDirectChat } from './CreateDirectChat'; +import type { TFunction } from 'i18next'; +import type { ApolloQueryResult, FetchResult } from '@apollo/client'; + const { setItem } = useLocalStorage(); /** @@ -3947,7 +3952,7 @@ describe('Testing Create Direct Chat Modal [User Portal]', () => { - + @@ -4001,7 +4006,7 @@ describe('Testing Create Direct Chat Modal [User Portal]', () => { - + @@ -4033,4 +4038,160 @@ describe('Testing Create Direct Chat Modal [User Portal]', () => { await wait(); }); + it('should create chat if a conversation does not with the selected user', async () => { + const t = ((key: string) => { + return key; + }) as TFunction; + const createChat = vi.fn(async (): Promise> => { + return { data: {} } as FetchResult; + }); + const chatsListRefetch = vi.fn( + async (): Promise> => { + return { data: {} } as ApolloQueryResult; + }, + ); + const toggleCreateDirectChatModal = vi.fn(); + const chats: Chat[] = [ + { + _id: '1', + isGroup: false, + name: '', + image: '', + messages: [], + unseenMessagesByUsers: '{}', + users: [ + { + _id: '1', + firstName: 'Aaditya', + lastName: 'Agarwal', + email: '', + image: '', + }, + { + _id: '3', + firstName: 'Test', + lastName: 'User', + email: '', + image: '', + }, + ], + }, + ]; + await handleCreateDirectChat( + '2', + chats, + t, + createChat, + '1', + '1', + chatsListRefetch, + toggleCreateDirectChatModal, + ); + expect(createChat).toHaveBeenCalled(); + expect(chatsListRefetch).toHaveBeenCalled(); + expect(toggleCreateDirectChatModal).toHaveBeenCalled(); + }); + it('should not create chat if a conversation already exists with the selected user', async () => { + const t = ((key: string) => { + return key; + }) as TFunction; + const createChat = vi.fn(async (): Promise> => { + return { data: {} } as FetchResult; + }); + const chatsListRefetch = vi.fn( + async (): Promise> => { + return { data: {} } as ApolloQueryResult; + }, + ); + const toggleCreateDirectChatModal = vi.fn(); + const chats: Chat[] = [ + { + _id: '1', + isGroup: false, + name: '', + image: '', + messages: [], + unseenMessagesByUsers: '{}', + users: [ + { + _id: '1', + firstName: 'Aaditya', + lastName: 'Agarwal', + email: '', + image: '', + }, + { + _id: '2', + firstName: 'Test', + lastName: 'User', + email: '', + image: '', + }, + ], + }, + ]; + await handleCreateDirectChat( + '2', + chats, + t, + createChat, + '1', + '1', + chatsListRefetch, + toggleCreateDirectChatModal, + ); + expect(createChat).not.toHaveBeenCalled(); + expect(chatsListRefetch).not.toHaveBeenCalled(); + expect(toggleCreateDirectChatModal).not.toHaveBeenCalled(); + }); + + it('should handle error if create chat fails', async () => { + const t = ((key: string) => { + return key; + }) as TFunction; + const createChat = vi.fn(async (): Promise> => { + throw new Error('Error'); + }); + const chatsListRefetch = vi.fn(); + const toggleCreateDirectChatModal = vi.fn(); + const chats: Chat[] = [ + { + _id: '1', + isGroup: false, + name: '', + image: '', + messages: [], + unseenMessagesByUsers: '{}', + users: [ + { + _id: '1', + firstName: 'Aaditya', + lastName: 'Agarwal', + email: '', + image: '', + }, + { + _id: '3', + firstName: 'Test', + lastName: 'User', + email: '', + image: '', + }, + ], + }, + ]; + await handleCreateDirectChat( + '2', + chats, + t, + createChat, + '1', + '1', + chatsListRefetch, + toggleCreateDirectChatModal, + ); + expect(createChat).toHaveBeenCalled(); + expect(chatsListRefetch).not.toHaveBeenCalled(); + expect(toggleCreateDirectChatModal).not.toHaveBeenCalled(); + }); }); diff --git a/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx b/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx index 4b1c2cda02..7fe105c2bd 100644 --- a/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx +++ b/src/components/UserPortal/CreateDirectChat/CreateDirectChat.tsx @@ -1,7 +1,14 @@ import { Paper, TableBody } from '@mui/material'; import React, { useState } from 'react'; import { Button, Form, Modal } from 'react-bootstrap'; -import type { ApolloQueryResult } from '@apollo/client'; +import type { + ApolloCache, + ApolloQueryResult, + DefaultContext, + FetchResult, + MutationFunctionOptions, + OperationVariables, +} from '@apollo/client'; import { useMutation, useQuery } from '@apollo/client'; import useLocalStorage from 'utils/useLocalstorage'; import { CREATE_CHAT } from 'GraphQl/Mutations/OrganizationMutations'; @@ -18,7 +25,9 @@ import { Search } from '@mui/icons-material'; import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import styles from '../../../style/app.module.css'; - +import type { Chat } from 'screens/UserPortal/Chat/Chat'; +import { errorHandler } from 'utils/errorHandler'; +import type { TFunction } from 'i18next'; interface InterfaceCreateDirectChatProps { toggleCreateDirectChatModal: () => void; createDirectChatModalisOpen: boolean; @@ -29,6 +38,7 @@ interface InterfaceCreateDirectChatProps { }> | undefined, ) => Promise>; + chats: Chat[]; } /** @@ -57,10 +67,77 @@ const StyledTableRow = styled(TableRow)(() => ({ const { getItem } = useLocalStorage(); +export const handleCreateDirectChat = async ( + id: string, + chats: Chat[], + t: TFunction<'translation', 'userChat'>, + createChat: { + ( + options?: + | MutationFunctionOptions< + unknown, + OperationVariables, + DefaultContext, + ApolloCache + > + | undefined, + ): Promise>; + (arg0: { + variables: { + organizationId: unknown; + userIds: unknown[]; + isGroup: boolean; + }; + }): unknown; + }, + organizationId: string | undefined, + userId: string | null, + chatsListRefetch: { + ( + variables?: + | Partial<{ + id: string; + }> + | undefined, + ): Promise>; + (): Promise>; + }, + toggleCreateDirectChatModal: { (): void; (): void }, +): Promise => { + const existingChat = chats.find( + (chat) => + chat.users?.length === 2 && chat.users.some((user) => user._id === id), + ); + if (existingChat) { + const existingUser = existingChat.users.find((user) => user._id === id); + errorHandler( + t, + new Error( + `A conversation with ${existingUser?.firstName || 'this user'} already exists!`, + ), + ); + } else { + try { + await createChat({ + variables: { + organizationId, + userIds: [userId, id], + isGroup: false, + }, + }); + await chatsListRefetch(); + toggleCreateDirectChatModal(); + } catch (error) { + errorHandler(t, error); + } + } +}; + export default function createDirectChatModal({ toggleCreateDirectChatModal, createDirectChatModalisOpen, chatsListRefetch, + chats, }: InterfaceCreateDirectChatProps): JSX.Element { const { t } = useTranslation('translation', { keyPrefix: 'userChat', @@ -73,18 +150,6 @@ export default function createDirectChatModal({ const [createChat] = useMutation(CREATE_CHAT); - const handleCreateDirectChat = async (id: string): Promise => { - await createChat({ - variables: { - organizationId, - userIds: [userId, id], - isGroup: false, - }, - }); - await chatsListRefetch(); - toggleCreateDirectChatModal(); - }; - const { data: allUsersData, loading: allUsersLoading, @@ -98,7 +163,6 @@ export default function createDirectChatModal({ const handleUserModalSearchChange = (e: React.FormEvent): void => { e.preventDefault(); - /* istanbul ignore next */ const [firstName, lastName] = userName.split(' '); const newFilterData = { @@ -190,7 +254,16 @@ export default function createDirectChatModal({