@@ -29,28 +29,27 @@ const documentSuggestionListMock = {
29
29
} ) ,
30
30
} ;
31
31
32
- // @ts -ignore
33
- global . CoveoHeadlessCaseAssist = {
32
+ const functionsMocks = {
33
+ fetchDocumentSuggestions : jest . fn ( ) ,
34
+ logDocumentSuggestionClick : jest . fn ( ) ,
35
+ logDocumentSuggestionRating : jest . fn ( ) ,
36
+ } ;
37
+
38
+ const headlessCaseAssistMock = {
34
39
buildDocumentSuggestionList : jest
35
40
. fn ( )
36
41
. mockReturnValue ( documentSuggestionListMock ) ,
37
42
loadCaseAssistAnalyticsActions : jest . fn ( ) . mockReturnValue ( { } ) ,
38
43
loadDocumentSuggestionActions : jest . fn ( ) . mockReturnValue ( {
39
- fetchDocumentSuggestions : jest
40
- . fn ( )
41
- . mockReturnValue ( 'mockedFetchDocumentSuggestions' ) ,
42
- logDocumentSuggestionClick : jest . fn ( ( id ) => [
43
- 'mockedLogDocumentSuggestionClick' ,
44
- id ,
45
- ] ) ,
46
- logDocumentSuggestionRating : jest . fn ( ( id , score ) => [
47
- 'mockedLogDocumentSuggestionRating' ,
48
- id ,
49
- score ,
50
- ] ) ,
44
+ fetchDocumentSuggestions : functionsMocks . fetchDocumentSuggestions ,
45
+ logDocumentSuggestionClick : functionsMocks . logDocumentSuggestionClick ,
46
+ logDocumentSuggestionRating : functionsMocks . logDocumentSuggestionRating ,
51
47
} ) ,
52
48
} ;
53
49
50
+ // @ts -ignore
51
+ global . CoveoHeadlessCaseAssist = headlessCaseAssistMock ;
52
+
54
53
const createTestComponent = buildCreateTestComponent (
55
54
QuanticDocumentSuggestion ,
56
55
'c-quantic-document-suggestion' ,
@@ -69,6 +68,16 @@ const selectors = {
69
68
componentError : 'c-quantic-component-error' ,
70
69
} ;
71
70
71
+ function mockErroneousHeadlessInitialization ( ) {
72
+ headlessLoaderMock . initializeWithHeadless . mockImplementation (
73
+ async ( element ) => {
74
+ if ( element instanceof QuanticDocumentSuggestion ) {
75
+ element . setInitializationError ( ) ;
76
+ }
77
+ }
78
+ ) ;
79
+ }
80
+
72
81
function checkElement ( element , selector , shouldExist ) {
73
82
if ( shouldExist ) {
74
83
expect ( element . shadowRoot . querySelector ( selector ) ) . toBeTruthy ( ) ;
@@ -89,6 +98,30 @@ describe('c-quantic-document-suggestion', () => {
89
98
cleanup ( ) ;
90
99
} ) ;
91
100
101
+ describe ( 'on initialization' , ( ) => {
102
+ it ( 'should initialize the component and subscribe to the controller' , async ( ) => {
103
+ createTestComponent ( ) ;
104
+
105
+ expect ( headlessLoaderMock . registerComponentForInit ) . toHaveBeenCalled ( ) ;
106
+ expect ( headlessLoaderMock . initializeWithHeadless ) . toHaveBeenCalled ( ) ;
107
+ expect (
108
+ headlessCaseAssistMock . buildDocumentSuggestionList
109
+ ) . toHaveBeenCalledTimes ( 1 ) ;
110
+ expect (
111
+ headlessCaseAssistMock . buildDocumentSuggestionList
112
+ ) . toHaveBeenCalledWith ( engineMock ) ;
113
+ expect (
114
+ headlessCaseAssistMock . loadCaseAssistAnalyticsActions
115
+ ) . toHaveBeenCalledTimes ( 1 ) ;
116
+ expect (
117
+ headlessCaseAssistMock . loadDocumentSuggestionActions
118
+ ) . toHaveBeenCalledTimes ( 1 ) ;
119
+ expect ( engineMock . dispatch ) . not . toHaveBeenCalled ( ) ;
120
+ expect ( documentSuggestionListMock . subscribe ) . toHaveBeenCalledTimes ( 1 ) ;
121
+ expect ( updateSuggestions ) . toBeDefined ( ) ;
122
+ } ) ;
123
+ } ) ;
124
+
92
125
describe ( 'when loading suggestions' , ( ) => {
93
126
it ( 'should render the loading holder only' , async ( ) => {
94
127
const element = createTestComponent ( ) ;
@@ -107,8 +140,6 @@ describe('c-quantic-document-suggestion', () => {
107
140
const element = createTestComponent ( ) ;
108
141
await updateSuggestions ( ) ;
109
142
110
- expect ( engineMock . dispatch ) . not . toHaveBeenCalled ( ) ;
111
- expect ( headlessLoaderMock . registerComponentForInit ) . toHaveBeenCalled ( ) ;
112
143
checkElement ( element , selectors . accordion , false ) ;
113
144
checkElement ( element , selectors . noSuggestions , true ) ;
114
145
} ) ;
@@ -121,9 +152,7 @@ describe('c-quantic-document-suggestion', () => {
121
152
} ) ;
122
153
await flushPromises ( ) ;
123
154
124
- expect ( engineMock . dispatch ) . toHaveBeenCalledWith (
125
- 'mockedFetchDocumentSuggestions'
126
- ) ;
155
+ expect ( functionsMocks . fetchDocumentSuggestions ) . toHaveBeenCalledTimes ( 1 ) ;
127
156
} ) ;
128
157
} ) ;
129
158
@@ -148,82 +177,97 @@ describe('c-quantic-document-suggestion', () => {
148
177
it ( 'should render the component and all parts with default options' , async ( ) => {
149
178
const element = createTestComponent ( ) ;
150
179
await flushPromises ( ) ;
180
+ expect ( functionsMocks . fetchDocumentSuggestions ) . not . toHaveBeenCalled ( ) ;
181
+ expect ( headlessLoaderMock . registerComponentForInit ) . toHaveBeenCalled ( ) ;
151
182
152
183
checkElement ( element , selectors . accordion , false ) ;
153
184
checkElement ( element , selectors . noSuggestions , true ) ;
154
185
checkElement ( element , selectors . componentError , false ) ;
155
186
156
187
await updateSuggestions ( ) ;
157
188
158
- expect ( engineMock . dispatch ) . not . toHaveBeenCalled ( ) ;
159
- expect ( headlessLoaderMock . registerComponentForInit ) . toHaveBeenCalled ( ) ;
160
-
161
189
checkElement ( element , selectors . noSuggestions , false ) ;
162
190
checkElement ( element , selectors . container , true ) ;
163
191
checkElement ( element , selectors . accordion , true ) ;
164
192
const sections = element . shadowRoot . querySelectorAll (
165
193
selectors . accordionSection
166
194
) ;
167
195
expect ( sections . length ) . toBe ( 2 ) ;
168
- expect ( sections [ 0 ] . getAttribute ( 'data-id' ) ) . toBe ( 'ego' ) ;
169
- checkElement ( element , selectors . quickview , true ) ;
196
+ sections . forEach ( ( section , index ) => {
197
+ expect ( section . label ) . toBe (
198
+ documentSuggestionListMock . state . documents [ index ] . title
199
+ ) ;
200
+ const uniqueId =
201
+ documentSuggestionListMock . state . documents [ index ] . uniqueId ;
202
+ expect ( section . getAttribute ( 'data-id' ) ) . toBe ( uniqueId ) ;
203
+ expect ( section . querySelector ( selectors . quickview ) ) . toBeTruthy ( ) ;
204
+ expect (
205
+ section
206
+ . querySelector ( 'slot[name="actions"]' )
207
+ . getAttribute ( 'data-doc-id' )
208
+ ) . toBe ( uniqueId ) ;
209
+ expect (
210
+ section
211
+ . querySelector ( 'slot[name="rating"]' )
212
+ . getAttribute ( 'data-doc-id' )
213
+ ) . toBe ( uniqueId ) ;
214
+ } ) ;
170
215
} ) ;
171
216
172
217
it ( 'should not render quick view button when withoutQuickview is set to true' , async ( ) => {
173
218
const element = createTestComponent ( {
174
219
withoutQuickview : true ,
175
- fetchOnInit : true ,
176
220
} ) ;
177
- await flushPromises ( ) ;
221
+ await updateSuggestions ( ) ;
178
222
179
223
expect ( element . shadowRoot . querySelector ( selectors . quickview ) ) . toBeFalsy ( ) ;
180
224
} ) ;
181
225
182
226
it ( 'should log a suggestion click if not opened' , async ( ) => {
183
- const element = createTestComponent ( {
184
- fetchOnInit : true ,
185
- } ) ;
227
+ const element = createTestComponent ( ) ;
186
228
await updateSuggestions ( ) ;
187
229
188
- const accordion = element . shadowRoot . querySelector ( selectors . accordion ) ;
189
230
const sections = element . shadowRoot . querySelectorAll (
190
231
selectors . accordionSection
191
232
) ;
233
+ const accordion = element . shadowRoot . querySelector ( selectors . accordion ) ;
192
234
193
- // Should not log click when opening first
235
+ // First document is already opened and will be collapsed, no click event logged.
194
236
sections [ 0 ] . click ( ) ;
195
- expect ( engineMock . dispatch ) . not . toHaveBeenCalledWith (
196
- 'mockedLogDocumentSuggestionClick'
237
+ expect ( functionsMocks . logDocumentSuggestionClick ) . toHaveBeenCalledTimes (
238
+ 0
197
239
) ;
198
-
199
240
accordion . activeSectionName = sections [ 1 ] . name ;
241
+
200
242
sections [ 1 ] . click ( ) ;
201
- expect ( engineMock . dispatch ) . toHaveBeenCalledWith ( [
202
- 'mockedLogDocumentSuggestionClick' ,
203
- sections [ 1 ] . name ,
204
- ] ) ;
243
+ await flushPromises ( ) ;
244
+ expect ( functionsMocks . logDocumentSuggestionClick ) . toHaveBeenCalledTimes (
245
+ 1
246
+ ) ;
247
+ expect ( functionsMocks . logDocumentSuggestionClick ) . toHaveBeenCalledWith (
248
+ documentSuggestionListMock . state . documents [ 1 ] . uniqueId
249
+ ) ;
205
250
} ) ;
206
251
207
252
it ( 'should handle document rating event' , async ( ) => {
208
- const element = createTestComponent ( {
209
- fetchOnInit : true ,
210
- } ) ;
253
+ const element = createTestComponent ( ) ;
211
254
await updateSuggestions ( ) ;
212
255
213
256
const customEvent = new CustomEvent ( 'quantic__rating' , {
214
257
detail : { id : 'mastercraft' , score : 2 } ,
215
258
} ) ;
216
259
element . shadowRoot . dispatchEvent ( customEvent ) ;
217
- expect ( engineMock . dispatch ) . toHaveBeenCalledWith ( [
218
- 'mockedLogDocumentSuggestionRating' ,
260
+ expect ( functionsMocks . logDocumentSuggestionRating ) . toHaveBeenCalledTimes (
261
+ 1
262
+ ) ;
263
+ expect ( functionsMocks . logDocumentSuggestionRating ) . toHaveBeenCalledWith (
219
264
'mastercraft' ,
220
- 2 ,
221
- ] ) ;
265
+ 2
266
+ ) ;
222
267
} ) ;
223
268
224
- it ( 'should truncate documents to maxDocuments' , async ( ) => {
269
+ it ( 'should truncate documents to maxDocuments if the state contains more ' , async ( ) => {
225
270
const element = createTestComponent ( {
226
- fetchOnInit : true ,
227
271
maxDocuments : 1 ,
228
272
} ) ;
229
273
await updateSuggestions ( ) ;
@@ -253,6 +297,46 @@ describe('c-quantic-document-suggestion', () => {
253
297
} ) ;
254
298
} ) ;
255
299
300
+ describe ( 'when two document suggestions have a similar title' , ( ) => {
301
+ it ( 'should open the right document suggestion when clicked' , async ( ) => {
302
+ documentSuggestionListMock . state . documents = [
303
+ {
304
+ title : 'dewalt' ,
305
+ uniqueId : 'dw745' ,
306
+ fields : {
307
+ uri : 'table saw' ,
308
+ } ,
309
+ } ,
310
+ {
311
+ title : 'dewalt' ,
312
+ uniqueId : 'dw560' ,
313
+ fields : {
314
+ uri : 'router' ,
315
+ } ,
316
+ } ,
317
+ ] ;
318
+
319
+ const element = createTestComponent ( ) ;
320
+ await updateSuggestions ( ) ;
321
+
322
+ const sectionToClick = element . shadowRoot . querySelectorAll (
323
+ selectors . accordionSection
324
+ ) [ 1 ] ;
325
+ const accordion = element . shadowRoot . querySelector ( selectors . accordion ) ;
326
+ accordion . activeSectionName = sectionToClick . name ;
327
+ sectionToClick . click ( ) ;
328
+ expect ( sectionToClick . name ) . toBe (
329
+ documentSuggestionListMock . state . documents [ 1 ] . uniqueId
330
+ ) ;
331
+ expect ( functionsMocks . logDocumentSuggestionClick ) . toHaveBeenCalledTimes (
332
+ 1
333
+ ) ;
334
+ expect ( functionsMocks . logDocumentSuggestionClick ) . toHaveBeenCalledWith (
335
+ sectionToClick . name
336
+ ) ;
337
+ } ) ;
338
+ } ) ;
339
+
256
340
describe ( 'with invalid options' , ( ) => {
257
341
it ( 'should set an error message if maxDocuments is invalid' , async ( ) => {
258
342
const element = createTestComponent ( {
@@ -271,4 +355,17 @@ describe('c-quantic-document-suggestion', () => {
271
355
checkElement ( element , selectors . componentError , true ) ;
272
356
} ) ;
273
357
} ) ;
358
+
359
+ describe ( 'when an initialization error occurs' , ( ) => {
360
+ beforeEach ( ( ) => {
361
+ mockErroneousHeadlessInitialization ( ) ;
362
+ } ) ;
363
+
364
+ it ( 'should display the initialization error component' , async ( ) => {
365
+ const element = createTestComponent ( ) ;
366
+ await flushPromises ( ) ;
367
+
368
+ checkElement ( element , selectors . componentError , true ) ;
369
+ } ) ;
370
+ } ) ;
274
371
} ) ;
0 commit comments