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.
- package/lib/commonjs/components/Attachment/Gallery.js +11 -9
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/Attachment/VideoThumbnail.js +11 -5
- package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
- package/lib/commonjs/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +7 -6
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +20 -27
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/mock-builders/generator/attachment.js +3 -2
- package/lib/commonjs/mock-builders/generator/attachment.js.map +1 -1
- package/lib/commonjs/utils/getUrlOfImageAttachment.js +1 -1
- package/lib/commonjs/utils/getUrlOfImageAttachment.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Attachment/Gallery.js +11 -9
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/Attachment/VideoThumbnail.js +11 -5
- package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
- package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
- package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
- package/lib/module/components/Message/Message.js +7 -6
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +20 -27
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/mock-builders/generator/attachment.js +3 -2
- package/lib/module/mock-builders/generator/attachment.js.map +1 -1
- package/lib/module/utils/getUrlOfImageAttachment.js +1 -1
- package/lib/module/utils/getUrlOfImageAttachment.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Attachment/VideoThumbnail.d.ts +3 -1
- package/lib/typescript/components/Attachment/utils/buildGallery/types.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/MessageInputContext.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/isValidMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/pickFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/removeFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/removeImage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/sendMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/sendMessageAsync.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/updateMessage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/uploadFile.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/uploadImage.test.d.ts +1 -0
- package/lib/typescript/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.d.ts +1 -0
- package/lib/typescript/mock-builders/generator/attachment.d.ts +10 -0
- package/lib/typescript/mock-builders/generator/channel.d.ts +13 -13
- package/lib/typescript/mock-builders/generator/message.d.ts +38 -0
- package/lib/typescript/mock-builders/generator/user.d.ts +9 -9
- package/package.json +5 -4
- package/src/components/Attachment/Gallery.tsx +2 -1
- package/src/components/Attachment/VideoThumbnail.tsx +12 -5
- package/src/components/Attachment/__tests__/Attachment.test.js +12 -0
- package/src/components/Attachment/__tests__/Gallery.test.js +23 -1
- package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts +1 -0
- package/src/components/Attachment/utils/buildGallery/types.ts +1 -0
- package/src/components/Message/Message.tsx +5 -1
- package/src/contexts/messageInputContext/MessageInputContext.tsx +3 -4
- package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +208 -0
- package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +109 -0
- package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessageAsync.test.tsx.snap +33 -0
- package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx +71 -0
- package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +67 -0
- package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx +82 -0
- package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx +80 -0
- package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +286 -0
- package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx +124 -0
- package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +92 -0
- package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +76 -0
- package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx +55 -0
- package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +62 -0
- package/src/mock-builders/generator/attachment.js +4 -2
- package/src/utils/getUrlOfImageAttachment.ts +1 -1
- 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
|
+
});
|