@internetarchive/collection-browser 0.2.15-0 → 0.2.16-alpha1

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 (55) hide show
  1. package/dist/src/app-root.d.ts +1 -0
  2. package/dist/src/app-root.js +29 -2
  3. package/dist/src/app-root.js.map +1 -1
  4. package/dist/src/assets/img/icons/arrow-left.d.ts +2 -0
  5. package/dist/src/assets/img/icons/arrow-left.js +10 -0
  6. package/dist/src/assets/img/icons/arrow-left.js.map +1 -0
  7. package/dist/src/assets/img/icons/arrow-right.d.ts +2 -0
  8. package/dist/src/assets/img/icons/arrow-right.js +10 -0
  9. package/dist/src/assets/img/icons/arrow-right.js.map +1 -0
  10. package/dist/src/collection-browser.d.ts +2 -0
  11. package/dist/src/collection-browser.js +9 -13
  12. package/dist/src/collection-browser.js.map +1 -1
  13. package/dist/src/collection-facets/more-facets-content.d.ts +56 -0
  14. package/dist/src/collection-facets/more-facets-content.js +374 -0
  15. package/dist/src/collection-facets/more-facets-content.js.map +1 -0
  16. package/dist/src/collection-facets/more-facets-pagination.d.ts +27 -0
  17. package/dist/src/collection-facets/more-facets-pagination.js +193 -0
  18. package/dist/src/collection-facets/more-facets-pagination.js.map +1 -0
  19. package/dist/src/collection-facets.d.ts +19 -2
  20. package/dist/src/collection-facets.js +102 -0
  21. package/dist/src/collection-facets.js.map +1 -1
  22. package/dist/src/models.d.ts +3 -2
  23. package/dist/src/models.js +8 -4
  24. package/dist/src/models.js.map +1 -1
  25. package/dist/src/sort-filter-bar/sort-filter-bar.d.ts +23 -1
  26. package/dist/src/sort-filter-bar/sort-filter-bar.js +96 -12
  27. package/dist/src/sort-filter-bar/sort-filter-bar.js.map +1 -1
  28. package/dist/test/collection-browser.test.js +35 -0
  29. package/dist/test/collection-browser.test.js.map +1 -1
  30. package/dist/test/collection-facets/more-facets-content.test.d.ts +1 -0
  31. package/dist/test/collection-facets/more-facets-content.test.js +75 -0
  32. package/dist/test/collection-facets/more-facets-content.test.js.map +1 -0
  33. package/dist/test/collection-facets/more-facets-pagination.test.d.ts +1 -0
  34. package/dist/test/collection-facets/more-facets-pagination.test.js +38 -0
  35. package/dist/test/collection-facets/more-facets-pagination.test.js.map +1 -0
  36. package/dist/test/mocks/mock-search-responses.js +13 -0
  37. package/dist/test/mocks/mock-search-responses.js.map +1 -1
  38. package/dist/test/sort-filter-bar/sort-filter-bar.test.d.ts +1 -0
  39. package/dist/test/sort-filter-bar/sort-filter-bar.test.js +122 -0
  40. package/dist/test/sort-filter-bar/sort-filter-bar.test.js.map +1 -0
  41. package/package.json +3 -1
  42. package/src/app-root.ts +29 -2
  43. package/src/assets/img/icons/arrow-left.ts +10 -0
  44. package/src/assets/img/icons/arrow-right.ts +10 -0
  45. package/src/collection-browser.ts +8 -13
  46. package/src/collection-facets/more-facets-content.ts +393 -0
  47. package/src/collection-facets/more-facets-pagination.ts +201 -0
  48. package/src/collection-facets.ts +117 -1
  49. package/src/models.ts +9 -4
  50. package/src/sort-filter-bar/sort-filter-bar.ts +98 -12
  51. package/test/collection-browser.test.ts +43 -0
  52. package/test/collection-facets/more-facets-content.test.ts +113 -0
  53. package/test/collection-facets/more-facets-pagination.test.ts +70 -0
  54. package/test/mocks/mock-search-responses.ts +13 -0
  55. package/test/sort-filter-bar/sort-filter-bar.test.ts +187 -0
