@internetarchive/collection-browser 3.4.0 → 3.4.1-alpha-webdev7761.1

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 (38) hide show
  1. package/dist/src/collection-browser.d.ts +15 -2
  2. package/dist/src/collection-browser.js +189 -14
  3. package/dist/src/collection-browser.js.map +1 -1
  4. package/dist/src/collection-facets/facet-row.js +2 -1
  5. package/dist/src/collection-facets/facet-row.js.map +1 -1
  6. package/dist/src/collection-facets.js +17 -2
  7. package/dist/src/collection-facets.js.map +1 -1
  8. package/dist/src/data-source/collection-browser-data-source-interface.d.ts +10 -1
  9. package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
  10. package/dist/src/data-source/collection-browser-data-source.d.ts +19 -1
  11. package/dist/src/data-source/collection-browser-data-source.js +36 -18
  12. package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
  13. package/dist/src/data-source/collection-browser-query-state.d.ts +1 -2
  14. package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
  15. package/dist/src/data-source/models.d.ts +11 -0
  16. package/dist/src/data-source/models.js.map +1 -1
  17. package/dist/src/models.d.ts +2 -6
  18. package/dist/src/models.js +10 -14
  19. package/dist/src/models.js.map +1 -1
  20. package/dist/src/restoration-state-handler.d.ts +1 -2
  21. package/dist/src/restoration-state-handler.js +3 -9
  22. package/dist/src/restoration-state-handler.js.map +1 -1
  23. package/dist/test/collection-browser.test.js +19 -9
  24. package/dist/test/collection-browser.test.js.map +1 -1
  25. package/dist/test/restoration-state-handler.test.js +5 -37
  26. package/dist/test/restoration-state-handler.test.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/collection-browser.ts +219 -11
  29. package/src/collection-facets/facet-row.ts +4 -1
  30. package/src/collection-facets.ts +17 -2
  31. package/src/data-source/collection-browser-data-source-interface.ts +12 -0
  32. package/src/data-source/collection-browser-data-source.ts +59 -19
  33. package/src/data-source/collection-browser-query-state.ts +1 -7
  34. package/src/data-source/models.ts +13 -0
  35. package/src/models.ts +12 -16
  36. package/src/restoration-state-handler.ts +9 -11
  37. package/test/collection-browser.test.ts +21 -11
  38. package/test/restoration-state-handler.test.ts +12 -42
@@ -153,6 +153,7 @@ export class CollectionFacets extends LitElement {
153
153
  creator: false,
154
154
  collection: false,
155
155
  year: false,
156
+ clip_type: false,
156
157
  program: false,
157
158
  person: false,
158
159
  sponsor: false,
@@ -169,6 +170,10 @@ export class CollectionFacets extends LitElement {
169
170
  managing: this.isManageView,
170
171
  });
171
172
 
173
+ const heading = this.isTvSearch
174
+ ? msg('Date Published')
175
+ : msg('Year Published');
176
+
172
177
  // Added data-testid for Playwright testing
173
178
  // Using facet-group class and aria-labels is not ideal for Playwright locator
174
179
  const datePickerLabelId = 'date-picker-label';
