stream-chat-react-native-core 4.9.0-beta.2 → 4.9.0

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 (98) hide show
  1. package/lib/commonjs/components/Attachment/Gallery.js +246 -190
  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/components/MessageInput/FileUploadPreview.js +24 -18
  10. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  11. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +2 -2
  12. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
  13. package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js +43 -0
  14. package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
  15. package/lib/commonjs/components/Reply/Reply.js +7 -2
  16. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  17. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +20 -27
  18. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  19. package/lib/commonjs/mock-builders/generator/attachment.js +3 -2
  20. package/lib/commonjs/mock-builders/generator/attachment.js.map +1 -1
  21. package/lib/commonjs/utils/getUrlOfImageAttachment.js +1 -1
  22. package/lib/commonjs/utils/getUrlOfImageAttachment.js.map +1 -1
  23. package/lib/commonjs/version.json +1 -1
  24. package/lib/module/components/Attachment/Gallery.js +246 -190
  25. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  26. package/lib/module/components/Attachment/VideoThumbnail.js +11 -5
  27. package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
  28. package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js +1 -0
  29. package/lib/module/components/Attachment/utils/buildGallery/buildThumbnail.js.map +1 -1
  30. package/lib/module/components/Message/Message.js +7 -6
  31. package/lib/module/components/Message/Message.js.map +1 -1
  32. package/lib/module/components/MessageInput/FileUploadPreview.js +24 -18
  33. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  34. package/lib/module/components/MessageInput/ImageUploadPreview.js +2 -2
  35. package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
  36. package/lib/module/components/RTLComponents/WritingDirectionAwareText.js +43 -0
  37. package/lib/module/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
  38. package/lib/module/components/Reply/Reply.js +7 -2
  39. package/lib/module/components/Reply/Reply.js.map +1 -1
  40. package/lib/module/contexts/messageInputContext/MessageInputContext.js +20 -27
  41. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  42. package/lib/module/mock-builders/generator/attachment.js +3 -2
  43. package/lib/module/mock-builders/generator/attachment.js.map +1 -1
  44. package/lib/module/utils/getUrlOfImageAttachment.js +1 -1
  45. package/lib/module/utils/getUrlOfImageAttachment.js.map +1 -1
  46. package/lib/module/version.json +1 -1
  47. package/lib/typescript/components/Attachment/VideoThumbnail.d.ts +3 -1
  48. package/lib/typescript/components/Attachment/utils/buildGallery/types.d.ts +1 -0
  49. package/lib/typescript/components/RTLComponents/WritingDirectionAwareText.d.ts +4 -0
  50. package/lib/typescript/components/Reply/__tests__/Reply.test.d.ts +1 -0
  51. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -0
  52. package/lib/typescript/contexts/messageInputContext/__tests__/MessageInputContext.test.d.ts +1 -0
  53. package/lib/typescript/contexts/messageInputContext/__tests__/isValidMessage.test.d.ts +1 -0
  54. package/lib/typescript/contexts/messageInputContext/__tests__/pickFile.test.d.ts +1 -0
  55. package/lib/typescript/contexts/messageInputContext/__tests__/removeFile.test.d.ts +1 -0
  56. package/lib/typescript/contexts/messageInputContext/__tests__/removeImage.test.d.ts +1 -0
  57. package/lib/typescript/contexts/messageInputContext/__tests__/sendMessage.test.d.ts +1 -0
  58. package/lib/typescript/contexts/messageInputContext/__tests__/sendMessageAsync.test.d.ts +1 -0
  59. package/lib/typescript/contexts/messageInputContext/__tests__/updateMessage.test.d.ts +1 -0
  60. package/lib/typescript/contexts/messageInputContext/__tests__/uploadFile.test.d.ts +1 -0
  61. package/lib/typescript/contexts/messageInputContext/__tests__/uploadImage.test.d.ts +1 -0
  62. package/lib/typescript/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.d.ts +1 -0
  63. package/lib/typescript/mock-builders/api/getOrCreateChannel.d.ts +7 -0
  64. package/lib/typescript/mock-builders/api/useMockedApis.d.ts +1 -0
  65. package/lib/typescript/mock-builders/generator/attachment.d.ts +10 -0
  66. package/lib/typescript/mock-builders/generator/channel.d.ts +116 -0
  67. package/lib/typescript/mock-builders/generator/message.d.ts +38 -0
  68. package/lib/typescript/mock-builders/generator/user.d.ts +9 -9
  69. package/package.json +7 -5
  70. package/src/components/Attachment/Gallery.tsx +231 -140
  71. package/src/components/Attachment/VideoThumbnail.tsx +12 -5
  72. package/src/components/Attachment/__tests__/Attachment.test.js +12 -0
  73. package/src/components/Attachment/__tests__/Gallery.test.js +23 -1
  74. package/src/components/Attachment/utils/buildGallery/buildThumbnail.ts +1 -0
  75. package/src/components/Attachment/utils/buildGallery/types.ts +1 -0
  76. package/src/components/Message/Message.tsx +5 -1
  77. package/src/components/MessageInput/FileUploadPreview.tsx +7 -5
  78. package/src/components/MessageInput/ImageUploadPreview.tsx +2 -2
  79. package/src/components/RTLComponents/WritingDirectionAwareText.tsx +17 -0
  80. package/src/components/Reply/Reply.tsx +19 -3
  81. package/src/components/Reply/__tests__/Reply.test.tsx +48 -0
  82. package/src/contexts/messageInputContext/MessageInputContext.tsx +3 -4
  83. package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +208 -0
  84. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +109 -0
  85. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessageAsync.test.tsx.snap +33 -0
  86. package/src/contexts/messageInputContext/__tests__/isValidMessage.test.tsx +71 -0
  87. package/src/contexts/messageInputContext/__tests__/pickFile.test.tsx +67 -0
  88. package/src/contexts/messageInputContext/__tests__/removeFile.test.tsx +82 -0
  89. package/src/contexts/messageInputContext/__tests__/removeImage.test.tsx +80 -0
  90. package/src/contexts/messageInputContext/__tests__/sendMessage.test.tsx +286 -0
  91. package/src/contexts/messageInputContext/__tests__/sendMessageAsync.test.tsx +124 -0
  92. package/src/contexts/messageInputContext/__tests__/updateMessage.test.tsx +92 -0
  93. package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +76 -0
  94. package/src/contexts/messageInputContext/__tests__/uploadImage.test.tsx +55 -0
  95. package/src/contexts/messageInputContext/__tests__/useMessageDetailsForState.test.tsx +62 -0
  96. package/src/mock-builders/generator/attachment.js +4 -2
  97. package/src/utils/getUrlOfImageAttachment.ts +1 -1
  98. package/src/version.json +1 -1