@@ -9,11 +9,19 @@ import {
9
9
  } from 'lit';
10
10
  import { customElement, property, state } from 'lit/decorators.js';
11
11
  import { repeat } from 'lit/directives/repeat.js';
12
- import type { Aggregation, Bucket } from '@internetarchive/search-service';
12
+ import type {
13
+ Aggregation,
14
+ Bucket,
15
+ SearchServiceInterface,
16
+ } from '@internetarchive/search-service';
13
17
  import '@internetarchive/histogram-date-range';
14
18
  import '@internetarchive/feature-feedback';
15
19
  import '@internetarchive/collection-name-cache';
16
20
  import type { CollectionNameCacheInterface } from '@internetarchive/collection-name-cache';
21
+ import {
22
+ ModalConfig,
23
+ ModalManagerInterface,
24
+ } from '@internetarchive/modal-manager';
17
25
  import eyeIcon from './assets/img/icons/eye';
18
26
  import eyeClosedIcon from './assets/img/icons/eye-closed';
19
27
  import chevronIcon from './assets/img/icons/chevron';
@@ -25,6 +33,7 @@ import {
25
33
  defaultSelectedFacets,
26
34
  } from './models';
27
35
  import type { LanguageCodeHandlerInterface } from './language-code-handler/language-code-handler';
36
+ import './collection-facets/more-facets-content';
28
37
 
