@@ -94,6 +94,16 @@ describe('GlobalSearchState', () => {
9494 expect ( mockGetFilterOptions ) . not . toHaveBeenCalled ( ) ;
9595 } ) ;
9696
97+ it ( 'should skip the API call for a CEDAR filter found only in extraFilters (before first fetch)' , ( ) => {
98+ const { store, mockGetFilterOptions } = setup ( ) ;
99+ store . dispatch ( new SetExtraFilters ( [ CEDAR_FILTER ] ) ) ;
100+ // Intentionally no FetchResources — state.filters is still empty
101+
102+ store . dispatch ( new LoadFilterOptions ( CEDAR_FILTER . key ) ) ;
103+
104+ expect ( mockGetFilterOptions ) . not . toHaveBeenCalled ( ) ;
105+ } ) ;
106+
97107 it ( 'should set isLoaded to true for a CEDAR filter when short-circuiting' , ( ) => {
98108 const { store } = setup ( ) ;
99109
@@ -264,4 +274,59 @@ describe('GlobalSearchState', () => {
264274 expect ( params [ 'cardSearchFilter[defaultKey][]' ] ) . toBe ( 'default-value' ) ;
265275 } ) ;
266276 } ) ;
277+
278+ describe ( 'updateResourcesState (CEDAR filter key collision)' , ( ) => {
279+ const COLLIDING_API_FILTER : DiscoverableFilter = {
280+ key : CEDAR_FILTER . key ,
281+ label : 'School Type (from API)' ,
282+ operator : FilterOperatorOption . AnyOf ,
283+ resultCount : 5 ,
284+ } ;
285+
286+ const MOCK_RESOURCES_WITH_COLLIDING_FILTER : ResourcesData = {
287+ resources : [ ] ,
288+ filters : [ COLLIDING_API_FILTER ] ,
289+ count : 5 ,
290+ self : '' ,
291+ first : null ,
292+ next : null ,
293+ previous : null ,
294+ } ;
295+
296+ it ( 'should preserve cedarPropertyIri when API returns a filter with the same key as an extra filter' , ( ) => {
297+ const { store, mockGetResources } = setup ( ) ;
298+ mockGetResources . mockReturnValue ( of ( MOCK_RESOURCES_WITH_COLLIDING_FILTER ) ) ;
299+
300+ store . dispatch ( new SetExtraFilters ( [ CEDAR_FILTER ] ) ) ;
301+ store . dispatch ( new FetchResources ( ) ) ;
302+
303+ const filters = store . selectSnapshot ( GlobalSearchSelectors . getFilters ) ;
304+ const filter = filters . find ( ( f ) => f . key === CEDAR_FILTER . key ) ;
305+ expect ( filter ?. cedarPropertyIri ) . toBe ( CEDAR_FILTER . cedarPropertyIri ) ;
306+ expect ( filter ?. options ) . toEqual ( CEDAR_FILTER . options ) ;
307+ } ) ;
308+
309+ it ( 'should use cardSearchText even when the API returns a filter with the same key' , ( ) => {
310+ const { store, mockGetResources } = setup ( ) ;
311+ mockGetResources . mockReturnValue ( of ( MOCK_RESOURCES_WITH_COLLIDING_FILTER ) ) ;
312+
313+ store . dispatch ( new SetExtraFilters ( [ CEDAR_FILTER ] ) ) ;
314+ store . dispatch ( new FetchResources ( ) ) ;
315+ mockGetResources . mockClear ( ) ;
316+ mockGetResources . mockReturnValue ( of ( MOCK_RESOURCES_DATA ) ) ;
317+
318+ store . dispatch (
319+ new LoadFilterOptionsAndSetValues ( {
320+ [ CEDAR_FILTER . key ] : [ { label : 'High School' , value : 'High School' , cardSearchResultCount : null } ] ,
321+ } )
322+ ) ;
323+ store . dispatch ( new FetchResources ( ) ) ;
324+
325+ const params = mockGetResources . mock . calls [ 0 ] [ 0 ] ;
326+ expect ( params [ `cardSearchText[osf:hasCedarRecord.cedar:${ CEDAR_FILTER . cedarPropertyIri } ][]` ] ) . toEqual ( [
327+ '"High School"' ,
328+ ] ) ;
329+ expect ( params [ `cardSearchFilter[${ CEDAR_FILTER . key } ][]` ] ) . toBeUndefined ( ) ;
330+ } ) ;
331+ } ) ;
267332} ) ;
0 commit comments