stream-chat-react-native-core 4.9.0-beta.3 → 4.9.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/lib/commonjs/components/Attachment/Gallery.js +11 -9
  2. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  3. package/lib/commonjs/components/Attachment/VideoThumbnail.js +11 -5
  4. package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
  6. package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
  7. package/lib/commonjs/components/Message/Message.js +7 -6
  8. package/lib/commonjs/components/Message/Message.js.map +1 -1
  9. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +20 -27
  10. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  11. package/lib/commonjs/mock-builders/generator/attachment.js +3 -2
  12. package/lib/commonjs/mock-builders/generator/attachment.js.map +1 -1
  13. package/lib/commonjs/utils/getUrlOfImageAttachment.js +1 -1
  14. package/lib/commonjs/utils/getUrlOfImageAttachment.js.map +1 -1
  15. package/lib/commonjs/version.json +1 -1
  16. package/lib/module/components/Attachment/Gallery.js +11 -9
  17. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  18. package/lib/module/components/Attachment/VideoThumbnail.js +11 -5
  19. package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
  20. package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
  21. package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
  22. package/lib/module/components/Message/Message.js +7 -6
  23. package/lib/module/components/Message/Message.js.map +1 -1
  24. package/lib/module/contexts/messageInputContext/MessageInputContext.js +20 -27
  25. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  26. package/lib/module/mock-builders/generator/attachment.js +3 -2
  27. package/lib/module/mock-builders/generator/attachment.js.map +1 -1
  28. package/lib/module/utils/getUrlOfImageAttachment.js +1 -1
  29. package/lib/module/utils/getUrlOfImageAttachment.js.map +1 -1
  30. package/lib/module/version.json +1 -1
  31. package/lib/typescript/components/Attachment/VideoThumbnail.d.ts +3 -1
  32. package/lib/typescript/components/Attachment/utils/buildGallery/types.d.ts +1 -0
  33. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -0
  34. package/lib/typescript/contexts/messageInputContext/__tests__/MessageInputContext.test.d.ts +1 -0
  35. package/lib/typescript/contexts/messageInputContext/__tests__/isValidMessage.test.d.ts +1 -0
  36. package/lib/typescript/contexts/messageInputContext/__tests__/pickFile.test.d.ts +1 -0
  37. package/lib/typescript/contexts/messageInputContext/__tests__/removeFile.test.d.ts +1 -0
  38. package/lib/typescript/contexts/messageInputContext/__tests__/removeImage.test.d.ts +1 -0
  39. package/lib/typescript/contexts/messageInputContext/__tests__/sendMessage.test.d.ts +1 -0
  40. package/lib/typescript/contexts/messageInputContext/__tests__/sendMessageAsync.test.d.ts +1 -0
  41. package/lib/typescript/contexts/messageInputContext/__tests__/updateMessage.test.d.ts +1 -0
  42. package/lib/typescript/contexts/messageInputContext/__tests__/uploadFile.test.d.ts +1 -0
  43. package/lib/typescript/contexts/messageInputContext/__tests__/uploadImage.test.d.ts +1 -0
  44. package/lib/typescript/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.d.ts +1 -0
  45. package/lib/typescript/mock-builders/generator/attachment.d.ts +10 -0
  46. package/lib/typescript/mock-builders/generator/channel.d.ts +13 -13
  47. package/lib/typescript/mock-builders/generator/message.d.ts +38 -0
  48. package/lib/typescript/mock-builders/generator/user.d.ts +9 -9
  49. package/package.json +5 -4
  50. package/src/components/Attachment/Gallery.tsx +2 -1
  51. package/src/components/Attachment/VideoThumbnail.tsx +12 -5
  52. package/src/components/Attachment/__tests__/Attachment.test.js +12 -0
  53. package/src/components/Attachment/__tests__/Gallery.test.js +23 -1
  54. package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts +1 -0
  55. package/src/components/Attachment/utils/buildGallery/types.ts +1 -0
  56. package/src/components/Message/Message.tsx +5 -1
  57. package/src/contexts/messageInputContext/MessageInputContext.tsx +3 -4
  58. package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +208 -0
  59. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +109 -0
  60. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessageAsync.test.tsx.snap +33 -0
  61. package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx +71 -0
  62. package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +67 -0
  63. package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx +82 -0
  64. package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx +80 -0
  65. package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +286 -0
  66. package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx +124 -0
  67. package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +92 -0
  68. package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +76 -0
  69. package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx +55 -0
  70. package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +62 -0
  71. package/src/mock-builders/generator/attachment.js +4 -2
  72. package/src/utils/getUrlOfImageAttachment.ts +1 -1
  73. package/src/version.json +1 -1