29
38
  const facetDisplayOrder: FacetOption[] = [
30
39
  'mediatype',
@@ -55,6 +64,8 @@ const facetTitles: Record<FacetOption, string> = {
55
64
 
56
65
  @customElement('collection-facets')
57
66
  export class CollectionFacets extends LitElement {
67
+ @property({ type: Object }) searchService?: SearchServiceInterface;
68
+
58
69
  @property({ type: Object }) aggregations?: Record<string, Aggregation>;
59
70
 
60
71
  @property({ type: Object }) fullYearsHistogramAggregation?: Aggregation;
@@ -73,6 +84,10 @@ export class CollectionFacets extends LitElement {
73
84
 
74
85
  @property({ type: Boolean }) showHistogramDatePicker = false;
75
86
 
87
+ @property({ type: String }) fullQuery?: string;
88
+
89
+ @property({ type: Object }) modalManager?: ModalManagerInterface;
90
+
76
91
  @property({ type: Object })
77
92
  languageCodeHandler?: LanguageCodeHandlerInterface;
78
93
 
@@ -88,6 +103,12 @@ export class CollectionFacets extends LitElement {
88
103
  year: false,
89
104
  };
90
105
 
106
+ /**
107
+ * If listed facets on page more then this number,
108
+ * - show the more link button just below the facets group
109
+ */
110
+ private moreLinkEligibilityCount = 5;
111
+
91
112
  render() {
92
113
  return html`
93
114
  <div id="container" class="${this.facetsLoading ? 'loading' : ''}">
@@ -112,6 +133,7 @@ export class CollectionFacets extends LitElement {
112
133
  }
113
134
  }
114
135
 
136
+ // TODO: want to fire analytics?
115
137
  private dispatchFacetsChangedEvent() {
116
138
  const event = new CustomEvent<SelectedFacets>('facetsChanged', {
117
139
  detail: this.selectedFacets,
@@ -322,11 +344,92 @@ export class CollectionFacets extends LitElement {
322
344
  </h1>
323
345
  <div class="facet-group-content ${isOpen ? 'open' : ''}">
324
346
  ${this.getFacetTemplate(facetGroup)}
347
+ ${this.searchMoreFacetsLink(facetGroup)}
325
348
  </div>
326
349
  </div>
327
350
  `;
328
351
  }
329
352
 
353
+ /**
354
+ * Generate the More... link button just below the facets group
355
+ *
356
+ * TODO: want to fire analytics?
357
+ */
358
+ private searchMoreFacetsLink(
359
+ facetGroup: FacetGroup
360
+ ): TemplateResult | typeof nothing {
361
+ // don't render More... link if the number of facets is < this.moreLinkEligibilityCount
362
+ if (Object.keys(facetGroup.buckets).length < this.moreLinkEligibilityCount)
363
+ return nothing;
364
+
365
+ return html`<button
366
+ class="more-link"
367
+ @click=${() => {
368
+ this.showMoreFacetsModal(facetGroup);
369
+ }}
370
+ >
371
+ More...
372
+ </button>`;
373
+ }
374
+
375
+ async showMoreFacetsModal(facetGroup: FacetGroup): Promise<void> {
376
+ const facetAggrKey = Object.keys(aggregationToFacetOption).find(
377
+ value => aggregationToFacetOption[value] === facetGroup.key
378
+ );
379
+
380
+ // TODO - lets move sr-only style into modal-manager component as well
381
+ const headline = html`
382
+ <span
383
+ style="display:block;text-align:left;font-size:1.8rem;padding:0 10px;"
384
+ >
385
+ <span
386
+ style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip: rect(0,0,0,0);border:0;"
387
+ >More facets for:
388
+ </span>
389
+ ${facetTitles[facetGroup.key]}
390
+ <img
391
+ src="https://archive.org/images/filter-count.png"
392
+ style="height: 1.5rem;vertical-align: baseline;"
393
+ alt=""
394
+ />
395
+ </span>
396
+ `;
397
+
398
+ const message = html`
399
+ <more-facets-content
400
+ @facetsChanged=${(e: CustomEvent) => {
401
+ const event = new CustomEvent<SelectedFacets>('facetsChanged', {
402
+ detail: e.detail,
403
+ bubbles: true,
404
+ composed: true,
405
+ });
406
+ this.dispatchEvent(event);
407
+ }}
408
+ .facetKey=${facetGroup.key}
409
+ .facetAggregationKey=${facetAggrKey}
410
+ .fullQuery=${this.fullQuery}
411
+ .modalManager=${this.modalManager}
412
+ .searchService=${this.searchService}
413
+ .collectionNameCache=${this.collectionNameCache}
414
+ .languageCodeHandler=${this.languageCodeHandler}
415
+ .selectedFacets=${this.selectedFacets}
416
+ >
417
+ </more-facets-content>
418
+ `;
419
+
420
+ const config = new ModalConfig({
421
+ bodyColor: '#fff',
422
+ headerColor: '#194880',
423
+ showHeaderLogo: false,
424
+ closeOnBackdropClick: true, // TODO: want to fire analytics
425
+ title: html`Select filters`,
426
+ headline,
427
+ message,
428
+ });
429
+ this.modalManager?.classList.add('more-search-facets');
430
+ this.modalManager?.showModal({ config });
431
+ }
432
+
330
433
  /**
331
434
  * Generate the list template for each bucket in a facet group
332
435
  */
@@ -605,6 +708,19 @@ export class CollectionFacets extends LitElement {
605
708
  .hide-facet-icon.active .eye {
606
709
  display: none;
607
710
  }
711
+
712
+ .more-link {
713
+ font-size: 1.2rem;
714
+ text-decoration: none;
715
+ padding: 0px 4px;
716
+ background: inherit;
717
+ border: 0;
718
+ color: blue;
719
+ cursor: pointer;
720
+ }
721
+ .sorting-icon {
722
+ cursor: pointer;
723
+ }
608
724
  `;
609
725
  }
610
726
  }
package/src/models.ts CHANGED
@@ -47,7 +47,8 @@ export type CollectionBrowserContext = 'collection' | 'search';
47
47
  */
48
48
  export enum SortField {
49
49
  'relevance' = 'relevance',
50
- 'views' = 'views',
50
+ 'alltimeview' = 'alltimeview',
51
+ 'weeklyview' = 'weeklyview',
51
52
  'title' = 'title',
52
53
  'datearchived' = 'datearchived',
53
54
  'date' = 'date',
@@ -60,6 +61,7 @@ export enum SortField {
60
61
  * The metadata fields we sort by that map to the SortFields above
61
62
  */
62
63
  export type MetadataSortField =
64
+ | 'downloads'
63
65
  | 'week'
64
66
  | 'titleSorter'
65
67
  | 'date'
@@ -72,7 +74,8 @@ export const SortFieldDisplayName: {
72
74
  [key in SortField]: string;
73
75
  } = {
74
76
  relevance: 'Relevance',
75
- views: 'Views',
77
+ alltimeview: 'All-time Views',
78
+ weeklyview: 'Weekly Views',
76
79
  title: 'Title',
77
80
  datearchived: 'Date Archived',
78
81
  date: 'Date Published',
@@ -88,7 +91,8 @@ export const SortFieldToMetadataField: {
88
91
  [key in SortField]: MetadataSortField | null;
89
92
  } = {
90
93
  relevance: null,
91
- views: 'week',
94
+ alltimeview: 'downloads',
95
+ weeklyview: 'week',
92
96
  title: 'titleSorter',
93
97
  datearchived: 'publicdate',
94
98
  date: 'date',
@@ -103,13 +107,14 @@ export const SortFieldToMetadataField: {
103
107
  export const MetadataFieldToSortField: {
104
108
  [key in MetadataSortField]: SortField;
105
109
  } = {
110
+ week: SortField.weeklyview,
111
+ downloads: SortField.alltimeview,
106
112
  titleSorter: SortField.title,
107
113
  date: SortField.date,
108
114
  publicdate: SortField.datearchived,
109
115
  reviewdate: SortField.datereviewed,
110
116
  addeddate: SortField.dateadded,
111
117
  creatorSorter: SortField.creator,
112
- week: SortField.views,
113
118
  };
114
119
 
115
120
  export type FacetOption =
@@ -48,6 +48,8 @@ export class SortFilterBar
48
48
 
49
49
  @state() dateSortSelectorVisible = false;
50
50
 
51
+ @state() viewSortSelectorVisible = false;
52
+
51
53
  @state() desktopSelectorBarWidth = 0;
52
54
 
53
55
  @state() selectorBarContainerWidth = 0;
@@ -76,6 +78,9 @@ export class SortFilterBar
76
78
  <div id="display-style-selector">${this.displayOptionTemplate}</div>
77
79
  </div>
78
80
 
81
+ ${this.viewSortSelectorVisible && !this.mobileSelectorVisible
82
+ ? this.viewSortSelector
83
+ : nothing}
79
84
  ${this.dateSortSelectorVisible && !this.mobileSelectorVisible
80
85
  ? this.dateSortSelector
81
86
  : nothing}
@@ -103,7 +108,10 @@ export class SortFilterBar
103
108
  this.alphaSelectorVisible = 'creator';
104
109
  }
105
110
 
106
- if (changed.has('dateSortSelectorVisible')) {
111
+ if (
112
+ changed.has('dateSortSelectorVisible') ||
113
+ changed.has('viewSortSelectorVisible')
114
+ ) {
107
115
  this.setupEscapeListeners();
108
116
  }
109
117
 
@@ -117,21 +125,22 @@ export class SortFilterBar
117
125
  }
118
126
 
119
127
  private setupEscapeListeners() {
120
- if (this.dateSortSelectorVisible) {
128
+ if (this.dateSortSelectorVisible || this.viewSortSelectorVisible) {
121
129
  document.addEventListener(
122
130
  'keydown',
123
- this.boundDateSelectorEscapeListener
131
+ this.boundSortBarSelectorEscapeListener
124
132
  );
125
133
  } else {
126
134
  document.removeEventListener(
127
135
  'keydown',
128
- this.boundDateSelectorEscapeListener
136
+ this.boundSortBarSelectorEscapeListener
129
137
  );
130
138
  }
131
139
  }
132
140
 
133
- private boundDateSelectorEscapeListener = (e: KeyboardEvent) => {
141
+ private boundSortBarSelectorEscapeListener = (e: KeyboardEvent) => {
134
142
  if (e.key === 'Escape') {
143
+ this.viewSortSelectorVisible = false;
135
144
  this.dateSortSelectorVisible = false;
136
145
  }
137
146
  };
@@ -235,13 +244,30 @@ export class SortFilterBar
235
244
  ? this.getSortDisplayOption(SortField.relevance)
236
245
  : nothing}
237
246
  </li>
238
- <li>${this.getSortDisplayOption(SortField.views)}</li>
247
+ <li>
248
+ ${this.getSortDisplayOption(SortField.weeklyview, {
249
+ clickEvent: () => {
250
+ if (!this.viewOptionSelected)
251
+ this.setSelectedSort(SortField.weeklyview);
252
+ this.viewSortSelectorVisible = !this.viewSortSelectorVisible;
253
+ this.dateSortSelectorVisible = false;
254
+ this.alphaSelectorVisible = null;
255
+ this.selectedTitleFilter = null;
256
+ this.selectedCreatorFilter = null;
257
+ this.emitTitleLetterChangedEvent();
258
+ this.emitCreatorLetterChangedEvent();
259
+ },
260
+ displayName: html`${this.viewSortField}`,
261
+ isSelected: () => this.viewOptionSelected,
262
+ })}
263
+ </li>
239
264
  <li>
240
265
  ${this.getSortDisplayOption(SortField.title, {
241
266
  clickEvent: () => {
242
267
  this.alphaSelectorVisible = 'title';
243
268
  this.selectedCreatorFilter = null;
244
269
  this.dateSortSelectorVisible = false;
270
+ this.viewSortSelectorVisible = false;
245
271
  this.setSelectedSort(SortField.title);
246
272
  this.emitCreatorLetterChangedEvent();
247
273
  },
@@ -253,6 +279,7 @@ export class SortFilterBar
253
279
  if (!this.dateOptionSelected)
254
280
  this.setSelectedSort(SortField.date);
255
281
  this.dateSortSelectorVisible = !this.dateSortSelectorVisible;
282
+ this.viewSortSelectorVisible = false;
256
283
  this.alphaSelectorVisible = null;
257
284
  this.selectedTitleFilter = null;
258
285
  this.selectedCreatorFilter = null;
@@ -366,7 +393,7 @@ export class SortFilterBar
366
393
  </li>
367
394
  <li>
368
395
  <button
369
- id="grid-button"
396
+ id="list-detail-button"
370
397
  @click=${() => {
371
398
  this.displayMode = 'list-detail';
372
399
  }}
@@ -378,7 +405,7 @@ export class SortFilterBar
378
405
  </li>
379
406
  <li>
380
407
  <button
381
- id="list-button"
408
+ id="list-compact-button"
382
409
  @click=${() => {
383
410
  this.displayMode = 'list-compact';
384
411
  }}
@@ -414,6 +441,26 @@ export class SortFilterBar
414
441
  `;
415
442
  }
416
443
 
444
+ private get viewSortSelector() {
445
+ return html`
446
+ <div
447
+ id="view-sort-selector-backdrop"
448
+ @keyup=${() => {
449
+ this.viewSortSelectorVisible = false;
450
+ }}
451
+ @click=${() => {
452
+ this.viewSortSelectorVisible = false;
453
+ }}
454
+ ></div>
455
+ <div id="view-sort-selector">
456
+ <ul>
457
+ <li>${this.getDateSortButton(SortField.alltimeview)}</li>
458
+ <li>${this.getDateSortButton(SortField.weeklyview)}</li>
459
+ </ul>
460
+ </div>
461
+ `;
462
+ }
463
+
417
464
  private getDateSortButton(sortField: SortField) {
418
465
  return html`
419
466
  <button
@@ -429,6 +476,7 @@ export class SortFilterBar
429
476
 
430
477
  private selectDateSort(sortField: SortField) {
431
478
  this.dateSortSelectorVisible = false;
479
+ this.viewSortSelectorVisible = false;
432
480
  this.setSelectedSort(sortField);
433
481
  }
434
482
 
@@ -462,6 +510,24 @@ export class SortFilterBar
462
510
  return dateSortFields.includes(this.selectedSort);
463
511
  }
464
512
 
513
+ /**
514
+ * There are two view sort options.
515
+ *
516
+ * This checks to see if the current sort is one of them.
517
+ *
518
+ * @readonly
519
+ * @private
520
+ * @type {boolean}
521
+ * @memberof SortFilterBar
522
+ */
523
+ private get viewOptionSelected(): boolean {
524
+ const viewSortFields: SortField[] = [
525
+ SortField.alltimeview,
526
+ SortField.weeklyview,
527
+ ];
528
+ return viewSortFields.includes(this.selectedSort);
529
+ }
530
+
465
531
  /**
466
532
  * The display name of the current date field
467
533
  *
@@ -478,6 +544,22 @@ export class SortFilterBar
478
544
  return name;
479
545
  }
480
546
 
547
+ /**
548
+ * The display name of the current view field
549
+ *
550
+ * @readonly
551
+ * @private
552
+ * @type {string}
553
+ * @memberof SortFilterBar
554
+ */
555
+ private get viewSortField(): string {
556
+ const defaultSort = SortFieldDisplayName[SortField.weeklyview];
557
+ const name = this.viewOptionSelected
558
+ ? SortFieldDisplayName[this.selectedSort] ?? defaultSort
559
+ : defaultSort;
560
+ return name;
561
+ }
562
+
481
563
  private get titleSelectorBar() {
482
564
  return html` <alpha-bar
483
565
  .selectedLetter=${this.selectedTitleFilter}
@@ -607,7 +689,8 @@ export class SortFilterBar
607
689
  cursor: default;
608
690
  }
609
691
 
610
- #date-sort-selector {
692
+ #date-sort-selector,
693
+ #view-sort-selector {
611
694
  position: absolute;
612
695
  left: 150px;
613
696
  top: 45px;
@@ -619,7 +702,8 @@ export class SortFilterBar
619
702
  border: 1px solid #404142;
620
703
  }
621
704
 
622
- #date-sort-selector button {
705
+ #date-sort-selector button,
706
+ #view-sort-selector button {
623
707
  background: none;
624
708
  border-radius: 15px;
625
709
  color: #404142;
@@ -632,7 +716,8 @@ export class SortFilterBar
632
716
  padding: 0.5rem 1.2rem;
633
717
  }
634
718
 
635
- #date-sort-selector button.selected {
719
+ #date-sort-selector button.selected,
720
+ #view-sort-selector button.selected {
636
721
  background-color: #404142;
637
722
  color: white;
638
723
  }
@@ -679,7 +764,8 @@ export class SortFilterBar
679
764
  display: none;
680
765
  }
