@@ -12,58 +12,62 @@ import '@testing-library/jest-dom';
12
12
/* @conditional -compile-remove(rich-text-editor-composite-support) */
13
13
import { COMPOSITE_LOCALE_ZH_TW } from '../localization/locales/zh-TW/CompositeLocale' ;
14
14
/* @conditional -compile-remove(rich-text-editor-composite-support) */
15
- import { ChatComposite } from './ChatComposite' ;
15
+ import { ChatComposite , ChatCompositeProps } from './ChatComposite' ;
16
16
/* @conditional -compile-remove(rich-text-editor-composite-support) */
17
17
import React from 'react' ;
18
-
19
18
/* @conditional -compile-remove(rich-text-editor-composite-support) */
20
- function createMockChatAdapter ( ) : ChatAdapter {
21
- const chatAdapter = { } as ChatAdapter ;
22
- chatAdapter . onStateChange = jest . fn ( ) ;
23
- chatAdapter . offStateChange = jest . fn ( ) ;
24
- chatAdapter . fetchInitialData = jest . fn ( ) ;
25
- chatAdapter . loadPreviousChatMessages = jest . fn ( ) ;
26
- chatAdapter . getState = jest . fn (
27
- ( ) : ChatAdapterState => ( {
28
- userId : { kind : 'communicationUser' , communicationUserId : 'test' } ,
29
- displayName : 'test' ,
30
- thread : {
31
- chatMessages : { } ,
32
- participants : { } ,
33
- threadId : 'test' ,
34
- readReceipts : [ ] ,
35
- typingIndicators : [ ] ,
36
- latestReadTime : new Date ( )
37
- } ,
38
- latestErrors : { } ,
39
- error : undefined
40
- } )
41
- ) ;
42
- return chatAdapter ;
43
- }
19
+ import { RichTextSendBoxProps } from '@internal/react-components' ;
20
+ /* @conditional -compile-remove(rich-text-editor-composite-support) */
21
+ import { RichTextSendBoxWrapper } from '../common/RichTextSendBoxWrapper' ;
22
+ /* @conditional -compile-remove(rich-text-editor-composite-support) */
23
+ import { removeImageTags } from './ImageUpload/ImageUploadUtils' ;
44
24
45
25
// Mock the richTextSendBoxWrapper component as it's lazy loaded in ChatComposite
46
26
/* @conditional -compile-remove(rich-text-editor-composite-support) */
47
- function MockedRichTextSendBoxWrapper ( ) : JSX . Element {
48
- return < div id = "richTextSendBoxWrapper "> Mocked RichTextSendboxWrapper</ div > ;
27
+ function MockedRichTextSendBoxWrapperComponent ( ) : JSX . Element {
28
+ return < div data-testid = "rich-text-editor-test "> Mocked RichTextSendboxWrapper</ div > ;
49
29
}
50
-
51
30
/* @conditional -compile-remove(rich-text-editor-composite-support) */
52
- jest . mock ( '../common/RichTextSendBoxWrapper' , ( ) => {
53
- return {
54
- RichTextSendBoxWrapper : MockedRichTextSendBoxWrapper
55
- } ;
56
- } ) ;
31
+ jest . mock ( '../common/RichTextSendBoxWrapper' ) ;
32
+ /* @conditional -compile-remove(rich-text-editor-composite-support) */
33
+ const mockedRichTextSendBoxWrapper = jest . mocked ( RichTextSendBoxWrapper ) ;
57
34
58
35
/* @conditional -compile-remove(rich-text-editor-composite-support) */
59
36
describe ( 'ChatComposite' , ( ) => {
37
+ const createMockChatAdapter = ( ) : ChatAdapter => {
38
+ const chatAdapter = { } as ChatAdapter ;
39
+ chatAdapter . onStateChange = jest . fn ( ) ;
40
+ chatAdapter . offStateChange = jest . fn ( ) ;
41
+ chatAdapter . fetchInitialData = jest . fn ( ) ;
42
+ chatAdapter . loadPreviousChatMessages = jest . fn ( ) ;
43
+ chatAdapter . getState = jest . fn (
44
+ ( ) : ChatAdapterState => ( {
45
+ userId : { kind : 'communicationUser' , communicationUserId : 'test' } ,
46
+ displayName : 'test' ,
47
+ thread : {
48
+ chatMessages : { } ,
49
+ participants : { } ,
50
+ threadId : 'test' ,
51
+ readReceipts : [ ] ,
52
+ typingIndicators : [ ] ,
53
+ latestReadTime : new Date ( )
54
+ } ,
55
+ latestErrors : { }
56
+ } )
57
+ ) ;
58
+ return chatAdapter ;
59
+ } ;
60
+
60
61
beforeEach ( ( ) => {
62
+ jest . restoreAllMocks ( ) ;
61
63
// Register icons used in ChatComposite to avoid warnings
62
64
registerIcons ( {
63
65
icons : {
64
66
chevrondown : < > </ >
65
67
}
66
68
} ) ;
69
+
70
+ mockedRichTextSendBoxWrapper . mockImplementation ( MockedRichTextSendBoxWrapperComponent ) ;
67
71
} ) ;
68
72
69
73
test ( 'Chat Composite should show RichTextSendBoxWrapper if it is enabled' , async ( ) => {
@@ -81,7 +85,8 @@ describe('ChatComposite', () => {
81
85
const mockChatAdapter = createMockChatAdapter ( ) ;
82
86
83
87
render ( < ChatComposite adapter = { mockChatAdapter } { ...mockBaseCompositeProps } /> ) ;
84
- expect ( await screen . findByText ( / M o c k e d R i c h T e x t S e n d b o x W r a p p e r / ) ) . toBeVisible ( ) ;
88
+ const mockSendBox = await screen . findByTestId ( 'rich-text-editor-test' ) ;
89
+ expect ( mockSendBox ) . toBeVisible ( ) ;
85
90
} ) ;
86
91
87
92
test ( 'Chat Composite should not show RichTextSendBoxWrapper if it is not enabled' , async ( ) => {
@@ -99,7 +104,129 @@ describe('ChatComposite', () => {
99
104
const mockChatAdapter = createMockChatAdapter ( ) ;
100
105
101
106
render ( < ChatComposite adapter = { mockChatAdapter } { ...mockBaseCompositeProps } /> ) ;
102
- expect ( screen . findByText ( / M o c k e d R i c h T e x t S e n d b o x W r a p p e r / ) ) . rejects . toThrow ( ) ;
107
+ expect ( screen . queryByTestId ( 'rich-text-editor-test' ) ) . toBeNull ( ) ;
108
+ } ) ;
109
+ } ) ;
110
+
111
+ /* @conditional -compile-remove(rich-text-editor-composite-support) */
112
+ describe ( 'ChatComposite - text only mode' , ( ) => {
113
+ const createMockChatAdapter = ( textOnlyChat : boolean ) : ChatAdapter => {
114
+ const chatAdapter = { } as ChatAdapter ;
115
+ chatAdapter . onStateChange = jest . fn ( ) ;
116
+ chatAdapter . offStateChange = jest . fn ( ) ;
117
+ chatAdapter . fetchInitialData = jest . fn ( ) ;
118
+ chatAdapter . loadPreviousChatMessages = jest . fn ( ) ;
119
+ chatAdapter . getState = jest . fn (
120
+ ( ) : ChatAdapterState => ( {
121
+ //Text only mode is available for Teams meetings only
122
+ userId : { kind : 'microsoftTeamsUser' , microsoftTeamsUserId : 'test' } ,
123
+ displayName : 'test' ,
124
+ thread : {
125
+ chatMessages : { } ,
126
+ participants : { } ,
127
+ threadId : 'test' ,
128
+ readReceipts : [ ] ,
129
+ typingIndicators : [ ] ,
130
+ latestReadTime : new Date ( ) ,
131
+ properties : {
132
+ messagingPolicy : { textOnlyChat : textOnlyChat } ,
133
+ createdBy : { kind : 'microsoftTeamsUser' , microsoftTeamsUserId : 'test' }
134
+ }
135
+ } ,
136
+ latestErrors : { }
137
+ } )
138
+ ) ;
139
+ return chatAdapter ;
140
+ } ;
141
+
142
+ const mockBaseCompositeProps = ( adapter : ChatAdapter , richTextEditor : boolean ) : ChatCompositeProps => {
143
+ return {
144
+ adapter : adapter ,
145
+ fluentTheme : { } ,
146
+ icons : { } ,
147
+ locale : COMPOSITE_LOCALE_ZH_TW ,
148
+ rtl : true ,
149
+ onFetchAvatarPersonaData : jest . fn ( ) ,
150
+ options : {
151
+ richTextEditor : richTextEditor ,
152
+ attachmentOptions : {
153
+ uploadOptions : {
154
+ handleAttachmentSelection : ( ) => { }
155
+ }
156
+ }
157
+ }
158
+ } ;
159
+ } ;
160
+
161
+ beforeEach ( ( ) => {
162
+ jest . restoreAllMocks ( ) ;
163
+ // Register icons used in ChatComposite to avoid warnings
164
+ registerIcons ( {
165
+ icons : {
166
+ chevrondown : < > </ >
167
+ }
168
+ } ) ;
169
+ mockedRichTextSendBoxWrapper . mockImplementation ( MockedRichTextSendBoxWrapperComponent ) ;
170
+ } ) ;
171
+
172
+ test ( 'Chat Composite should set onPaste callback when text only mode is on' , async ( ) => {
173
+ let onPaste : ( ( event : { content : DocumentFragment } ) => void ) | undefined = undefined ;
174
+ expect . assertions ( 2 ) ;
175
+ function Wrapper ( props : RichTextSendBoxProps ) : JSX . Element {
176
+ onPaste = props . onPaste ;
177
+ return < MockedRichTextSendBoxWrapperComponent /> ;
178
+ }
179
+ mockedRichTextSendBoxWrapper . mockImplementation ( Wrapper ) ;
180
+ const mockChatAdapter = createMockChatAdapter ( true ) ;
181
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , true ) } /> ) ;
182
+ await screen . findByTestId ( 'rich-text-editor-test' ) ;
183
+ expect ( onPaste ) . toBeDefined ( ) ;
184
+ if ( onPaste !== undefined ) {
185
+ const onPasteFunction = onPaste as ( event : { content : DocumentFragment } ) => void ;
186
+ expect ( onPasteFunction ) . toBe ( removeImageTags ) ;
187
+ } else {
188
+ fail ( 'onPaste is undefined' ) ;
189
+ }
190
+ } ) ;
191
+
192
+ test ( 'Chat Composite with rich text send box should not show attachments button when text only mode is on' , async ( ) => {
193
+ const mockChatAdapter = createMockChatAdapter ( true ) ;
194
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , true ) } /> ) ;
195
+ expect ( screen . queryByTestId ( 'attachment-upload-button' ) ) . toBeNull ( ) ;
196
+ } ) ;
197
+
198
+ test ( 'Chat Composite with plain text send box should not show attachments button when text only mode is on' , async ( ) => {
199
+ const mockChatAdapter = createMockChatAdapter ( true ) ;
200
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , false ) } /> ) ;
201
+ expect ( screen . queryByTestId ( 'attachment-upload-button' ) ) . toBeNull ( ) ;
202
+ } ) ;
203
+
204
+ test ( 'Chat Composite should set onPaste callback to undefined when text only mode is off' , async ( ) => {
205
+ let onPaste : ( ( event : { content : DocumentFragment } ) => void ) | undefined = undefined ;
206
+ expect . assertions ( 1 ) ;
207
+ function Wrapper ( props : RichTextSendBoxProps ) : JSX . Element {
208
+ onPaste = props . onPaste ;
209
+ return < MockedRichTextSendBoxWrapperComponent /> ;
210
+ }
211
+ mockedRichTextSendBoxWrapper . mockImplementation ( Wrapper ) ;
212
+ const mockChatAdapter = createMockChatAdapter ( false ) ;
213
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , true ) } /> ) ;
214
+ await screen . findByTestId ( 'rich-text-editor-test' ) ;
215
+ expect ( onPaste ) . toBeUndefined ( ) ;
216
+ } ) ;
217
+
218
+ test ( 'Chat Composite with rich text send box should show attachments button when text only mode is off' , async ( ) => {
219
+ const mockChatAdapter = createMockChatAdapter ( false ) ;
220
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , true ) } /> ) ;
221
+ const attachmentsButton = await screen . findByTestId ( 'attachment-upload-button' ) ;
222
+ expect ( attachmentsButton ) . toBeDefined ( ) ;
223
+ } ) ;
224
+
225
+ test ( 'Chat Composite with plain text send box should show attachments button when text only mode is off' , async ( ) => {
226
+ const mockChatAdapter = createMockChatAdapter ( false ) ;
227
+ render ( < ChatComposite { ...mockBaseCompositeProps ( mockChatAdapter , false ) } /> ) ;
228
+ const attachmentsButton = await screen . findByTestId ( 'attachment-upload-button' ) ;
229
+ expect ( attachmentsButton ) . toBeDefined ( ) ;
103
230
} ) ;
104
231
} ) ;
105
232
0 commit comments