@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.
- package/dist/src/app-root.js +1 -0
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +6 -2
- package/dist/src/collection-browser.js +20 -14
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets.js +21 -5
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/models.d.ts +0 -1
- package/dist/src/models.js +0 -8
- package/dist/src/models.js.map +1 -1
- package/dist/test/collection-browser.test.js +59 -14
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets.test.d.ts +1 -0
- package/dist/test/collection-facets.test.js +119 -0
- package/dist/test/collection-facets.test.js.map +1 -0
- package/package.json +1 -1
- package/src/app-root.ts +1 -0
- package/src/collection-browser.ts +19 -14
- package/src/collection-facets.ts +21 -5
- package/src/models.ts +0 -9
- package/test/collection-browser.test.ts +75 -14
- package/test/collection-facets.test.ts +163 -0
|
@@ -7,12 +7,13 @@ import type { CollectionBrowser } from '../src/collection-browser';
|
|
|
7
7
|
import '../src/collection-browser';
|
|
8
8
|
import {
|
|
9
9
|
defaultSelectedFacets,
|
|
10
|
-
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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('
|
|
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
|
-
|
|
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('
|
|
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
|
-
|
|
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
|
+
});
|