@@ -0,0 +1,286 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { act } from 'react-test-renderer';
3
+
4
+ import { renderHook } from '@testing-library/react-hooks';
5
+
6
+ import type { MessageType } from '../../../components/MessageList/hooks/useMessageList';
7
+ import {
8
+ generateFileUploadPreview,
9
+ generateImageUploadPreview,
10
+ } from '../../../mock-builders/generator/attachment';
11
+ import { generateMessage } from '../../../mock-builders/generator/message';
12
+ import { generateUser } from '../../../mock-builders/generator/user';
13
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
14
+ import { FileState } from '../../../utils/utils';
15
+ import {
16
+ InputMessageInputContextValue,
17
+ MessageInputContextValue,
18
+ MessageInputProvider,
19
+ useMessageInputContext,
20
+ } from '../MessageInputContext';
21
+
22
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
23
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
24
+
25
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
26
+ children,
27
+ ...rest
28
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
29
+ <MessageInputProvider
30
+ value={
31
+ {
32
+ ...rest,
33
+ } as MessageInputContextValue<StreamChatGenerics>
34
+ }
35
+ >
36
+ {children}
37
+ </MessageInputProvider>
38
+ );
39
+
40
+ describe("MessageInputContext's sendMessage", () => {
41
+ const message: boolean | MessageType<DefaultStreamChatGenerics> = generateMessage({
42
+ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)',
43
+ id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf',
44
+ updated_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)',
45
+ user: generateUser({
46
+ id: '5d6f6322-567e-4e1e-af90-97ef1ed5cc23',
47
+ image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33',
48
+ name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995',
49
+ }),
50
+ }) as unknown as MessageType<DefaultStreamChatGenerics>;
51
+
52
+ it('exit sendMessage when file upload status failed', async () => {
53
+ const files = generateFileUploadPreview({ state: FileState.UPLOAD_FAILED });
54
+ const images = generateImageUploadPreview({ state: FileState.UPLOAD_FAILED });
55
+ const { result } = renderHook(() => useMessageInputContext(), {
56
+ initialProps: {
57
+ editing: true,
58
+ },
59
+ wrapper: Wrapper,
60
+ });
61
+
62
+ act(() => {
63
+ result.current.setFileUploads([files]);
64
+ result.current.setImageUploads([images]);
65
+ });
66
+
67
+ act(() => {
68
+ result.current.sendMessage();
69
+ });
70
+
71
+ await expect(result.current.sending.current).toBeFalsy();
72
+ });
73
+
74
+ it('exit sendMessage when image upload status is uploading', async () => {
75
+ const images = generateImageUploadPreview({ state: FileState.UPLOADING });
76
+
77
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
78
+ initialProps: {
79
+ editing: true,
80
+ sendImageAsync: true,
81
+ },
82
+ wrapper: Wrapper,
83
+ });
84
+
85
+ act(() => {
86
+ result.current.setImageUploads([images]);
87
+ result.current.setMentionedUsers([]);
88
+ result.current.setText('');
89
+ });
90
+
91
+ act(() => {
92
+ result.current.sendMessage();
93
+ });
94
+
95
+ rerender({ editing: false, sendImageAsync: true });
96
+
97
+ await expect(result.current.asyncIds).toHaveLength(1);
98
+ await expect(result.current.sending.current).toBeFalsy();
99
+ });
100
+
101
+ it('exit sendMessage when image upload status is uploading and sendImageAsync is available', async () => {
102
+ const images = generateImageUploadPreview({ state: FileState.UPLOADING });
103
+
104
+ const { result } = renderHook(() => useMessageInputContext(), {
105
+ initialProps: {
106
+ editing: true,
107
+ },
108
+ wrapper: Wrapper,
109
+ });
110
+
111
+ act(() => {
112
+ result.current.setImageUploads([images]);
113
+ result.current.setMentionedUsers([]);
114
+ result.current.setText('');
115
+ });
116
+
117
+ act(() => {
118
+ result.current.sendMessage();
119
+ });
120
+
121
+ await expect(result.current.sending.current).toBeFalsy();
122
+ });
123
+
124
+ it('exit sendMessage when file upload status is uploading', async () => {
125
+ const files = generateFileUploadPreview({ state: FileState.UPLOADING });
126
+ const { result } = renderHook(() => useMessageInputContext(), {
127
+ initialProps: {
128
+ editing: true,
129
+ },
130
+ wrapper: Wrapper,
131
+ });
132
+
133
+ act(() => {
134
+ result.current.setFileUploads([files]);
135
+ result.current.setMentionedUsers([]);
136
+ result.current.setText('');
137
+ });
138
+
139
+ act(() => {
140
+ result.current.sendMessage();
141
+ });
142
+
143
+ await expect(result.current.sending.current).toBeFalsy();
144
+ });
145
+
146
+ it('exit sendMessage when image upload status is uploaded successfully', () => {
147
+ const sendMessageMock = jest.fn();
148
+ const clearQuotedMessageStateMock = jest.fn();
149
+ const images = [
150
+ generateImageUploadPreview({ state: FileState.UPLOADED }),
151
+ generateImageUploadPreview({ state: FileState.FINISHED }),
152
+ ];
153
+ const { result } = renderHook(() => useMessageInputContext(), {
154
+ initialProps: {
155
+ clearQuotedMessageState: clearQuotedMessageStateMock,
156
+ editing: true,
157
+ quotedMessage: false,
158
+ sendMessage: sendMessageMock,
159
+ },
160
+ wrapper: Wrapper,
161
+ });
162
+
163
+ act(() => {
164
+ result.current.setImageUploads(images);
165
+ result.current.setMentionedUsers(['dummy1', 'dummy2']);
166
+ result.current.setText('');
167
+ });
168
+
169
+ act(() => {
170
+ result.current.sendMessage();
171
+ });
172
+
173
+ expect(sendMessageMock.mock.calls[0][0]).toMatchSnapshot();
174
+ expect(clearQuotedMessageStateMock).toHaveBeenCalled();
175
+ expect(result.current.sending.current).toBeFalsy();
176
+ expect(result.current.fileUploads.length).toBe(0);
177
+ expect(result.current.imageUploads.length).toBe(0);
178
+ expect(result.current.mentionedUsers.length).toBe(0);
179
+ });
180
+
181
+ it('exit sendMessage when image upload has an error and catch block is executed', () => {
182
+ const setQuotedMessageStateMock = jest.fn();
183
+ const clearQuotedMessageStateMock = jest.fn();
184
+ const generatedQuotedMessage: boolean | MessageType<DefaultStreamChatGenerics> = message;
185
+ const images = [
186
+ generateImageUploadPreview({ state: FileState.UPLOADED }),
187
+ generateImageUploadPreview({ state: FileState.FINISHED }),
188
+ ];
189
+ const { result } = renderHook(() => useMessageInputContext(), {
190
+ initialProps: {
191
+ clearQuotedMessageState: clearQuotedMessageStateMock,
192
+ editing: true,
193
+ quotedMessage: generatedQuotedMessage,
194
+ setQuotedMessageState: setQuotedMessageStateMock,
195
+ },
196
+ wrapper: Wrapper,
197
+ });
198
+
199
+ act(() => {
200
+ result.current.setImageUploads(images);
201
+ result.current.setMentionedUsers(['dummy1', 'dummy2']);
202
+ result.current.setText('');
203
+ });
204
+
205
+ act(() => {
206
+ result.current.sendMessage();
207
+ });
208
+
209
+ expect(setQuotedMessageStateMock).toHaveBeenCalled();
210
+ expect(result.current.sending.current).toBeFalsy();
211
+ });
212
+
213
+ it('exit sendMessage when edit message is not boolean image upload status is uploaded successfully', () => {
214
+ const sendMessageMock = jest.fn();
215
+ const clearQuotedMessageStateMock = jest.fn();
216
+ const clearEditingStateMock = jest.fn();
217
+ const editMessageMock = jest.fn().mockResolvedValue({ data: {} });
218
+ const images = generateImageUploadPreview({ state: FileState.UPLOADED });
219
+ const generatedMessage: boolean | MessageType<DefaultStreamChatGenerics> = message;
220
+ const { result } = renderHook(() => useMessageInputContext(), {
221
+ initialProps: {
222
+ clearEditingState: clearEditingStateMock,
223
+ clearQuotedMessageState: clearQuotedMessageStateMock,
224
+ editing: generatedMessage,
225
+ editMessage: editMessageMock,
226
+ quotedMessage: false,
227
+ sendMessage: sendMessageMock,
228
+ },
229
+ wrapper: Wrapper,
230
+ });
231
+
232
+ act(() => {
233
+ result.current.setImageUploads([images]);
234
+ result.current.setMentionedUsers(['dummy1', 'dummy2']);
235
+ result.current.setText('');
236
+ });
237
+
238
+ act(() => {
239
+ result.current.sendMessage();
240
+ });
241
+
242
+ expect(editMessageMock.mock.calls[0][0]).toMatchSnapshot();
243
+ expect(clearEditingStateMock).toHaveBeenCalled();
244
+ expect(result.current.sending.current).toBeFalsy();
245
+ expect(result.current.fileUploads.length).toBe(0);
246
+ expect(result.current.imageUploads.length).toBe(0);
247
+ expect(result.current.mentionedUsers.length).toBe(0);
248
+ });
249
+
250
+ it('exit sendMessage when file upload status is uploaded successfully', () => {
251
+ const files = [
252
+ generateFileUploadPreview({ state: FileState.UPLOADED }),
253
+ generateFileUploadPreview({ state: FileState.FINISHED, type: 'video/mp4' }),
254
+ generateFileUploadPreview({ state: FileState.UPLOADED, type: 'audio/mp3' }),
255
+ generateFileUploadPreview({ state: FileState.FINISHED, type: 'image/jpeg' }),
256
+ ];
257
+ const sendMessageMock = jest.fn();
258
+ const clearQuotedMessageStateMock = jest.fn();
259
+ const { result } = renderHook(() => useMessageInputContext(), {
260
+ initialProps: {
261
+ clearQuotedMessageState: clearQuotedMessageStateMock,
262
+ editing: true,
263
+ quotedMessage: false,
264
+ sendMessage: sendMessageMock,
265
+ },
266
+ wrapper: Wrapper,
267
+ });
268
+
269
+ act(() => {
270
+ result.current.setFileUploads(files);
271
+ result.current.setMentionedUsers(['dummy1', 'dummy2']);
272
+ result.current.setText('');
273
+ });
274
+
275
+ act(() => {
276
+ result.current.sendMessage();
277
+ });
278
+
279
+ expect(sendMessageMock.mock.calls[0][0]).toMatchSnapshot();
280
+ expect(clearQuotedMessageStateMock).toHaveBeenCalled();
281
+ expect(result.current.sending.current).toBeFalsy();
282
+ expect(result.current.fileUploads.length).toBe(0);
283
+ expect(result.current.imageUploads.length).toBe(0);
284
+ expect(result.current.mentionedUsers.length).toBe(0);
285
+ });
286
+ });
@@ -0,0 +1,124 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { act } from 'react-test-renderer';
3
+
4
+ import { renderHook } from '@testing-library/react-hooks';
5
+
6
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
7
+ import { FileState } from '../../../utils/utils';
8
+ import {
9
+ InputMessageInputContextValue,
10
+ MessageInputContextValue,
11
+ MessageInputProvider,
12
+ useMessageInputContext,
13
+ } from '../MessageInputContext';
14
+
15
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
16
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
17
+
18
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
19
+ children,
20
+ ...rest
21
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
22
+ <MessageInputProvider
23
+ value={
24
+ {
25
+ ...rest,
26
+ } as MessageInputContextValue<StreamChatGenerics>
27
+ }
28
+ >
29
+ {children}
30
+ </MessageInputProvider>
31
+ );
32
+
33
+ describe("MessageInputContext's sendMessageAsync", () => {
34
+ it('sendMessageAsync returns undefined when image state is UPLOAD_FAILED', () => {
35
+ const asyncUploads = {
36
+ 'test-file': {
37
+ state: FileState.UPLOAD_FAILED,
38
+ url: 'https://www.test.com',
39
+ },
40
+ };
41
+
42
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
43
+ initialProps: {
44
+ editing: true,
45
+ },
46
+ wrapper: Wrapper,
47
+ });
48
+
49
+ act(() => {
50
+ result.current.setAsyncUploads(asyncUploads);
51
+ });
52
+
53
+ rerender({ editing: false });
54
+
55
+ let data;
56
+ act(() => {
57
+ data = result.current.sendMessageAsync('test-file');
58
+ });
59
+
60
+ expect(data).toBeUndefined();
61
+ });
62
+
63
+ it.each([[FileState.UPLOADED], [FileState.FINISHED]])(
64
+ 'sendImageAsync is been called with %s file upload state and checked for snapshot)',
65
+ (fileState) => {
66
+ const sendMessageMock = jest.fn();
67
+ const asyncUploads = {
68
+ 'test-file': {
69
+ state: fileState,
70
+ url: 'https://www.test.com',
71
+ },
72
+ };
73
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
74
+ initialProps: {
75
+ editing: true,
76
+ quotedMessage: false,
77
+ sendMessage: sendMessageMock,
78
+ },
79
+ wrapper: Wrapper,
80
+ });
81
+
82
+ act(() => {
83
+ result.current.setAsyncUploads(asyncUploads);
84
+ });
85
+
86
+ rerender({ editing: false, quotedMessage: false, sendMessage: sendMessageMock });
87
+
88
+ act(() => {
89
+ result.current.sendMessageAsync('test-file');
90
+ });
91
+
92
+ expect(sendMessageMock.mock.calls[0][0]).toMatchSnapshot();
93
+ },
94
+ );
95
+
96
+ it('sendMessageAsync goes to catch block', () => {
97
+ const sendMessageMock = jest.fn();
98
+ const asyncUploads = {
99
+ 'test-file': {
100
+ state: FileState.FINISHED,
101
+ url: 'https://www.test.com',
102
+ },
103
+ };
104
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
105
+ initialProps: {
106
+ editing: true,
107
+ quotedMessage: false,
108
+ },
109
+ wrapper: Wrapper,
110
+ });
111
+
112
+ act(() => {
113
+ result.current.setAsyncUploads(asyncUploads);
114
+ });
115
+
116
+ rerender({ editing: false, quotedMessage: false });
117
+
118
+ act(() => {
119
+ result.current.sendMessageAsync('test-file');
120
+ });
121
+
122
+ expect(sendMessageMock).not.toHaveBeenCalled();
123
+ });
124
+ });
@@ -0,0 +1,92 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { act } from 'react-test-renderer';
3
+
4
+ import { renderHook } from '@testing-library/react-hooks';
5
+
6
+ import type { StreamChat } from 'stream-chat';
7
+
8
+ import type { MessageType } from '../../../components/MessageList/hooks/useMessageList';
9
+
10
+ import { ChatContextValue, ChatProvider } from '../../../contexts/chatContext/ChatContext';
11
+ import { generateMessage } from '../../../mock-builders/generator/message';
12
+ import { generateUser } from '../../../mock-builders/generator/user';
13
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
14
+ import {
15
+ InputMessageInputContextValue,
16
+ MessageInputContextValue,
17
+ MessageInputProvider,
18
+ useMessageInputContext,
19
+ } from '../MessageInputContext';
20
+
21
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
22
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
23
+
24
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
25
+ children,
26
+ ...rest
27
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
28
+ <ChatProvider
29
+ value={
30
+ {
31
+ client: {
32
+ updateMessage: jest.fn().mockResolvedValue({ message: generateMessage() }),
33
+ } as unknown as StreamChat<StreamChatGenerics>,
34
+ } as ChatContextValue<StreamChatGenerics>
35
+ }
36
+ >
37
+ <MessageInputProvider
38
+ value={
39
+ {
40
+ ...rest,
41
+ } as MessageInputContextValue<StreamChatGenerics>
42
+ }
43
+ >
44
+ {children}
45
+ </MessageInputProvider>
46
+ </ChatProvider>
47
+ );
48
+
49
+ describe("MessageInputContext's updateMessage", () => {
50
+ const clearEditingStateMock = jest.fn();
51
+ const generatedMessage: boolean | MessageType<DefaultStreamChatGenerics> = generateMessage({
52
+ created_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)',
53
+ id: '7a85f744-cc89-4f82-a1d4-5456432cc8bf',
54
+ updated_at: 'Sat Jul 02 2022 23:55:13 GMT+0530 (India Standard Time)',
55
+ user: generateUser({
56
+ id: '5d6f6322-567e-4e1e-af90-97ef1ed5cc23',
57
+ image: 'fc86ddcb-bac4-400c-9afd-b0c0a1c0cd33',
58
+ name: '50cbdd0e-ca7e-4478-9e2c-be0f1ac6a995',
59
+ }),
60
+ }) as unknown as MessageType<DefaultStreamChatGenerics>;
61
+
62
+ it('updateMessage throws error as clearEditingState is not available', async () => {
63
+ const { result } = renderHook(() => useMessageInputContext(), {
64
+ initialProps: {
65
+ editing: generatedMessage,
66
+ },
67
+ wrapper: Wrapper,
68
+ });
69
+
70
+ await act(async () => {
71
+ await result.current.updateMessage();
72
+ });
73
+
74
+ expect(clearEditingStateMock).toHaveBeenCalledTimes(0);
75
+ });
76
+
77
+ it('updateMessage throws error as client.updateMessage is available', async () => {
78
+ const { result } = renderHook(() => useMessageInputContext(), {
79
+ initialProps: {
80
+ clearEditingState: clearEditingStateMock,
81
+ editing: generatedMessage,
82
+ },
83
+ wrapper: Wrapper,
84
+ });
85
+
86
+ await act(async () => {
87
+ await result.current.updateMessage();
88
+ });
89
+
90
+ expect(clearEditingStateMock).toHaveBeenCalledTimes(1);
91
+ });
92
+ });
@@ -0,0 +1,76 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { act } from 'react-test-renderer';
3
+
4
+ import { renderHook } from '@testing-library/react-hooks';
5
+
6
+ import { generateFileUploadPreview } from '../../../mock-builders/generator/attachment';
7
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
8
+ import {
9
+ InputMessageInputContextValue,
10
+ MessageInputContextValue,
11
+ MessageInputProvider,
12
+ useMessageInputContext,
13
+ } from '../MessageInputContext';
14
+
15
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
16
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
17
+
18
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
19
+ children,
20
+ ...rest
21
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
22
+ <MessageInputProvider
23
+ value={
24
+ {
25
+ ...rest,
26
+ } as MessageInputContextValue<StreamChatGenerics>
27
+ }
28
+ >
29
+ {children}
30
+ </MessageInputProvider>
31
+ );
32
+
33
+ describe("MessageInputContext's uploadFile", () => {
34
+ it('uploadFile works', () => {
35
+ const doDocUploadRequestMock = jest.fn().mockResolvedValue({
36
+ file: {
37
+ url: '',
38
+ },
39
+ thumb_url: '',
40
+ });
41
+ const { result } = renderHook(() => useMessageInputContext(), {
42
+ initialProps: {
43
+ doDocUploadRequest: doDocUploadRequestMock,
44
+ editing: true,
45
+ },
46
+ wrapper: Wrapper,
47
+ });
48
+
49
+ expect(result.current.fileUploads).toHaveLength(0);
50
+
51
+ act(() => {
52
+ result.current.uploadFile({ newFile: generateFileUploadPreview({ state: '' }) });
53
+ });
54
+
55
+ expect(doDocUploadRequestMock).toHaveBeenCalled();
56
+ });
57
+
58
+ it('uploadFile catch block gets executed', () => {
59
+ const doDocUploadRequestMock = jest.fn().mockResolvedValue(new Error('This is an error'));
60
+ const { result } = renderHook(() => useMessageInputContext(), {
61
+ initialProps: {
62
+ doDocUploadRequest: doDocUploadRequestMock,
63
+ editing: true,
64
+ },
65
+ wrapper: Wrapper,
66
+ });
67
+
68
+ expect(result.current.fileUploads).toHaveLength(0);
69
+
70
+ act(() => {
71
+ result.current.uploadFile({ newFile: generateFileUploadPreview({ state: '' }) });
72
+ });
73
+
74
+ expect(result.current.fileUploads.length).toBe(0);
75
+ });
76
+ });
@@ -0,0 +1,55 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { act } from 'react-test-renderer';
3
+
4
+ import { renderHook } from '@testing-library/react-hooks';
5
+
6
+ import { generateImageUploadPreview } from '../../../mock-builders/generator/attachment';
7
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
8
+ import {
9
+ InputMessageInputContextValue,
10
+ MessageInputContextValue,
11
+ MessageInputProvider,
12
+ useMessageInputContext,
13
+ } from '../MessageInputContext';
14
+
15
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
16
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
17
+
18
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
19
+ children,
20
+ ...rest
21
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
22
+ <MessageInputProvider
23
+ value={
24
+ {
25
+ ...rest,
26
+ } as MessageInputContextValue<StreamChatGenerics>
27
+ }
28
+ >
29
+ {children}
30
+ </MessageInputProvider>
31
+ );
32
+
33
+ describe("MessageInputContext's uploadImage", () => {
34
+ it('uploadImage works', async () => {
35
+ const doImageUploadRequestMock = jest
36
+ .fn()
37
+ .mockResolvedValue({ file: 'https://www.test.com/dummy.png' });
38
+
39
+ const initialProps = {
40
+ doImageUploadRequest: doImageUploadRequestMock,
41
+ editing: true,
42
+ };
43
+
44
+ const { result } = renderHook(() => useMessageInputContext(), {
45
+ initialProps,
46
+ wrapper: Wrapper,
47
+ });
48
+
49
+ await act(async () => {
50
+ await result.current.uploadImage({ newImage: generateImageUploadPreview() });
51
+ });
52
+
53
+ expect(doImageUploadRequestMock).toHaveBeenCalledTimes(1);
54
+ });
55
+ });
@@ -0,0 +1,62 @@
1
+ import { renderHook } from '@testing-library/react-hooks';
2
+ import type { MessageType } from 'src/components';
3
+ import type { DefaultStreamChatGenerics } from 'src/types/types';
4
+
5
+ import {
6
+ generateFileAttachment,
7
+ generateImageAttachment,
8
+ } from '../../../mock-builders/generator/attachment';
9
+ import { generateMessage } from '../../../mock-builders/generator/message';
10
+
11
+ import { generateUser } from '../../../mock-builders/generator/user';
12
+ import { useMessageDetailsForState } from '../hooks/useMessageDetailsForState';
13
+
14
+ describe('useMessageDetailsForState', () => {
15
+ it.each([[{ message: true }], [{ initialValue: '', message: true }]])(
16
+ 'test state of useMessageDetailsForState when initialProps differ',
17
+ () => {
18
+ const { result } = renderHook(({ message }) => useMessageDetailsForState(message), {
19
+ initialProps: { message: true },
20
+ });
21
+
22
+ expect(result.current.text).toBe('');
23
+ },
24
+ );
25
+
26
+ it('showMoreOptions is true when initialValue and text is same', () => {
27
+ const { result } = renderHook(
28
+ ({ initialValue, message }) => useMessageDetailsForState(message, initialValue),
29
+ { initialProps: { initialValue: 'Dummy text', message: true } },
30
+ );
31
+
32
+ expect(result.current.showMoreOptions).toBe(true);
33
+ });
34
+
35
+ it('fileUploads, imageUploads and mentionedUsers are not empty when attachments are present in message', () => {
36
+ const { result } = renderHook(
37
+ ({ initialValue, message }) =>
38
+ useMessageDetailsForState(
39
+ message as unknown as MessageType<DefaultStreamChatGenerics> | boolean,
40
+ initialValue,
41
+ ),
42
+ {
43
+ initialProps: {
44
+ initialValue: '',
45
+ message: generateMessage({
46
+ attachments: [
47
+ generateFileAttachment(),
48
+ generateImageAttachment(),
49
+ generateFileAttachment({ type: 'video' }),
50
+ generateFileAttachment({ type: 'audio' }),
51
+ ],
52
+ mentioned_users: [generateUser()],
53
+ }),
54
+ },
55
+ },
56
+ );
57
+
58
+ expect(result.current.fileUploads.length).toBeGreaterThan(0);
59
+ expect(result.current.imageUploads.length).toBeGreaterThan(0);
60
+ expect(result.current.mentionedUsers.length).toBeGreaterThan(0);
61
+ });
62
+ });