@@ -0,0 +1,33 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`MessageInputContext's sendMessageAsync sendImageAsync is been called with finished file upload state and checked for snapshot) 1`] = `
4
+ Object {
5
+ "attachments": Array [
6
+ Object {
7
+ "image_url": "https://www.test.com",
8
+ "type": "image",
9
+ },
10
+ ],
11
+ "mentioned_users": Array [],
12
+ "parent_id": undefined,
13
+ "quoted_message_id": undefined,
14
+ "show_in_channel": undefined,
15
+ "text": "",
16
+ }
17
+ `;
18
+
19
+ exports[`MessageInputContext's sendMessageAsync sendImageAsync is been called with uploaded file upload state and checked for snapshot) 1`] = `
20
+ Object {
21
+ "attachments": Array [
22
+ Object {
23
+ "image_url": "https://www.test.com",
24
+ "type": "image",
25
+ },
26
+ ],
27
+ "mentioned_users": Array [],
28
+ "parent_id": undefined,
29
+ "quoted_message_id": undefined,
30
+ "show_in_channel": undefined,
31
+ "text": "",
32
+ }
33
+ `;
@@ -0,0 +1,71 @@
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 {
7
+ generateFileUploadPreview,
8
+ generateImageUploadPreview,
9
+ } from '../../../mock-builders/generator/attachment';
10
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
11
+ import { FileState } from '../../../utils/utils';
12
+ import {
13
+ InputMessageInputContextValue,
14
+ MessageInputContextValue,
15
+ MessageInputProvider,
16
+ useMessageInputContext,
17
+ } from '../MessageInputContext';
18
+
19
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
20
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
21
+
22
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
23
+ children,
24
+ ...rest
25
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
26
+ <MessageInputProvider
27
+ value={
28
+ {
29
+ ...rest,
30
+ } as MessageInputContextValue<StreamChatGenerics>
31
+ }
32
+ >
33
+ {children}
34
+ </MessageInputProvider>
35
+ );
36
+
37
+ describe("MessageInputContext's isValidMessage", () => {
38
+ const initialProps = {
39
+ editing: true,
40
+ hasImagePicker: true,
41
+ };
42
+
43
+ it.each([
44
+ [[], [], [], 0, '', false],
45
+ [[], [], [], 0, 'Dummy Text', true],
46
+ [[generateFileUploadPreview()], [], [], 0, '', true],
47
+ [[], [generateImageUploadPreview()], [], 0, '', true],
48
+ [[], [generateImageUploadPreview({ state: FileState.UPLOAD_FAILED })], [], 0, '', false],
49
+ [[generateFileUploadPreview({ state: FileState.UPLOAD_FAILED })], [], [], 0, '', false],
50
+ [[generateFileUploadPreview({ state: FileState.UPLOADING })], [], [], 0, '', false],
51
+ [[], [generateImageUploadPreview({ state: FileState.UPLOADING })], [], 0, '', false],
52
+ ])(
53
+ 'isValidMessage with fileUploads %p, imageUploads %p, mentionedUsers %p, numberOfUploads %d, text %s gives %p',
54
+ (fileUploads, imageUploads, mentionedUsers, numberOfUploads, text, isValidMessageStatus) => {
55
+ const { result } = renderHook(() => useMessageInputContext(), {
56
+ initialProps,
57
+ wrapper: Wrapper,
58
+ });
59
+
60
+ act(() => {
61
+ result.current.setFileUploads(fileUploads);
62
+ result.current.setImageUploads(imageUploads);
63
+ result.current.setMentionedUsers(mentionedUsers);
64
+ result.current.setNumberOfUploads(numberOfUploads);
65
+ result.current.setText(text);
66
+ });
67
+
68
+ expect(result.current.isValidMessage()).toBe(isValidMessageStatus);
69
+ },
70
+ );
71
+ });
@@ -0,0 +1,67 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ import { Alert } from 'react-native';
3
+ import { act } from 'react-test-renderer';
4
+
5
+ import { renderHook } from '@testing-library/react-hooks';
6
+
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
+ afterEach(jest.clearAllMocks);
34
+
35
+ describe("MessageInputContext's pickFile", () => {
36
+ jest.spyOn(Alert, 'alert');
37
+
38
+ const initialProps = {
39
+ editing: true,
40
+ maxNumberOfFiles: 2,
41
+ };
42
+
43
+ it.each([
44
+ [3, 1],
45
+ [1, 0],
46
+ ])(
47
+ 'run pickFile when numberOfUploads is %d and alert is triggered %d number of times',
48
+ (numberOfUploads, numberOfTimesCalled) => {
49
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
50
+ initialProps,
51
+ wrapper: Wrapper,
52
+ });
53
+
54
+ act(() => {
55
+ result.current.setNumberOfUploads(numberOfUploads);
56
+ });
57
+
58
+ rerender({ editing: false, maxNumberOfFiles: 2 });
59
+
60
+ act(() => {
61
+ result.current.pickFile();
62
+ });
63
+
64
+ expect(Alert.alert).toHaveBeenCalledTimes(numberOfTimesCalled);
65
+ },
66
+ );
67
+ });
@@ -0,0 +1,82 @@
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 { waitFor } from '@testing-library/react-native';
7
+
8
+ import { generateFileUploadPreview } from '../../../mock-builders/generator/attachment';
9
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
10
+ import {
11
+ InputMessageInputContextValue,
12
+ MessageInputContextValue,
13
+ MessageInputProvider,
14
+ useMessageInputContext,
15
+ } from '../MessageInputContext';
16
+
17
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
18
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
19
+
20
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
21
+ children,
22
+ ...rest
23
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
24
+ <MessageInputProvider
25
+ value={
26
+ {
27
+ ...rest,
28
+ } as MessageInputContextValue<StreamChatGenerics>
29
+ }
30
+ >
31
+ {children}
32
+ </MessageInputProvider>
33
+ );
34
+
35
+ describe("MessageInputContext's removeFile", () => {
36
+ const initialProps = {
37
+ editing: true,
38
+ };
39
+
40
+ const file = generateFileUploadPreview({
41
+ file: {
42
+ id: 'test',
43
+ name: 'Test Image',
44
+ uri: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg',
45
+ },
46
+ });
47
+
48
+ it.each([
49
+ [file.id, 0, 0],
50
+ ['dummy', 1, 1],
51
+ ])(
52
+ 'removeFile is been called with %s and checked for expectedFileUploadsLength %i, and expectedNumberOfUploadsLength %i)',
53
+ async (fileId, expectedFileUploadsLength, expectedNumberOfUploadsLength) => {
54
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
55
+ initialProps,
56
+ wrapper: Wrapper,
57
+ });
58
+
59
+ act(() => {
60
+ result.current.setFileUploads([file]);
61
+ result.current.setNumberOfUploads(1);
62
+ });
63
+
64
+ rerender({ editing: false });
65
+
66
+ await waitFor(() => {
67
+ expect(result.current.fileUploads.length).toBe(1);
68
+ });
69
+
70
+ act(() => {
71
+ result.current.removeFile(fileId);
72
+ });
73
+
74
+ rerender({ editing: true });
75
+
76
+ await waitFor(() => {
77
+ expect(result.current.fileUploads.length).toBe(expectedFileUploadsLength);
78
+ expect(result.current.numberOfUploads).toBe(expectedNumberOfUploadsLength);
79
+ });
80
+ },
81
+ );
82
+ });
@@ -0,0 +1,80 @@
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 { waitFor } from '@testing-library/react-native';
7
+
8
+ import { generateImageUploadPreview } from '../../../mock-builders/generator/attachment';
9
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
10
+ import {
11
+ InputMessageInputContextValue,
12
+ MessageInputContextValue,
13
+ MessageInputProvider,
14
+ useMessageInputContext,
15
+ } from '../MessageInputContext';
16
+
17
+ type WrapperType<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
18
+ Partial<InputMessageInputContextValue<StreamChatGenerics>>;
19
+
20
+ const Wrapper = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({
21
+ children,
22
+ ...rest
23
+ }: PropsWithChildren<WrapperType<StreamChatGenerics>>) => (
24
+ <MessageInputProvider
25
+ value={
26
+ {
27
+ ...rest,
28
+ } as MessageInputContextValue<StreamChatGenerics>
29
+ }
30
+ >
31
+ {children}
32
+ </MessageInputProvider>
33
+ );
34
+
35
+ describe("MessageInputContext's removeImage", () => {
36
+ const initialProps = {
37
+ editing: true,
38
+ };
39
+ const image = generateImageUploadPreview({
40
+ file: {
41
+ id: 'test',
42
+ name: 'Test Image',
43
+ uri: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg',
44
+ },
45
+ });
46
+ it.each([
47
+ [image.id, 0, 0],
48
+ ['dummy', 1, 1],
49
+ ])(
50
+ 'removeImage is been called with %s and checked for expectedImageUploadsLength %i, and expectedNumberOfUploadsLength %i)',
51
+ async (imageId, expectedImageUploadsLength, expectedNumberOfUploadsLength) => {
52
+ const { rerender, result } = renderHook(() => useMessageInputContext(), {
53
+ initialProps,
54
+ wrapper: Wrapper,
55
+ });
56
+
57
+ act(() => {
58
+ result.current.setImageUploads([image]);
59
+ result.current.setNumberOfUploads(1);
60
+ });
61
+
62
+ rerender({ editing: false });
63
+
64
+ await waitFor(() => {
65
+ expect(result.current.imageUploads.length).toBe(1);
66
+ });
67
+
68
+ act(() => {
69
+ result.current.removeImage(imageId);
70
+ });
71
+
72
+ rerender({ editing: true });
73
+
74
+ await waitFor(() => {
75
+ expect(result.current.imageUploads.length).toBe(expectedImageUploadsLength);
76
+ expect(result.current.numberOfUploads).toBe(expectedNumberOfUploadsLength);
77
+ });
78
+ },
79
+ );
80
+ });
@@ -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
+ });