681
766
 
682
- #date-sort-selector-backdrop {
767
+ #date-sort-selector-backdrop,
768
+ #view-sort-selector-backdrop {
683
769
  position: fixed;
684
770
  top: 0;
685
771
  left: 0;
@@ -1,6 +1,8 @@
1
1
  /* eslint-disable import/no-duplicates */
2
2
  import { expect, fixture } from '@open-wc/testing';
3
3
  import { html } from 'lit';
4
+ import sinon from 'sinon';
5
+ import type { InfiniteScroller } from '@internetarchive/infinite-scroller';
4
6
  import type { CollectionBrowser } from '../src/collection-browser';
5
7
  import '../src/collection-browser';
6
8
  import { MockSearchService } from './mocks/mock-search-service';
@@ -59,4 +61,45 @@ describe('Collection Browser', () => {
59
61
  'boop',
60
62
  ]);
61
63
  });
64
+ it('refreshes when certain properties change', async () => {
65
+ const searchService = new MockSearchService();
66
+ const collectionNameCache = new MockCollectionNameCache();
67
+ const el = await fixture<CollectionBrowser>(
68
+ html`<collection-browser
69
+ .searchService=${searchService}
70
+ .collectionNameCache=${collectionNameCache}
71
+ ></collection-browser>`
72
+ );
73
+ const infiniteScrollerRefreshSpy = sinon.spy();
74
+
75
+ const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');
76
+ (infiniteScroller as InfiniteScroller).reload = infiniteScrollerRefreshSpy;
77
+ expect(infiniteScrollerRefreshSpy.called).to.be.false;
78
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(0);
79
+
80
+ // testing: `loggedIn`
81
+ el.loggedIn = true;
82
+ await el.updateComplete;
83
+ expect(infiniteScrollerRefreshSpy.called).to.be.true;
84
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(1);
85
+
86
+ el.loggedIn = false;
87
+ await el.updateComplete;
88
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(2);
89
+
90
+ // testing: `displayMode`
91
+ el.displayMode = 'list-compact';
92
+ await el.updateComplete;
93
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(3);
94
+
95
+ // testing: `baseNavigationUrl`
96
+ el.baseNavigationUrl = 'https://funtestsite.com';
97
+ await el.updateComplete;
98
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(4);
99
+
100
+ // testing: `baseImageUrl`
101
+ el.baseImageUrl = 'https://funtestsiteforimages.com';
102
+ await el.updateComplete;
103
+ expect(infiniteScrollerRefreshSpy.callCount).to.equal(5);
104
+ });
62
105
  });
