@internetarchive/collection-browser 0.2.20-alpha.1 → 0.2.21

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.
@@ -7,12 +7,13 @@ import type { CollectionBrowser } from '../src/collection-browser';
7
7
  import '../src/collection-browser';
8
8
  import {
9
9
  defaultSelectedFacets,
10
- mockedSelectedFacets,
10
+ SelectedFacets,
11
11
  SortField,
12
12
  } from '../src/models';
13
13
  import { MockSearchService } from './mocks/mock-search-service';
14
14
  import { MockCollectionNameCache } from './mocks/mock-collection-name-cache';
15
15
  import { MockAnalyticsHandler } from './mocks/mock-analytics-handler';
16
+ import { analyticsCategories } from '../src/utils/analytics-events';
16
17
 
17
18
  describe('Collection Browser', () => {
18
19
  it('clear existing filter for facets & sort-bar', async () => {
@@ -32,6 +33,30 @@ describe('Collection Browser', () => {
32
33
  expect(el.selectedTitleFilter).to.null;
33
34
  });
34
35
 
36
+ it('filterBy creator with analytics', async () => {
37
+ const mockAnalyticsHandler = new MockAnalyticsHandler();
38
+ const el = await fixture<CollectionBrowser>(
39
+ html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>
40
+ </collection-browser>`
41
+ );
42
+
43
+ el.searchContext = 'betaSearchService';
44
+ el.selectedCreatorFilter = 'A';
45
+ await el.updateComplete;
46
+
47
+ expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');
48
+ expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');
49
+ expect(mockAnalyticsHandler.callLabel).to.equal('start-A');
50
+
51
+ el.clearFilters();
52
+ await el.updateComplete;
53
+
54
+ expect(el.selectedTitleFilter).to.null;
55
+ expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');
56
+ expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');
57
+ expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');
58
+ });
59
+
35
60
  it('filterBy title with analytics', async () => {
36
61
  const mockAnalyticsHandler = new MockAnalyticsHandler();
37
62
  const el = await fixture<CollectionBrowser>(
@@ -39,11 +64,12 @@ describe('Collection Browser', () => {
39
64
  </collection-browser>`
40
65
  );
41
66
 
67
+ el.searchContext = 'beta-search-service';
42
68
  el.selectedSort = 'title' as SortField;
43
69
  el.selectedTitleFilter = 'A';
44
70
  await el.updateComplete;
45
71
 
46
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
72
+ expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');
47
73
  expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');
48
74
  expect(mockAnalyticsHandler.callLabel).to.equal('start-A');
49
75
 
@@ -51,51 +77,71 @@ describe('Collection Browser', () => {
51
77
  await el.updateComplete;
52
78
 
53
79
  expect(el.selectedTitleFilter).to.null;
54
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
80
+ expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');
55
81
  expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');
56
82
  expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');
57
83
  });
58
84
 
59
85
  it('selected facets with analytics - not negative facets', async () => {
60
86
  const mockAnalyticsHandler = new MockAnalyticsHandler();
87
+ const mockedSelectedFacets: SelectedFacets = {
88
+ subject: {},
89
+ mediatype: { data: 'selected' },
90
+ language: {},
91
+ creator: {},
92
+ collection: {},
93
+ year: {},
94
+ };
95
+
61
96
  const el = await fixture<CollectionBrowser>(
62
97
  html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>
63
98
  </collection-browser>`
64
99
  );
65
100
 
101
+ el.searchContext = 'search-service';
66
102
  el.selectedFacets = mockedSelectedFacets;
67
103
  await el.updateComplete;
68
104
 
69
105
  el.facetClickHandler('mediatype', true, false);
70
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
106
+ expect(mockAnalyticsHandler.callCategory).to.equal('search-service');
71
107
  expect(mockAnalyticsHandler.callAction).to.equal('facetSelected');
72
108
  expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');
73
109
 
74
110
  el.facetClickHandler('mediatype', false, false);
75
111
  expect(el.selectedFacets).to.equal(mockedSelectedFacets);
76
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
112
+ expect(mockAnalyticsHandler.callCategory).to.equal('search-service');
77
113
  expect(mockAnalyticsHandler.callAction).to.equal('facetDeselected');
78
114
  expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');
79
115
  });
80
116
 
81
117
  it('selected facets with analytics - negative facets', async () => {
82
118
  const mockAnalyticsHandler = new MockAnalyticsHandler();
119
+ const mockedSelectedFacets: SelectedFacets = {
120
+ subject: {},
121
+ mediatype: { data: 'selected' },
122
+ language: {},
123
+ creator: {},
124
+ collection: {},
125
+ year: {},
126
+ };
127
+
83
128
  const el = await fixture<CollectionBrowser>(
84
129
  html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>
85
130
  </collection-browser>`
86
131
  );
87
132
 
133
+ el.searchContext = 'beta-search-service';
88
134
  el.selectedFacets = mockedSelectedFacets;
89
135
  await el.updateComplete;
90
136
 
91
137
  el.facetClickHandler('mediatype', true, true);
92
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
138
+ expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');
93
139
  expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeSelected');
94
140
  expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');
95
141
 
96
142
  el.facetClickHandler('mediatype', false, true);
97
143
  expect(el.selectedFacets).to.equal(mockedSelectedFacets);
98
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
144
+ expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');
99
145
  expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeDeselected');
100
146
  expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');
101
147
  });
@@ -120,9 +166,8 @@ describe('Collection Browser', () => {
120
166
  const searchService = new MockSearchService();
121
167
 
122
168
  const el = await fixture<CollectionBrowser>(
123
- html`<collection-browser
124
- .searchService=${searchService}
125
- ></collection-browser>`
169
+ html`<collection-browser .searchService=${searchService}>
170
+ </collection-browser>`
126
171
  );
127
172
 
128
173
  el.baseQuery = 'collection:foo';
@@ -187,10 +232,11 @@ describe('Collection Browser', () => {
187
232
 
188
233
  // testing: `displayMode`
189
234
  el.displayMode = 'list-compact';
235
+ el.searchContext = 'beta-search';
190
236
  await el.updateComplete;
191
237
  expect(infiniteScrollerRefreshSpy.callCount).to.equal(3);
192
238
 
193
- expect(mockAnalyticsHandler.callCategory).to.equal('collection-browser');
239
+ expect(mockAnalyticsHandler.callCategory).to.equal('beta-search');
194
240
  expect(mockAnalyticsHandler.callAction).to.equal('displayMode');
195
241
  expect(mockAnalyticsHandler.callLabel).to.equal('list-compact');
196
242
 
@@ -217,9 +263,8 @@ describe('Collection Browser', () => {
217
263
  const searchService = new MockSearchService();
218
264
 
219
265
  const el = await fixture<CollectionBrowser>(
220
- html`<collection-browser
221
- .searchService=${searchService}
222
- ></collection-browser>`
266
+ html`<collection-browser .searchService=${searchService}>
267
+ </collection-browser>`
223
268
  );
224
269
 
225
270
  el.baseQuery = 'single-result';
@@ -229,4 +274,20 @@ describe('Collection Browser', () => {
229
274
  el.shadowRoot?.querySelector('#big-results-label')?.textContent
230
275
  ).to.contains('Result');
231
276
  });
277
+
278
+ it('`searchContext` prop helps describe where component is being used', async () => {
279
+ const el = await fixture<CollectionBrowser>(
280
+ html`<collection-browser></collection-browser>`
281
+ );
282
+
283
+ expect(el.searchContext).to.equal(analyticsCategories.default);
284
+
285
+ el.searchContext = 'unicorn-search';
286
+ await el.updateComplete;
287
+
288
+ expect(el.searchContext).to.equal('unicorn-search');
289
+
290
+ // property is reflected as attribute
291
+ expect(el.getAttribute('searchcontext')).to.equal('unicorn-search');
292
+ });
232
293
  });
@@ -0,0 +1,163 @@
1
+ /* eslint-disable import/no-duplicates */
2
+ import { expect, fixture } from '@open-wc/testing';
3
+ import { html } from 'lit';
4
+ import type { Aggregation } from '@internetarchive/search-service';
5
+ import type { CollectionFacets } from '../src/collection-facets';
6
+ import '../src/collection-facets';
7
+
8
+ describe('Collection Facets', () => {
9
+ it('renders aggregations as facets', async () => {
10
+ const el = await fixture<CollectionFacets>(
11
+ html`<collection-facets></collection-facets>`
12
+ );
13
+
14
+ const aggs: Record<string, Aggregation> = {
15
+ 'user_aggs__terms__field:subjectSorter__size:1': {
16
+ buckets: [
17
+ {
18
+ key: 'foo',
19
+ doc_count: 5,
20
+ },
21
+ ],
22
+ },
23
+ };
24
+
25
+ el.aggregations = aggs;
26
+ await el.updateComplete;
27
+
28
+ const facetGroups = el.shadowRoot?.querySelectorAll('.facet-group');
29
+ expect(facetGroups?.length).to.equal(1);
30
+
31
+ const titleFacetGroup = facetGroups?.[0];
32
+ const facetGroupHeader = titleFacetGroup?.querySelector('h1');
33
+ expect(facetGroupHeader?.textContent?.trim()).to.equal('Subject');
34
+
35
+ const titleFacetRow = titleFacetGroup?.querySelector('.facet-row');
36
+ expect(titleFacetRow?.textContent?.trim()).to.satisfy((text: string) =>
37
+ /^foo\s*5$/.test(text)
38
+ );
39
+ });
40
+
41
+ it('renders multiple aggregation types', async () => {
42
+ const el = await fixture<CollectionFacets>(
43
+ html`<collection-facets></collection-facets>`
44
+ );
45
+
46
+ const aggs: Record<string, Aggregation> = {
47
+ 'user_aggs__terms__field:subjectSorter__size:1': {
48
+ buckets: [
49
+ {
50
+ key: 'foo',
51
+ doc_count: 5,
52
+ },
53
+ ],
54
+ },
55
+ 'user_aggs__terms__field:mediatypeSorter__size:1': {
56
+ buckets: [
57
+ {
58
+ key: 'bar',
59
+ doc_count: 10,
60
+ },
61
+ ],
62
+ },
63
+ };
64
+
65
+ el.aggregations = aggs;
66
+ await el.updateComplete;
67
+
68
+ const facetGroups = el.shadowRoot?.querySelectorAll('.facet-group');
69
+ expect(facetGroups?.length).to.equal(2);
70
+ });
71
+
72
+ it('renders collection facets as links', async () => {
73
+ const el = await fixture<CollectionFacets>(
74
+ html`<collection-facets></collection-facets>`
75
+ );
76
+
77
+ const aggs: Record<string, Aggregation> = {
78
+ 'user_aggs__terms__field:collection__size:1': {
79
+ buckets: [
80
+ {
81
+ key: 'foo',
82
+ doc_count: 5,
83
+ },
84
+ ],
85
+ },
86
+ };
87
+
88
+ el.aggregations = aggs;
89
+ await el.updateComplete;
90
+
91
+ const collectionName = el.shadowRoot?.querySelector(
92
+ 'async-collection-name'
93
+ );
94
+ expect(collectionName?.parentElement).to.be.instanceOf(HTMLAnchorElement);
95
+ expect(collectionName?.parentElement?.getAttribute('href')).to.equal(
96
+ '/details/foo'
97
+ );
98
+ });
99
+
100
+ it('renders non-collection facets without links', async () => {
101
+ const el = await fixture<CollectionFacets>(
102
+ html`<collection-facets></collection-facets>`
103
+ );
104
+
105
+ const aggs: Record<string, Aggregation> = {
106
+ 'user_aggs__terms__field:subjectSorter__size:1': {
107
+ buckets: [
108
+ {
109
+ key: 'foo',
110
+ doc_count: 5,
111
+ },
112
+ ],
113
+ },
114
+ };
115
+
116
+ el.aggregations = aggs;
117
+ await el.updateComplete;
118
+
119
+ const collectionName = el.shadowRoot?.querySelector(
120
+ 'async-collection-name'
121
+ );
122
+ expect(collectionName?.parentElement).to.not.be.instanceOf(
123
+ HTMLAnchorElement
124
+ );
125
+ });
126
+
127
+ it('toggles selected facets on click', async () => {
128
+ const el = await fixture<CollectionFacets>(
129
+ html`<collection-facets></collection-facets>`
130
+ );
131
+
132
+ const aggs: Record<string, Aggregation> = {
133
+ 'user_aggs__terms__field:subjectSorter__size:1': {
134
+ buckets: [
135
+ {
136
+ key: 'foo',
137
+ doc_count: 5,
138
+ },
139
+ ],
140
+ },
141
+ };
142
+
143
+ el.aggregations = aggs;
144
+ await el.updateComplete;
145
+
146
+ const checkbox = el.shadowRoot?.querySelector(
147
+ '.select-facet-checkbox'
148
+ ) as HTMLInputElement;
149
+ expect(checkbox.checked).to.be.false;
150
+
151
+ // Select the facet
152
+ checkbox?.click();
153
+ await el.updateComplete;
154
+
155
+ expect(el.selectedFacets?.subject.foo).to.equal('selected');
156
+
157
+ // Unselect the facet
158
+ checkbox?.click();
159
+ await el.updateComplete;
160
+
161
+ expect(el.selectedFacets?.subject.foo).to.be.undefined;
162
+ });
163
+ });