@@ -183,7 +188,7 @@ export class CollectionFacets extends LitElement {
183
188
  data-testid="facet-group-header-label-date-picker"
184
189
  >
185
190
  <h3 id=${datePickerLabelId}>
186
- Year Published <span class="sr-only">range filter</span>
191
+ ${heading} <span class="sr-only">${msg('range filter')}</span>
187
192
  ${this.expandDatePickerBtnTemplate}
188
193
  </h3>
189
194
  ${this.histogramTemplate}
@@ -191,6 +196,7 @@ export class CollectionFacets extends LitElement {
191
196
  `
192
197
  : nothing}
193
198
  ${this.collectionPartOfTemplate}
199
+ <slot name="facets-top"></slot>
194
200
  ${this.mergedFacets.map(facetGroup =>
195
201
  this.getFacetGroupTemplate(facetGroup),
196
202
  )}
@@ -572,6 +578,15 @@ export class CollectionFacets extends LitElement {
572
578
  }
573
579
  });
574
580
  }
581
+ // For TV clip_type facets, capitalize the display text
582
+ if (facetKey === 'clip_type') {
583
+ bucketsWithCount.forEach(b => {
584
+ b.displayText ??= b.key;
585
+ b.displayText =
586
+ b.displayText.charAt(0).toLocaleUpperCase() +
587
+ b.displayText.slice(1);
588
+ });
589
+ }
575
590
 
576
591
  // slice off how many items we want to show in page facet area
577
592
  facetGroup.buckets = bucketsWithCount.slice(0, allowedFacetCount);
@@ -908,7 +923,7 @@ export class CollectionFacets extends LitElement {
908
923
  transform: rotate(90deg);
909
924
  }
910
925
 
911
- .facet-group:not(:last-child) {
926
+ .facet-group {
912
927
  margin-bottom: 2rem;
913
928
  }
914
929
 
@@ -16,6 +16,7 @@ import type {
16
16
  PageSpecifierParams,
17
17
  CollectionTitles,
18
18
  TVChannelAliases,
19
+ TVChannelMaps,
19
20
  } from './models';
20
21
 
21
22
  export interface CollectionBrowserDataSourceInterface
@@ -98,6 +99,11 @@ export interface CollectionBrowserDataSourceInterface
98
99
  */
99
100
  readonly tvChannelAliases: TVChannelAliases;
100
101
 
102
+ /**
103
+ * An object holding mappings from channels to networks, and programs to channels.
104
+ */
105
+ readonly tvChannelMaps: TVChannelMaps;
106
+
101
107
  /**
102
108
  * The "extra info" package provided by the PPS for collection pages, including details
103
109
  * used to populate the target collection header & About tab content.
@@ -330,4 +336,10 @@ export interface CollectionBrowserDataSourceInterface
330
336
  * of the data source to account for any new gaps in the data.
331
337
  */
332
338
  removeCheckedTiles(): void;
339
+
340
+ /**
341
+ * Fires requests to populate the TV channel mappings (chan2network and programs2chan),
342
+ * or returns the existing Promise for any such request that has already been made.
343
+ */
344
+ populateTVChannelMaps(): Promise<TVChannelMaps>;
333
345
  }
@@ -24,7 +24,11 @@ import {
24
24
  SORT_OPTIONS,
25
25
  HitRequestSource,
26
26
  } from '../models';
27
- import { FACETLESS_PAGE_ELEMENTS, type PageSpecifierParams } from './models';
27
+ import {
28
+ FACETLESS_PAGE_ELEMENTS,
29
+ TVChannelMaps,
30
+ type PageSpecifierParams,
31
+ } from './models';
28
32
  import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';
29
33
  import type { CollectionBrowserSearchInterface } from './collection-browser-query-state';
30
34
  import { sha1 } from '../utils/sha1';
@@ -121,6 +125,11 @@ export class CollectionBrowserDataSource
121
125
  */
122
126
  collectionTitles = new Map<string, string>();
123
127
 
128
+ /**
129
+ * @inheritdoc
130
+ */
131
+ tvChannelMaps: TVChannelMaps = {};
132
+
124
133
  /**
125
134
  * @inheritdoc
126
135
  */
@@ -162,6 +171,11 @@ export class CollectionBrowserDataSource
162
171
  */
163
172
  queryErrorMessage?: string;
164
173
 
174
+ /**
175
+ * Internal property to store the promise for any current TV channel maps fetch.
176
+ */
177
+ private _tvMapsPromise?: Promise<TVChannelMaps>;
178
+
165
179
  /**
166
180
  * Internal property to store the private value backing the `initialSearchComplete` getter.
167
181
  */
@@ -773,24 +787,6 @@ export class CollectionBrowserDataSource
773
787
  );
774
788
  }
775
789
 
776
- // Add any TV clip type filter, if applicable
777
- if (this.host.searchType === SearchType.TV) {
778
- switch (this.host.tvClipFilter) {
779
- case 'commercials':
780
- builder.addFilter('ad_id', '*', FilterConstraint.INCLUDE);
781
- break;
782
- case 'factchecks':
783
- builder.addFilter('factcheck', '*', FilterConstraint.INCLUDE);
784
- break;
785
- case 'quotes':
786
- builder.addFilter('clip', '1', FilterConstraint.INCLUDE);
787
- break;
788
- case 'all':
789
- default:
790
- break;
791
- }
792
- }
793
-
794
790
  const filterMap = builder.build();
795
791
  return filterMap;
796
792
  }
@@ -1398,4 +1394,48 @@ export class CollectionBrowserDataSource
1398
1394
  this.updatePrefixFiltersForCurrentSort();
1399
1395
  this.requestHostUpdate();
1400
1396
  }
1397
+
1398
+ /**
1399
+ * @inheritdoc
1400
+ */
1401
+ populateTVChannelMaps(): Promise<TVChannelMaps> {
1402
+ // To ensure that we only make these requests once, cache the Promise returned by the
1403
+ // first call, and return the same Promise on repeated calls.
1404
+ // Resolves once both maps have been retrieved and saved in the data source.
1405
+ if (!this._tvMapsPromise) {
1406
+ this._tvMapsPromise = this._fetchTVChannelMaps();
1407
+ }
1408
+
1409
+ return this._tvMapsPromise;
1410
+ }
1411
+
1412
+ /**
1413
+ * Internal function implementing the actual fetches for TV channel mappings.
1414
+ * This should only called by the public populateTVChannelMaps method, which is guarded so
1415
+ * that we do not make extra requests for these rather large mappings.
1416
+ */
1417
+ private async _fetchTVChannelMaps(): Promise<TVChannelMaps> {
1418
+ const baseURL = 'https://av.archive.org/etc';
1419
+ const dateStr = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
1420
+ const chan2networkPromise = fetch(
1421
+ `${baseURL}/chan2network.json?date=${dateStr}`,
1422
+ );
1423
+ const program2chansPromise = fetch(
1424
+ `${baseURL}/program2chans.json?date=${dateStr}`,
1425
+ );
1426
+
1427
+ const [chan2networkResponse, program2chansResponse] = await Promise.all([
1428
+ chan2networkPromise,
1429
+ program2chansPromise,
1430
+ ]);
1431
+ this.tvChannelMaps.channelToNetwork = new Map(
1432
+ Object.entries(await chan2networkResponse.json()),
1433
+ );
1434
+ this.tvChannelMaps.programToChannels = new Map(
1435
+ Object.entries(await program2chansResponse.json()),
1436
+ );
1437
+
1438
+ this.requestHostUpdate();
1439
+ return this.tvChannelMaps;
1440
+ }
1401
1441
  }
@@ -6,12 +6,7 @@ import type {
6
6
  SortDirection,
7
7
  SortParam,
8
8
  } from '@internetarchive/search-service';
9
- import type {
10
- FacetLoadStrategy,
11
- SelectedFacets,
12
- SortField,
13
- TvClipFilterType,
14
- } from '../models';
9
+ import type { FacetLoadStrategy, SelectedFacets, SortField } from '../models';
15
10
  import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';
16
11
 
17
12
  /**
@@ -30,7 +25,6 @@ export interface CollectionBrowserQueryState {
30
25
  maxSelectedDate?: string;
31
26
  selectedTitleFilter: string | null;
32
27
  selectedCreatorFilter: string | null;
33
- tvClipFilter?: TvClipFilterType;
34
28
  selectedSort?: SortField;
35
29
  sortDirection: SortDirection | null;
36
30
  }
@@ -13,6 +13,19 @@ export type CollectionTitles = Map<string, string>;
13
13
  */
14
14
  export type TVChannelAliases = Map<string, string>;
15
15
 
16
+ /**
17
+ * A Map from program (show) names to a mapping of all the channels that run them.
18
+ */
19
+ export type TVProgramChannels = Map<string, Record<string, number>>;
20
+
21
+ /**
22
+ * Object storing the different TV channel mappings used by the data source.
23
+ */
24
+ export type TVChannelMaps = {
25
+ channelToNetwork?: TVChannelAliases;
26
+ programToChannels?: TVProgramChannels;
27
+ };
28
+
16
29
  /**
17
30
  * The subset of search service params that uniquely specify the type of results
18
31
  * that are sought by an instance of collection browser.
package/src/models.ts CHANGED
@@ -636,6 +636,7 @@ export type FacetOption =
636
636
  | 'collection'
637
637
  | 'year'
638
638
  // TV-specific facet options:
639
+ | 'clip_type'
639
640
  | 'program'
640
641
  | 'person'
641
642
  | 'sponsor';
@@ -693,6 +694,7 @@ export const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({
693
694
  creator: {},
694
695
  collection: {},
695
696
  year: {},
697
+ clip_type: {},
696
698
  program: {},
697
699
  person: {},
698
700
  sponsor: {},
@@ -701,25 +703,15 @@ export const getDefaultSelectedFacets = (): Required<SelectedFacets> => ({
701
703
  /**
702
704
  * For TV search results, what types of TV clips to restrict the results to.
703
705
  */
704
- export type TvClipFilterType = 'all' | 'commercials' | 'factchecks' | 'quotes';
705
-
706
- /**
707
- * Map from TV clip filter types to their corresponding URL params
708
- */
709
- export const tvClipFiltersToURLParams: Record<TvClipFilterType, string> = {
710
- all: '',
711
- commercials: 'only_commercials',
712
- factchecks: 'only_factchecks',
713
- quotes: 'only_quotes',
714
- };
706
+ export type TvClipFilterType = 'commercial' | 'fact check' | 'quote';
715
707
 
716
708
  /**
717
709
  * Map from allowed TV filtering parameters in the URL to their corresponding filter type
718
710
  */
719
711
  export const tvClipURLParamsToFilters: Record<string, TvClipFilterType> = {
720
- only_commercials: 'commercials',
721
- only_factchecks: 'factchecks',
722
- only_quotes: 'quotes',
712
+ only_commercials: 'commercial',
713
+ only_factchecks: 'fact check',
714
+ only_quotes: 'quote',
723
715
  };
724
716
 
725
717
  /**
@@ -743,10 +735,11 @@ export const tvFacetDisplayOrder: FacetOption[] = [
743
735
  'creator',
744
736
  'year',
745
737
  'subject',
746
- 'collection',
738
+ // 'collection',
747
739
  'person',
748
- 'sponsor',
740
+ // 'sponsor',
749
741
  'language',
742
+ 'clip_type',
750
743
  ];
751
744
 
752
745
  /**
@@ -760,6 +753,7 @@ export const facetTitles: Record<FacetOption, string> = {
760
753
  creator: 'Creator',
761
754
  collection: 'Collection',
762
755
  year: 'Year',
756
+ clip_type: 'Clip Type',
763
757
  program: 'Program',
764
758
  person: 'Person',
765
759
  sponsor: 'Sponsor',
@@ -776,6 +770,7 @@ export const defaultFacetSort: Record<FacetOption, AggregationSortType> = {
776
770
  creator: AggregationSortType.COUNT,
777
771
  collection: AggregationSortType.COUNT,
778
772
  year: AggregationSortType.NUMERIC, // Year facets are ordered by their numeric value by default
773
+ clip_type: AggregationSortType.COUNT,
779
774
  program: AggregationSortType.COUNT,
780
775
  person: AggregationSortType.COUNT,
781
776
  sponsor: AggregationSortType.COUNT,
@@ -793,6 +788,7 @@ export const valueFacetSort: Record<FacetOption, AggregationSortType> = {
793
788
  creator: AggregationSortType.ALPHABETICAL,
794
789
  collection: AggregationSortType.ALPHABETICAL,
795
790
  year: AggregationSortType.NUMERIC, // Year facets' values should be compared numerically, not lexicographically (year 2001 > year 3)
791
+ clip_type: AggregationSortType.ALPHABETICAL,
796
792
  program: AggregationSortType.ALPHABETICAL,
797
793
  person: AggregationSortType.ALPHABETICAL,
798
794
  sponsor: AggregationSortType.ALPHABETICAL,
@@ -5,14 +5,12 @@ import {
5
5
  CollectionBrowserContext,
6
6
  CollectionDisplayMode,
7
7
  SelectedFacets,
8
- TvClipFilterType,
9
8
  SortField,
10
9
  FacetBucket,
11
10
  FacetState,
12
11
  getDefaultSelectedFacets,
13
12
  sortOptionFromAPIString,
14
13
  SORT_OPTIONS,
15
- tvClipFiltersToURLParams,
16
14
  tvClipURLParamsToFilters,
17
15
  } from './models';
18
16
  import { arrayEquals } from './utils/array-equals';
@@ -31,7 +29,6 @@ export interface RestorationState {
31
29
  maxSelectedDate?: string;
32
30
  selectedTitleFilter?: string;
33
31
  selectedCreatorFilter?: string;
34
- tvClipFilter?: TvClipFilterType;
35
32
  }
36
33
 
37
34
  export interface RestorationStatePersistOptions {
@@ -210,12 +207,6 @@ export class RestorationStateHandler
210
207
  newParams.append('and[]', state.creatorQuery);
211
208
  }
212
209
 
213
- // TV clip special filters
214
- if (state.tvClipFilter) {
215
- const tvClipParam = tvClipFiltersToURLParams[state.tvClipFilter];
216
- if (tvClipParam) newParams.append(tvClipParam, '1');
217
- }
218
-
219
210
  // Ensure we aren't pushing consecutive identical states to the history stack.
220
211
  // - If the state has changed, we push a new history entry.
221
212
  // - If only the page number has changed, we replace the current history entry.
@@ -412,9 +403,16 @@ export class RestorationStateHandler
412
403
  }
413
404
 
414
405
  // TV clip special filters (carryovers from legacy page)
415
- for (const [paramKey, filter] of Object.entries(tvClipURLParamsToFilters)) {
406
+ for (const [paramKey, facetKey] of Object.entries(
407
+ tvClipURLParamsToFilters,
408
+ )) {
416
409
  if (url.searchParams.get(paramKey)) {
417
- restorationState.tvClipFilter = filter;
410
+ this.setSelectedFacetState(
411
+ restorationState.selectedFacets,
412
+ 'clip_type',
413
+ facetKey,
414
+ 'selected',
415
+ );
418
416
  break;
419
417
  }
420
418
  }
@@ -1087,7 +1087,7 @@ describe('Collection Browser', () => {
1087
1087
  });
1088
1088
  });
1089
1089
 
1090
- it('applies correct search filter when TV clip filter set to commercials', async () => {
1090
+ it('applies correct TV search filter for commercials', async () => {
1091
1091
  const searchService = new MockSearchService();
1092
1092
  const el = await fixture<CollectionBrowser>(
1093
1093
  html`<collection-browser .searchService=${searchService}>
@@ -1096,16 +1096,20 @@ describe('Collection Browser', () => {
1096
1096
 
1097
1097
  el.baseQuery = 'tv-fields';
1098
1098
  el.searchType = SearchType.TV;
1099
- el.tvClipFilter = 'commercials';
1099
+ el.selectedFacets = {
1100
+ clip_type: {
1101
+ commercial: { key: 'commercial', count: 1, state: 'selected' },
1102
+ },
1103
+ };
1100
1104
  await el.updateComplete;
1101
1105
  await el.initialSearchComplete;
1102
1106
 
1103
- expect(searchService.searchParams?.filters?.ad_id?.['*']).to.equal(
1107
+ expect(searchService.searchParams?.filters?.clip_type?.commercial).to.equal(
1104
1108
  FilterConstraint.INCLUDE,
1105
1109
  );
1106
1110
  });
1107
1111
 
1108
- it('applies correct search filter when TV clip filter set to factchecks', async () => {
1112
+ it('applies correct TV search filter for fact checks', async () => {
1109
1113
  const searchService = new MockSearchService();
1110
1114
  const el = await fixture<CollectionBrowser>(
1111
1115
  html`<collection-browser .searchService=${searchService}>
@@ -1114,16 +1118,20 @@ describe('Collection Browser', () => {
1114
1118
 
1115
1119
  el.baseQuery = 'tv-fields';
1116
1120
  el.searchType = SearchType.TV;
1117
- el.tvClipFilter = 'factchecks';
1121
+ el.selectedFacets = {
1122
+ clip_type: {
1123
+ 'fact check': { key: 'fact check', count: 1, state: 'selected' },
1124
+ },
1125
+ };
1118
1126
  await el.updateComplete;
1119
1127
  await el.initialSearchComplete;
1120
1128
 
1121
- expect(searchService.searchParams?.filters?.factcheck?.['*']).to.equal(
1122
- FilterConstraint.INCLUDE,
1123
- );
1129
+ expect(
1130
+ searchService.searchParams?.filters?.clip_type?.['fact check'],
1131
+ ).to.equal(FilterConstraint.INCLUDE);
1124
1132
  });
1125
1133
 
1126
- it('applies correct search filter when TV clip filter set to quotes', async () => {
1134
+ it('applies correct TV search filter for quotes', async () => {
1127
1135
  const searchService = new MockSearchService();
1128
1136
  const el = await fixture<CollectionBrowser>(
1129
1137
  html`<collection-browser .searchService=${searchService}>
@@ -1132,11 +1140,13 @@ describe('Collection Browser', () => {
1132
1140
 
1133
1141
  el.baseQuery = 'tv-fields';
1134
1142
  el.searchType = SearchType.TV;
1135
- el.tvClipFilter = 'quotes';
1143
+ el.selectedFacets = {
1144
+ clip_type: { quote: { key: 'quote', count: 1, state: 'selected' } },
1145
+ };
1136
1146
  await el.updateComplete;
1137
1147
  await el.initialSearchComplete;
1138
1148
 
1139
- expect(searchService.searchParams?.filters?.clip?.['1']).to.equal(
1149
+ expect(searchService.searchParams?.filters?.clip_type?.quote).to.equal(
1140
1150
  FilterConstraint.INCLUDE,
1141
1151
  );
1142
1152
  });
@@ -250,25 +250,33 @@ describe('Restoration state handler', () => {
250
250
  url.search = '?only_commercials=1';
251
251
  window.history.replaceState({ path: url.href }, '', url.href);
252
252
  const commercialsRestorationState = handler.getRestorationState();
253
- expect(commercialsRestorationState.tvClipFilter).to.equal('commercials');
253
+ expect(
254
+ commercialsRestorationState.selectedFacets.clip_type?.commercial.state,
255
+ ).to.equal('selected');
254
256
 
255
257
  // Fact checks
256
258
  url.search = '?only_factchecks=1';
257
259
  window.history.replaceState({ path: url.href }, '', url.href);
258
260
  const factchecksRestorationState = handler.getRestorationState();
259
- expect(factchecksRestorationState.tvClipFilter).to.equal('factchecks');
261
+ expect(
262
+ factchecksRestorationState.selectedFacets.clip_type?.['fact check'].state,
263
+ ).to.equal('selected');
260
264
 
261
265
  // Quotes
262
266
  url.search = '?only_quotes=1';
263
267
  window.history.replaceState({ path: url.href }, '', url.href);
264
268
  const quotesRestorationState = handler.getRestorationState();
265
- expect(quotesRestorationState.tvClipFilter).to.equal('quotes');
269
+ expect(
270
+ quotesRestorationState.selectedFacets.clip_type?.quote.state,
271
+ ).to.equal('selected');
266
272
 
267
273
  // No filter param
268
274
  url.search = '';
269
275
  window.history.replaceState({ path: url.href }, '', url.href);
270
276
  const unfilteredRestorationState = handler.getRestorationState();
271
- expect(unfilteredRestorationState.tvClipFilter).not.to.exist;
277
+ expect(unfilteredRestorationState.selectedFacets.clip_type).to.deep.equal(
278
+ {},
279
+ );
272
280
  });
273
281
 
274
282
  it('should restore sort from URL (space format)', async () => {
@@ -402,44 +410,6 @@ describe('Restoration state handler', () => {
402
410
  expect(window.location.search).to.equal('?page=2');
403
411
  });
404
412
 
405
- it('should persist TV clip filter types to the URL', async () => {
406
- const url = new URL(window.location.href);
407
- url.search = '';
408
- window.history.replaceState({ path: url.href }, '', url.href);
409
-
410
- // Commercials
411
- const handler = new RestorationStateHandler({ context: 'search' });
412
- handler.persistState({
413
- tvClipFilter: 'commercials',
414
- selectedFacets: getDefaultSelectedFacets(),
415
- });
416
- expect(window.location.search).to.equal('?only_commercials=1');
417
-
418
- // Fact checks
419
- window.history.replaceState({ path: url.href }, '', url.href);
420
- handler.persistState({
421
- tvClipFilter: 'factchecks',
422
- selectedFacets: getDefaultSelectedFacets(),
423
- });
424
- expect(window.location.search).to.equal('?only_factchecks=1');
425
-
426
- // Quotes
427
- window.history.replaceState({ path: url.href }, '', url.href);
428
- handler.persistState({
429
- tvClipFilter: 'quotes',
430
- selectedFacets: getDefaultSelectedFacets(),
431
- });
432
- expect(window.location.search).to.equal('?only_quotes=1');
433
-
434
- // Unfiltered
435
- window.history.replaceState({ path: url.href }, '', url.href);
436
- handler.persistState({
437
- tvClipFilter: 'all',
438
- selectedFacets: getDefaultSelectedFacets(),
439
- });
440
- expect(window.location.search).to.equal('');
441
- });
442
-
443
413
  it('should upgrade legacy search params to new ones', async () => {
444
414
  const url = new URL(window.location.href);
445
415
  url.search = '?q=foo';