@@ -0,0 +1,113 @@
1
+ /* eslint-disable import/no-duplicates */
2
+ import { expect, fixture, oneEvent } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import type { MoreFacetsContent } from '../../src/collection-facets/more-facets-content';
5
+ import '../../src/collection-facets/more-facets-content';
6
+ import { MockSearchService } from '../mocks/mock-search-service';
7
+
8
+ describe('More facets content', () => {
9
+ it('should render more facets template', async () => {
10
+ const el = await fixture<MoreFacetsContent>(
11
+ html`<more-facets-content></more-facets-content>`
12
+ );
13
+
14
+ el.facetsLoading = false;
15
+ await el.updateComplete;
16
+
17
+ expect(el.shadowRoot?.querySelector('.facets-content')).to.exist;
18
+ });
19
+
20
+ it('should render more facets loader template', async () => {
21
+ const el = await fixture<MoreFacetsContent>(
22
+ html`<more-facets-content></more-facets-content>`
23
+ );
24
+
25
+ el.facetsLoading = true;
26
+ await el.updateComplete;
27
+
28
+ expect(el.shadowRoot?.querySelector('.facets-loader')).to.exist;
29
+ });
30
+
31
+ it('should render more facets empty template', async () => {
32
+ const el = await fixture<MoreFacetsContent>(
33
+ html`<more-facets-content></more-facets-content>`
34
+ );
35
+
36
+ el.facetsLoading = false;
37
+ el.paginationSize = 0;
38
+ await el.updateComplete;
39
+
40
+ expect(
41
+ el.shadowRoot?.querySelector('#more-facets-page')?.textContent
42
+ ).to.contains('No result found. please try again later.');
43
+ });
44
+
45
+ it('should render pagination for more facets', async () => {
46
+ const searchService = new MockSearchService();
47
+
48
+ const el = await fixture<MoreFacetsContent>(
49
+ html`<more-facets-content
50
+ .searchService=${searchService}
51
+ ></more-facets-content>`
52
+ );
53
+
54
+ el.facetKey = 'mediatype';
55
+ el.facetsLoading = false;
56
+ el.paginationSize = 6;
57
+ await el.updateComplete;
58
+
59
+ expect(el.shadowRoot?.querySelectorAll('more-facets-pagination')).to.exist;
60
+ });
61
+
62
+ it('query for more facets content using search service', async () => {
63
+ const searchService = new MockSearchService();
64
+
65
+ const el = await fixture<MoreFacetsContent>(
66
+ html`<more-facets-content
67
+ .searchService=${searchService}
68
+ ></more-facets-content>`
69
+ );
70
+
71
+ el.facetKey = 'collection';
72
+ el.fullQuery = 'title:hello';
73
+ await el.updateComplete;
74
+
75
+ expect(searchService.searchParams?.query).to.equal('title:hello');
76
+ });
77
+
78
+ it('query for specific facets data', async () => {
79
+ const searchService = new MockSearchService();
80
+
81
+ const el = await fixture<MoreFacetsContent>(
82
+ html`<more-facets-content
83
+ .searchService=${searchService}
84
+ ></more-facets-content>`
85
+ );
86
+
87
+ el.facetKey = 'language';
88
+ el.facetsLoading = false;
89
+ await el.updateComplete;
90
+
91
+ expect(el.paginationSize).to.equal(1);
92
+ expect(el.shadowRoot?.querySelector('.facet-list')).to.exist;
93
+ expect(Object.keys(el.castedBuckets as []).length).to.equal(7);
94
+ });
95
+
96
+ it('page number clicked event', async () => {
97
+ const searchService = new MockSearchService();
98
+
99
+ const el = await fixture<MoreFacetsContent>(
100
+ html`<more-facets-content
101
+ .searchService=${searchService}
102
+ ></more-facets-content>`
103
+ );
104
+
105
+ setTimeout(() =>
106
+ el.dispatchEvent(
107
+ new CustomEvent('pageNumberClicked', { detail: { page: 15 } })
108
+ )
109
+ );
110
+ const { detail } = await oneEvent(el, 'pageNumberClicked');
111
+ expect(detail?.page).to.equal(15);
112
+ });
113
+ });
@@ -0,0 +1,70 @@
1
+ /* eslint-disable import/no-duplicates */
2
+ import { expect, fixture } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import type { MoreFacetsPagination } from '../../src/collection-facets/more-facets-pagination';
5
+ import '../../src/collection-facets/more-facets-pagination';
6
+
7
+ describe('More facets pagination', () => {
8
+ it('should render pagination container', async () => {
9
+ const el = await fixture<MoreFacetsPagination>(
10
+ html`<more-facets-pagination></more-facets-pagination>`
11
+ );
12
+
13
+ expect(el.shadowRoot?.querySelector('.facets-pagination')).to.exist;
14
+ });
15
+
16
+ it('should render pagination arrow icon', async () => {
17
+ const el = await fixture<MoreFacetsPagination>(
18
+ html`<more-facets-pagination></more-facets-pagination>`
19
+ );
20
+
21
+ expect(
22
+ el.shadowRoot
23
+ ?.querySelectorAll('.arrow-icon')[0]
24
+ ?.querySelector('svg')
25
+ ?.querySelector('title')?.textContent
26
+ ).to.equal('Go left icon');
27
+ });
28
+
29
+ it('should render pagination right arrow icon', async () => {
30
+ const el = await fixture<MoreFacetsPagination>(
31
+ html`<more-facets-pagination></more-facets-pagination>`
32
+ );
33
+
34
+ expect(
35
+ el.shadowRoot
36
+ ?.querySelectorAll('.arrow-icon')[1]
37
+ ?.querySelector('svg')
38
+ ?.querySelector('title')?.textContent
39
+ ).to.equal('Go right icon');
40
+ });
41
+
42
+ it('should render pagination pages', async () => {
43
+ const el = await fixture<MoreFacetsPagination>(
44
+ html`<more-facets-pagination></more-facets-pagination>`
45
+ );
46
+
47
+ el.size = 2;
48
+ await el.updateComplete;
49
+
50
+ // at a time we render 5 pages
51
+ expect(
52
+ el.shadowRoot?.querySelector('.page-numbers')?.children.length
53
+ ).to.equal(5);
54
+ });
55
+
56
+ it('should render current page as active page', async () => {
57
+ const el = await fixture<MoreFacetsPagination>(
58
+ html`<more-facets-pagination></more-facets-pagination>`
59
+ );
60
+
61
+ el.size = 2;
62
+ el.currentPage = 3;
63
+ await el.updateComplete;
64
+
65
+ expect(
66
+ el.shadowRoot?.querySelector('.page-numbers')?.querySelector('.current')
67
+ ?.textContent
68
+ ).to.contains(3);
69
+ });
70
+ });