@@ -24,6 +24,38 @@ const mockedState: Partial<State> = {
24
24
}
25
25
} ;
26
26
27
+ const mockedStateWithSingleFilter : Partial < State > = {
28
+ ...mockedState ,
29
+ filters : {
30
+ static : [ {
31
+ filter : {
32
+ kind : 'fieldValue' ,
33
+ fieldId : 'name' ,
34
+ matcher : Matcher . Equals ,
35
+ value : 'Real Person'
36
+ } ,
37
+ selected : true ,
38
+ displayName : 'Real Person'
39
+ } ]
40
+ }
41
+ } ;
42
+
43
+ const mockedStateWithMultipleFilters : Partial < State > = {
44
+ ...mockedState ,
45
+ filters : {
46
+ static : [ ...( mockedStateWithSingleFilter . filters ?. static ?? [ ] ) , {
47
+ filter : {
48
+ kind : 'fieldValue' ,
49
+ fieldId : 'name' ,
50
+ matcher : Matcher . Equals ,
51
+ value : 'Fake Person'
52
+ } ,
53
+ selected : true ,
54
+ displayName : 'Fake Person'
55
+ } ]
56
+ }
57
+ } ;
58
+
27
59
describe ( 'search with section labels' , ( ) => {
28
60
it ( 'renders the filter search bar, "Filter" label, and default placeholder text' , ( ) => {
29
61
renderFilterSearch ( { searchFields : searchFieldsProp , label : 'Filter' } ) ;
@@ -179,6 +211,125 @@ describe('search with section labels', () => {
179
211
} ) ;
180
212
} ) ;
181
213
214
+ it ( 'displays name of matching filter in state when no filter is selected from component' , async ( ) => {
215
+ renderFilterSearch ( undefined , mockedStateWithSingleFilter ) ;
216
+ const searchBarElement = screen . getByRole ( 'textbox' ) ;
217
+ expect ( searchBarElement ) . toHaveValue ( 'Real Person' ) ;
218
+ } ) ;
219
+
220
+ it ( 'logs a warning when multiple matching filters in state and no current filter selected' , async ( ) => {
221
+ const consoleWarnSpy = jest . spyOn ( global . console , 'warn' ) . mockImplementation ( ) ;
222
+ renderFilterSearch ( undefined , mockedStateWithMultipleFilters ) ;
223
+ const searchBarElement = screen . getByRole ( 'textbox' ) ;
224
+ expect ( searchBarElement ) . toHaveValue ( 'Real Person' ) ;
225
+ expect ( consoleWarnSpy ) . toBeCalledWith (
226
+ 'More than one selected static filter found that matches the filter search fields: [name].'
227
+ + ' Please update the state to remove the extra filters.'
228
+ + ' Picking one filter to display in the input.'
229
+ ) ;
230
+ } ) ;
231
+
232
+ it ( 'does not log a warning for multiple matching filters in state if onSelect is passed' , async ( ) => {
233
+ const consoleWarnSpy = jest . spyOn ( global . console , 'warn' ) . mockImplementation ( ) ;
234
+ const mockedOnSelect = jest . fn ( ) ;
235
+ renderFilterSearch (
236
+ { searchFields : searchFieldsProp , onSelect : mockedOnSelect } ,
237
+ mockedStateWithMultipleFilters
238
+ ) ;
239
+ const searchBarElement = screen . getByRole ( 'textbox' ) ;
240
+ expect ( searchBarElement ) . toHaveValue ( 'Real Person' ) ;
241
+ expect ( consoleWarnSpy ) . not . toHaveBeenCalled ( ) ;
242
+ } ) ;
243
+
244
+ it ( 'unselects single matching filter in state when a new filter is selected and doesn\'t log warning' , async ( ) => {
245
+ const consoleWarnSpy = jest . spyOn ( global . console , 'warn' ) . mockImplementation ( ) ;
246
+ renderFilterSearch ( undefined , mockedStateWithSingleFilter ) ;
247
+ const executeFilterSearch = jest
248
+ . spyOn ( SearchHeadless . prototype , 'executeFilterSearch' )
249
+ . mockResolvedValue ( labeledFilterSearchResponse ) ;
250
+ const setFilterOption = jest . spyOn ( SearchHeadless . prototype , 'setFilterOption' ) ;
251
+ const searchBarElement = screen . getByRole ( 'textbox' ) ;
252
+
253
+ userEvent . clear ( searchBarElement ) ;
254
+ userEvent . type ( searchBarElement , 'n' ) ;
255
+ await waitFor ( ( ) => expect ( executeFilterSearch ) . toHaveBeenCalled ( ) ) ;
256
+ await waitFor ( ( ) => screen . findByText ( 'first name 1' ) ) ;
257
+ userEvent . type ( searchBarElement , '{enter}' ) ;
258
+ await waitFor ( ( ) => {
259
+ expect ( setFilterOption ) . toBeCalledWith ( {
260
+ filter : {
261
+ kind : 'fieldValue' ,
262
+ fieldId : 'name' ,
263
+ matcher : Matcher . Equals ,
264
+ value : 'Real Person'
265
+ } ,
266
+ selected : false
267
+ } ) ;
268
+ } ) ;
269
+ expect ( setFilterOption ) . toBeCalledWith ( {
270
+ filter : {
271
+ kind : 'fieldValue' ,
272
+ fieldId : 'name' ,
273
+ matcher : Matcher . Equals ,
274
+ value : 'first name 1'
275
+ } ,
276
+ displayName : 'first name 1' ,
277
+ selected : true
278
+ } ) ;
279
+
280
+ expect ( consoleWarnSpy ) . not . toHaveBeenCalled ( ) ;
281
+ } ) ;
282
+
283
+ it ( 'unselects multiple matching filters in state when a new filter is selected and logs warning' , async ( ) => {
284
+ const consoleWarnSpy = jest . spyOn ( global . console , 'warn' ) . mockImplementation ( ) ;
285
+ renderFilterSearch ( undefined , mockedStateWithMultipleFilters ) ;
286
+ const executeFilterSearch = jest
287
+ . spyOn ( SearchHeadless . prototype , 'executeFilterSearch' )
288
+ . mockResolvedValue ( labeledFilterSearchResponse ) ;
289
+ const setFilterOption = jest . spyOn ( SearchHeadless . prototype , 'setFilterOption' ) ;
290
+ const searchBarElement = screen . getByRole ( 'textbox' ) ;
291
+
292
+ userEvent . clear ( searchBarElement ) ;
293
+ userEvent . type ( searchBarElement , 'n' ) ;
294
+ await waitFor ( ( ) => expect ( executeFilterSearch ) . toHaveBeenCalled ( ) ) ;
295
+ await waitFor ( ( ) => screen . findByText ( 'first name 1' ) ) ;
296
+ userEvent . type ( searchBarElement , '{enter}' ) ;
297
+ await waitFor ( ( ) => {
298
+ expect ( setFilterOption ) . toBeCalledWith ( {
299
+ filter : {
300
+ kind : 'fieldValue' ,
301
+ fieldId : 'name' ,
302
+ matcher : Matcher . Equals ,
303
+ value : 'Real Person'
304
+ } ,
305
+ selected : false
306
+ } ) ;
307
+ } ) ;
308
+ expect ( setFilterOption ) . toBeCalledWith ( {
309
+ filter : {
310
+ kind : 'fieldValue' ,
311
+ fieldId : 'name' ,
312
+ matcher : Matcher . Equals ,
313
+ value : 'Fake Person'
314
+ } ,
315
+ selected : false
316
+ } ) ;
317
+ expect ( setFilterOption ) . toBeCalledWith ( {
318
+ filter : {
319
+ kind : 'fieldValue' ,
320
+ fieldId : 'name' ,
321
+ matcher : Matcher . Equals ,
322
+ value : 'first name 1'
323
+ } ,
324
+ displayName : 'first name 1' ,
325
+ selected : true
326
+ } ) ;
327
+ expect ( consoleWarnSpy ) . toBeCalledWith (
328
+ 'More than one selected static filter found that matches the filter search fields: [name].'
329
+ + ' Unselecting all existing matching filters and selecting the new filter.'
330
+ ) ;
331
+ } ) ;
332
+
182
333
it ( 'executes onSelect function when a filter is selected' , async ( ) => {
183
334
const mockedOnSelect = jest . fn ( ) ;
184
335
const setFilterOption = jest . spyOn ( SearchHeadless . prototype , 'setFilterOption' ) ;
@@ -329,7 +480,7 @@ describe('search with section labels', () => {
329
480
expect ( setFilterOption ) . not . toBeCalled ( ) ;
330
481
expect ( mockExecuteSearch ) . not . toBeCalled ( ) ;
331
482
expect ( consoleWarnSpy ) . toBeCalledWith ( 'Both searchOnSelect and onSelect props were passed to the component.'
332
- + ' Using onSelect instead of searchOnSelect as the latter is deprecated.' ) ;
483
+ + ' Using onSelect instead of searchOnSelect as the latter is deprecated.' ) ;
333
484
} ) ;
334
485
} ) ;
335
486
} ) ;
@@ -460,8 +611,11 @@ describe('screen reader', () => {
460
611
} ) ;
461
612
} ) ;
462
613
463
- function renderFilterSearch ( props : FilterSearchProps = { searchFields : searchFieldsProp } ) : RenderResult {
464
- return render ( < SearchHeadlessContext . Provider value = { generateMockedHeadless ( mockedState ) } >
614
+ function renderFilterSearch (
615
+ props : FilterSearchProps = { searchFields : searchFieldsProp } ,
616
+ state = mockedState
617
+ ) : RenderResult {
618
+ return render ( < SearchHeadlessContext . Provider value = { generateMockedHeadless ( state ) } >
465
619
< FilterSearch { ...props } />
466
620
</ SearchHeadlessContext . Provider > ) ;
467
621
}
@@ -490,15 +644,15 @@ it('clears input when old filters are removed', async () => {
490
644
} ;
491
645
return (
492
646
< button onClick = { handleClickDeselectFilter } >
493
- Deselect Filter
647
+ Deselect Filter
494
648
</ button >
495
649
) ;
496
650
497
651
}
498
652
499
653
render ( < SearchHeadlessContext . Provider value = { generateMockedHeadless ( mockedState ) } >
500
654
< FilterSearch searchFields = { searchFieldsProp } />
501
- < DeselectFiltersButton />
655
+ < DeselectFiltersButton />
502
656
</ SearchHeadlessContext . Provider > ) ;
503
657
504
658
const searchBarElement = screen . getByRole ( 'textbox' ) ;
0 commit comments