@internetarchive/collection-browser 3.3.3 → 3.3.4-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.
- package/dist/src/collection-browser.d.ts +11 -2
- package/dist/src/collection-browser.js +840 -693
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/facet-row.js +141 -140
- package/dist/src/collection-facets/facet-row.js.map +1 -1
- package/dist/src/collection-facets/models.js.map +1 -1
- package/dist/src/collection-facets.js +12 -0
- package/dist/src/collection-facets.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source-interface.d.ts +10 -1
- package/dist/src/data-source/collection-browser-data-source-interface.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.d.ts +19 -1
- package/dist/src/data-source/collection-browser-data-source.js +36 -18
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/data-source/collection-browser-query-state.d.ts +1 -2
- package/dist/src/data-source/collection-browser-query-state.js.map +1 -1
- package/dist/src/data-source/models.d.ts +11 -0
- package/dist/src/data-source/models.js.map +1 -1
- package/dist/src/manage/manage-bar.js +77 -77
- package/dist/src/manage/manage-bar.js.map +1 -1
- package/dist/src/models.d.ts +2 -6
- package/dist/src/models.js +8 -12
- package/dist/src/models.js.map +1 -1
- package/dist/src/restoration-state-handler.d.ts +1 -2
- package/dist/src/restoration-state-handler.js +3 -9
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/tiles/grid/search-tile.js +42 -42
- package/dist/src/tiles/grid/search-tile.js.map +1 -1
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js +119 -119
- package/dist/src/tiles/grid/styles/tile-grid-shared-styles.js.map +1 -1
- package/dist/test/collection-browser.test.js +19 -9
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/collection-facets/facet-row.test.js +23 -23
- package/dist/test/collection-facets/facet-row.test.js.map +1 -1
- package/dist/test/collection-facets.test.js +20 -20
- package/dist/test/collection-facets.test.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +5 -37
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/package.json +1 -1
- package/src/collection-browser.ts +3002 -2829
- package/src/collection-facets/facet-row.ts +299 -296
- package/src/collection-facets/models.ts +10 -10
- package/src/collection-facets.ts +11 -0
- package/src/data-source/collection-browser-data-source-interface.ts +345 -333
- package/src/data-source/collection-browser-data-source.ts +59 -19
- package/src/data-source/collection-browser-query-state.ts +1 -7
- package/src/data-source/models.ts +13 -0
- package/src/manage/manage-bar.ts +247 -247
- package/src/models.ts +866 -870
- package/src/restoration-state-handler.ts +542 -544
- package/src/tiles/grid/search-tile.ts +90 -90
- package/src/tiles/grid/styles/tile-grid-shared-styles.ts +130 -130
- package/test/collection-browser.test.ts +21 -11
- package/test/collection-facets/facet-row.test.ts +375 -375
- package/test/collection-facets.test.ts +928 -928
- package/test/restoration-state-handler.test.ts +480 -510
|
@@ -1,375 +1,375 @@
|
|
|
1
|
-
import { expect, fixture } from '@open-wc/testing';
|
|
2
|
-
import sinon from 'sinon';
|
|
3
|
-
import { html } from 'lit';
|
|
4
|
-
import type { FacetRow } from '../../src/collection-facets/facet-row';
|
|
5
|
-
import '../../src/collection-facets/facet-row';
|
|
6
|
-
import type { FacetState } from '../../src/models';
|
|
7
|
-
|
|
8
|
-
describe('Facet row', () => {
|
|
9
|
-
it('renders nothing if no bucket provided', async () => {
|
|
10
|
-
const el = await fixture<FacetRow>(
|
|
11
|
-
html`<facet-row .facetType=${'subject'}></facet-row>`,
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
expect(el.shadowRoot?.querySelector('.facet-row-container')).not.to.exist;
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('renders nothing if no facet type provided', async () => {
|
|
18
|
-
const bucket = {
|
|
19
|
-
key: 'foo',
|
|
20
|
-
state: 'none' as FacetState,
|
|
21
|
-
count: 5,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const el = await fixture<FacetRow>(
|
|
25
|
-
html`<facet-row .bucket=${bucket}></facet-row>`,
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
expect(el.shadowRoot?.querySelector('.facet-row-container')).not.to.exist;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('renders provided bucket as facet row', async () => {
|
|
32
|
-
const bucket = {
|
|
33
|
-
key: 'foo',
|
|
34
|
-
state: 'none' as FacetState,
|
|
35
|
-
count: 5,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const el = await fixture<FacetRow>(
|
|
39
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
expect(el.shadowRoot?.querySelector('.facet-row-container')).to.exist;
|
|
43
|
-
expect(
|
|
44
|
-
el.shadowRoot?.querySelectorAll('input[type="checkbox"]'),
|
|
45
|
-
).to.have.length(2);
|
|
46
|
-
expect(el.shadowRoot?.querySelectorAll('label')).to.have.length(2);
|
|
47
|
-
|
|
48
|
-
const labelText = el.shadowRoot?.querySelector('.facet-info-display');
|
|
49
|
-
expect(labelText?.textContent?.trim()).to.match(/^foo\s*5$/);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('renders locale-appropriate facet count', async () => {
|
|
53
|
-
const bucket = {
|
|
54
|
-
key: 'foo',
|
|
55
|
-
state: 'none' as FacetState,
|
|
56
|
-
count: 54321,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const el = await fixture<FacetRow>(
|
|
60
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const facetCount = el.shadowRoot?.querySelector('.facet-count');
|
|
64
|
-
expect(facetCount?.textContent).to.equal('54,321');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('renders selected facets with checked checkbox', async () => {
|
|
68
|
-
const bucket = {
|
|
69
|
-
key: 'foo',
|
|
70
|
-
state: 'selected' as FacetState,
|
|
71
|
-
count: 5,
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const el = await fixture<FacetRow>(
|
|
75
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// "Positive" checkbox is checked; "Negative" checkbox is not checked
|
|
79
|
-
const selectCheckbox = el.shadowRoot?.querySelector(
|
|
80
|
-
'.select-facet-checkbox',
|
|
81
|
-
) as HTMLInputElement;
|
|
82
|
-
const hideCheckbox = el.shadowRoot?.querySelector(
|
|
83
|
-
'.hide-facet-checkbox',
|
|
84
|
-
) as HTMLInputElement;
|
|
85
|
-
expect(selectCheckbox?.checked).to.be.true;
|
|
86
|
-
expect(hideCheckbox?.checked).to.be.false;
|
|
87
|
-
|
|
88
|
-
// Eye icon is not in its active state
|
|
89
|
-
expect(
|
|
90
|
-
el.shadowRoot?.querySelector('.hide-facet-icon'),
|
|
91
|
-
).to.exist.and.satisfy(
|
|
92
|
-
(icon: HTMLElement) => !icon.classList.contains('active'),
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('renders hidden facets with closed eye icon', async () => {
|
|
97
|
-
const bucket = {
|
|
98
|
-
key: 'foo',
|
|
99
|
-
state: 'hidden' as FacetState,
|
|
100
|
-
count: 5,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const el = await fixture<FacetRow>(
|
|
104
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
// "Positive" checkbox is not checked; "Negative" checkbox is checked
|
|
108
|
-
const selectCheckbox = el.shadowRoot?.querySelector(
|
|
109
|
-
'.select-facet-checkbox',
|
|
110
|
-
) as HTMLInputElement;
|
|
111
|
-
const hideCheckbox = el.shadowRoot?.querySelector(
|
|
112
|
-
'.hide-facet-checkbox',
|
|
113
|
-
) as HTMLInputElement;
|
|
114
|
-
expect(selectCheckbox?.checked).to.be.false;
|
|
115
|
-
expect(hideCheckbox?.checked).to.be.true;
|
|
116
|
-
|
|
117
|
-
// Eye icon is in its "active" state
|
|
118
|
-
expect(
|
|
119
|
-
el.shadowRoot?.querySelector('.hide-facet-icon'),
|
|
120
|
-
).to.exist.and.satisfy((icon: HTMLElement) =>
|
|
121
|
-
icon.classList.contains('active'),
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('renders correct accessible label for unchecked negative facets', async () => {
|
|
126
|
-
const bucket = {
|
|
127
|
-
key: 'foo',
|
|
128
|
-
state: 'none' as FacetState,
|
|
129
|
-
count: 5,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
const el = await fixture<FacetRow>(
|
|
133
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
const hideFacetLabel = el.shadowRoot?.querySelector('.hide-facet-icon');
|
|
137
|
-
expect(hideFacetLabel?.textContent?.trim()).to.match(/^Hide subject: foo$/);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('renders correct accessible label for checked negative facets', async () => {
|
|
141
|
-
const bucket = {
|
|
142
|
-
key: 'foo',
|
|
143
|
-
state: 'hidden' as FacetState,
|
|
144
|
-
count: 5,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
const el = await fixture<FacetRow>(
|
|
148
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const hideFacetLabel = el.shadowRoot?.querySelector('.hide-facet-icon');
|
|
152
|
-
expect(hideFacetLabel?.textContent?.trim()).to.match(
|
|
153
|
-
/^Unhide subject: foo$/,
|
|
154
|
-
);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('renders collection facets as links', async () => {
|
|
158
|
-
const bucket = {
|
|
159
|
-
key: 'foo',
|
|
160
|
-
state: 'none' as FacetState,
|
|
161
|
-
count: 5,
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
const el = await fixture<FacetRow>(
|
|
165
|
-
html`<facet-row
|
|
166
|
-
.facetType=${'collection'}
|
|
167
|
-
.bucket=${bucket}
|
|
168
|
-
></facet-row>`,
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
const collectionName = el.shadowRoot?.querySelector(
|
|
172
|
-
'.facet-title > a:link',
|
|
173
|
-
);
|
|
174
|
-
expect(collectionName).to.exist;
|
|
175
|
-
expect(collectionName?.getAttribute('href')).to.equal('/details/foo');
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('does not render non-collection facets as links', async () => {
|
|
179
|
-
const bucket = {
|
|
180
|
-
key: 'foo',
|
|
181
|
-
state: 'none' as FacetState,
|
|
182
|
-
count: 5,
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const el = await fixture<FacetRow>(
|
|
186
|
-
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
expect(el.shadowRoot?.querySelector('a:link')).not.to.exist;
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
it('emits event when facet checkbox is clicked', async () => {
|
|
193
|
-
const facetClickSpy = sinon.spy();
|
|
194
|
-
const bucket = {
|
|
195
|
-
key: 'foo',
|
|
196
|
-
state: 'none' as FacetState,
|
|
197
|
-
count: 5,
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
const el = await fixture<FacetRow>(
|
|
201
|
-
html`<facet-row
|
|
202
|
-
.facetType=${'subject'}
|
|
203
|
-
.bucket=${bucket}
|
|
204
|
-
@facetClick=${facetClickSpy}
|
|
205
|
-
></facet-row>`,
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const positiveFacetCheck = el.shadowRoot?.querySelector(
|
|
209
|
-
'.select-facet-checkbox',
|
|
210
|
-
) as HTMLInputElement;
|
|
211
|
-
expect(positiveFacetCheck).to.exist;
|
|
212
|
-
positiveFacetCheck.click();
|
|
213
|
-
|
|
214
|
-
expect(facetClickSpy.callCount).to.equal(1);
|
|
215
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
216
|
-
facetType: 'subject',
|
|
217
|
-
bucket: {
|
|
218
|
-
key: 'foo',
|
|
219
|
-
state: 'selected',
|
|
220
|
-
count: 5,
|
|
221
|
-
},
|
|
222
|
-
negative: false,
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('emits event when facet checkbox is unchecked', async () => {
|
|
227
|
-
const facetClickSpy = sinon.spy();
|
|
228
|
-
const bucket = {
|
|
229
|
-
key: 'foo',
|
|
230
|
-
state: 'selected' as FacetState,
|
|
231
|
-
count: 5,
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const el = await fixture<FacetRow>(
|
|
235
|
-
html`<facet-row
|
|
236
|
-
.facetType=${'subject'}
|
|
237
|
-
.bucket=${bucket}
|
|
238
|
-
@facetClick=${facetClickSpy}
|
|
239
|
-
></facet-row>`,
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const positiveFacetCheck = el.shadowRoot?.querySelector(
|
|
243
|
-
'.select-facet-checkbox',
|
|
244
|
-
) as HTMLInputElement;
|
|
245
|
-
expect(positiveFacetCheck).to.exist;
|
|
246
|
-
positiveFacetCheck.click();
|
|
247
|
-
|
|
248
|
-
expect(facetClickSpy.callCount).to.equal(1);
|
|
249
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
250
|
-
facetType: 'subject',
|
|
251
|
-
bucket: {
|
|
252
|
-
key: 'foo',
|
|
253
|
-
state: 'none',
|
|
254
|
-
count: 5,
|
|
255
|
-
},
|
|
256
|
-
negative: false,
|
|
257
|
-
});
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('emits event when facet negative icon is clicked', async () => {
|
|
261
|
-
const facetClickSpy = sinon.spy();
|
|
262
|
-
const bucket = {
|
|
263
|
-
key: 'foo',
|
|
264
|
-
state: 'none' as FacetState,
|
|
265
|
-
count: 5,
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
const el = await fixture<FacetRow>(
|
|
269
|
-
html`<facet-row
|
|
270
|
-
.facetType=${'subject'}
|
|
271
|
-
.bucket=${bucket}
|
|
272
|
-
@facetClick=${facetClickSpy}
|
|
273
|
-
></facet-row>`,
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
const negativeFacetIcon = el.shadowRoot?.querySelector(
|
|
277
|
-
'.hide-facet-icon',
|
|
278
|
-
) as HTMLLabelElement;
|
|
279
|
-
expect(negativeFacetIcon).to.exist;
|
|
280
|
-
negativeFacetIcon.click();
|
|
281
|
-
|
|
282
|
-
expect(facetClickSpy.callCount).to.equal(1);
|
|
283
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
284
|
-
facetType: 'subject',
|
|
285
|
-
bucket: {
|
|
286
|
-
key: 'foo',
|
|
287
|
-
state: 'hidden',
|
|
288
|
-
count: 5,
|
|
289
|
-
},
|
|
290
|
-
negative: true,
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it('emits event when facet negative icon is unchecked', async () => {
|
|
295
|
-
const facetClickSpy = sinon.spy();
|
|
296
|
-
const bucket = {
|
|
297
|
-
key: 'foo',
|
|
298
|
-
state: 'hidden' as FacetState,
|
|
299
|
-
count: 5,
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
const el = await fixture<FacetRow>(
|
|
303
|
-
html`<facet-row
|
|
304
|
-
.facetType=${'subject'}
|
|
305
|
-
.bucket=${bucket}
|
|
306
|
-
@facetClick=${facetClickSpy}
|
|
307
|
-
></facet-row>`,
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
const negativeFacetIcon = el.shadowRoot?.querySelector(
|
|
311
|
-
'.hide-facet-icon',
|
|
312
|
-
) as HTMLLabelElement;
|
|
313
|
-
expect(negativeFacetIcon).to.exist;
|
|
314
|
-
negativeFacetIcon.click();
|
|
315
|
-
|
|
316
|
-
expect(facetClickSpy.callCount).to.equal(1);
|
|
317
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
318
|
-
facetType: 'subject',
|
|
319
|
-
bucket: {
|
|
320
|
-
key: 'foo',
|
|
321
|
-
state: 'none',
|
|
322
|
-
count: 5,
|
|
323
|
-
},
|
|
324
|
-
negative: true,
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it('selects/deselects facet when label is clicked', async () => {
|
|
329
|
-
const facetClickSpy = sinon.spy();
|
|
330
|
-
const bucket = {
|
|
331
|
-
key: 'foo',
|
|
332
|
-
state: 'none' as FacetState,
|
|
333
|
-
count: 5,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const el = await fixture<FacetRow>(
|
|
337
|
-
html`<facet-row
|
|
338
|
-
.facetType=${'subject'}
|
|
339
|
-
.bucket=${bucket}
|
|
340
|
-
@facetClick=${facetClickSpy}
|
|
341
|
-
></facet-row>`,
|
|
342
|
-
);
|
|
343
|
-
|
|
344
|
-
const facetLabel = el.shadowRoot?.querySelector(
|
|
345
|
-
'.facet-info-display',
|
|
346
|
-
) as HTMLLabelElement;
|
|
347
|
-
expect(facetLabel).to.exist;
|
|
348
|
-
|
|
349
|
-
// Select facet by clicking label
|
|
350
|
-
facetLabel.click();
|
|
351
|
-
expect(facetClickSpy.callCount).to.equal(1);
|
|
352
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
353
|
-
facetType: 'subject',
|
|
354
|
-
bucket: {
|
|
355
|
-
key: 'foo',
|
|
356
|
-
state: 'selected',
|
|
357
|
-
count: 5,
|
|
358
|
-
},
|
|
359
|
-
negative: false,
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
// Deselect facet by clicking label
|
|
363
|
-
facetLabel.click();
|
|
364
|
-
expect(facetClickSpy.callCount).to.equal(2);
|
|
365
|
-
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
366
|
-
facetType: 'subject',
|
|
367
|
-
bucket: {
|
|
368
|
-
key: 'foo',
|
|
369
|
-
state: 'none',
|
|
370
|
-
count: 5,
|
|
371
|
-
},
|
|
372
|
-
negative: false,
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
});
|
|
1
|
+
import { expect, fixture } from '@open-wc/testing';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
import { html } from 'lit';
|
|
4
|
+
import type { FacetRow } from '../../src/collection-facets/facet-row';
|
|
5
|
+
import '../../src/collection-facets/facet-row';
|
|
6
|
+
import type { FacetState } from '../../src/models';
|
|
7
|
+
|
|
8
|
+
describe('Facet row', () => {
|
|
9
|
+
it('renders nothing if no bucket provided', async () => {
|
|
10
|
+
const el = await fixture<FacetRow>(
|
|
11
|
+
html`<facet-row .facetType=${'subject'}></facet-row>`,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(el.shadowRoot?.querySelector('.facet-row-container')).not.to.exist;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders nothing if no facet type provided', async () => {
|
|
18
|
+
const bucket = {
|
|
19
|
+
key: 'foo',
|
|
20
|
+
state: 'none' as FacetState,
|
|
21
|
+
count: 5,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const el = await fixture<FacetRow>(
|
|
25
|
+
html`<facet-row .bucket=${bucket}></facet-row>`,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(el.shadowRoot?.querySelector('.facet-row-container')).not.to.exist;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('renders provided bucket as facet row', async () => {
|
|
32
|
+
const bucket = {
|
|
33
|
+
key: 'foo',
|
|
34
|
+
state: 'none' as FacetState,
|
|
35
|
+
count: 5,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const el = await fixture<FacetRow>(
|
|
39
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
expect(el.shadowRoot?.querySelector('.facet-row-container')).to.exist;
|
|
43
|
+
expect(
|
|
44
|
+
el.shadowRoot?.querySelectorAll('input[type="checkbox"]'),
|
|
45
|
+
).to.have.length(2);
|
|
46
|
+
expect(el.shadowRoot?.querySelectorAll('label')).to.have.length(2);
|
|
47
|
+
|
|
48
|
+
const labelText = el.shadowRoot?.querySelector('.facet-info-display');
|
|
49
|
+
expect(labelText?.textContent?.trim()).to.match(/^foo\s*5$/);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('renders locale-appropriate facet count', async () => {
|
|
53
|
+
const bucket = {
|
|
54
|
+
key: 'foo',
|
|
55
|
+
state: 'none' as FacetState,
|
|
56
|
+
count: 54321,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const el = await fixture<FacetRow>(
|
|
60
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const facetCount = el.shadowRoot?.querySelector('.facet-count');
|
|
64
|
+
expect(facetCount?.textContent).to.equal('54,321');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('renders selected facets with checked checkbox', async () => {
|
|
68
|
+
const bucket = {
|
|
69
|
+
key: 'foo',
|
|
70
|
+
state: 'selected' as FacetState,
|
|
71
|
+
count: 5,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const el = await fixture<FacetRow>(
|
|
75
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// "Positive" checkbox is checked; "Negative" checkbox is not checked
|
|
79
|
+
const selectCheckbox = el.shadowRoot?.querySelector(
|
|
80
|
+
'.select-facet-checkbox',
|
|
81
|
+
) as HTMLInputElement;
|
|
82
|
+
const hideCheckbox = el.shadowRoot?.querySelector(
|
|
83
|
+
'.hide-facet-checkbox',
|
|
84
|
+
) as HTMLInputElement;
|
|
85
|
+
expect(selectCheckbox?.checked).to.be.true;
|
|
86
|
+
expect(hideCheckbox?.checked).to.be.false;
|
|
87
|
+
|
|
88
|
+
// Eye icon is not in its active state
|
|
89
|
+
expect(
|
|
90
|
+
el.shadowRoot?.querySelector('.hide-facet-icon'),
|
|
91
|
+
).to.exist.and.satisfy(
|
|
92
|
+
(icon: HTMLElement) => !icon.classList.contains('active'),
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('renders hidden facets with closed eye icon', async () => {
|
|
97
|
+
const bucket = {
|
|
98
|
+
key: 'foo',
|
|
99
|
+
state: 'hidden' as FacetState,
|
|
100
|
+
count: 5,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const el = await fixture<FacetRow>(
|
|
104
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// "Positive" checkbox is not checked; "Negative" checkbox is checked
|
|
108
|
+
const selectCheckbox = el.shadowRoot?.querySelector(
|
|
109
|
+
'.select-facet-checkbox',
|
|
110
|
+
) as HTMLInputElement;
|
|
111
|
+
const hideCheckbox = el.shadowRoot?.querySelector(
|
|
112
|
+
'.hide-facet-checkbox',
|
|
113
|
+
) as HTMLInputElement;
|
|
114
|
+
expect(selectCheckbox?.checked).to.be.false;
|
|
115
|
+
expect(hideCheckbox?.checked).to.be.true;
|
|
116
|
+
|
|
117
|
+
// Eye icon is in its "active" state
|
|
118
|
+
expect(
|
|
119
|
+
el.shadowRoot?.querySelector('.hide-facet-icon'),
|
|
120
|
+
).to.exist.and.satisfy((icon: HTMLElement) =>
|
|
121
|
+
icon.classList.contains('active'),
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('renders correct accessible label for unchecked negative facets', async () => {
|
|
126
|
+
const bucket = {
|
|
127
|
+
key: 'foo',
|
|
128
|
+
state: 'none' as FacetState,
|
|
129
|
+
count: 5,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const el = await fixture<FacetRow>(
|
|
133
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const hideFacetLabel = el.shadowRoot?.querySelector('.hide-facet-icon');
|
|
137
|
+
expect(hideFacetLabel?.textContent?.trim()).to.match(/^Hide subject: foo$/);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('renders correct accessible label for checked negative facets', async () => {
|
|
141
|
+
const bucket = {
|
|
142
|
+
key: 'foo',
|
|
143
|
+
state: 'hidden' as FacetState,
|
|
144
|
+
count: 5,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const el = await fixture<FacetRow>(
|
|
148
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const hideFacetLabel = el.shadowRoot?.querySelector('.hide-facet-icon');
|
|
152
|
+
expect(hideFacetLabel?.textContent?.trim()).to.match(
|
|
153
|
+
/^Unhide subject: foo$/,
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('renders collection facets as links', async () => {
|
|
158
|
+
const bucket = {
|
|
159
|
+
key: 'foo',
|
|
160
|
+
state: 'none' as FacetState,
|
|
161
|
+
count: 5,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const el = await fixture<FacetRow>(
|
|
165
|
+
html`<facet-row
|
|
166
|
+
.facetType=${'collection'}
|
|
167
|
+
.bucket=${bucket}
|
|
168
|
+
></facet-row>`,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const collectionName = el.shadowRoot?.querySelector(
|
|
172
|
+
'.facet-title > a:link',
|
|
173
|
+
);
|
|
174
|
+
expect(collectionName).to.exist;
|
|
175
|
+
expect(collectionName?.getAttribute('href')).to.equal('/details/foo');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('does not render non-collection facets as links', async () => {
|
|
179
|
+
const bucket = {
|
|
180
|
+
key: 'foo',
|
|
181
|
+
state: 'none' as FacetState,
|
|
182
|
+
count: 5,
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const el = await fixture<FacetRow>(
|
|
186
|
+
html`<facet-row .facetType=${'subject'} .bucket=${bucket}></facet-row>`,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
expect(el.shadowRoot?.querySelector('a:link')).not.to.exist;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('emits event when facet checkbox is clicked', async () => {
|
|
193
|
+
const facetClickSpy = sinon.spy();
|
|
194
|
+
const bucket = {
|
|
195
|
+
key: 'foo',
|
|
196
|
+
state: 'none' as FacetState,
|
|
197
|
+
count: 5,
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const el = await fixture<FacetRow>(
|
|
201
|
+
html`<facet-row
|
|
202
|
+
.facetType=${'subject'}
|
|
203
|
+
.bucket=${bucket}
|
|
204
|
+
@facetClick=${facetClickSpy}
|
|
205
|
+
></facet-row>`,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const positiveFacetCheck = el.shadowRoot?.querySelector(
|
|
209
|
+
'.select-facet-checkbox',
|
|
210
|
+
) as HTMLInputElement;
|
|
211
|
+
expect(positiveFacetCheck).to.exist;
|
|
212
|
+
positiveFacetCheck.click();
|
|
213
|
+
|
|
214
|
+
expect(facetClickSpy.callCount).to.equal(1);
|
|
215
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
216
|
+
facetType: 'subject',
|
|
217
|
+
bucket: {
|
|
218
|
+
key: 'foo',
|
|
219
|
+
state: 'selected',
|
|
220
|
+
count: 5,
|
|
221
|
+
},
|
|
222
|
+
negative: false,
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('emits event when facet checkbox is unchecked', async () => {
|
|
227
|
+
const facetClickSpy = sinon.spy();
|
|
228
|
+
const bucket = {
|
|
229
|
+
key: 'foo',
|
|
230
|
+
state: 'selected' as FacetState,
|
|
231
|
+
count: 5,
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const el = await fixture<FacetRow>(
|
|
235
|
+
html`<facet-row
|
|
236
|
+
.facetType=${'subject'}
|
|
237
|
+
.bucket=${bucket}
|
|
238
|
+
@facetClick=${facetClickSpy}
|
|
239
|
+
></facet-row>`,
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
const positiveFacetCheck = el.shadowRoot?.querySelector(
|
|
243
|
+
'.select-facet-checkbox',
|
|
244
|
+
) as HTMLInputElement;
|
|
245
|
+
expect(positiveFacetCheck).to.exist;
|
|
246
|
+
positiveFacetCheck.click();
|
|
247
|
+
|
|
248
|
+
expect(facetClickSpy.callCount).to.equal(1);
|
|
249
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
250
|
+
facetType: 'subject',
|
|
251
|
+
bucket: {
|
|
252
|
+
key: 'foo',
|
|
253
|
+
state: 'none',
|
|
254
|
+
count: 5,
|
|
255
|
+
},
|
|
256
|
+
negative: false,
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('emits event when facet negative icon is clicked', async () => {
|
|
261
|
+
const facetClickSpy = sinon.spy();
|
|
262
|
+
const bucket = {
|
|
263
|
+
key: 'foo',
|
|
264
|
+
state: 'none' as FacetState,
|
|
265
|
+
count: 5,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const el = await fixture<FacetRow>(
|
|
269
|
+
html`<facet-row
|
|
270
|
+
.facetType=${'subject'}
|
|
271
|
+
.bucket=${bucket}
|
|
272
|
+
@facetClick=${facetClickSpy}
|
|
273
|
+
></facet-row>`,
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
const negativeFacetIcon = el.shadowRoot?.querySelector(
|
|
277
|
+
'.hide-facet-icon',
|
|
278
|
+
) as HTMLLabelElement;
|
|
279
|
+
expect(negativeFacetIcon).to.exist;
|
|
280
|
+
negativeFacetIcon.click();
|
|
281
|
+
|
|
282
|
+
expect(facetClickSpy.callCount).to.equal(1);
|
|
283
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
284
|
+
facetType: 'subject',
|
|
285
|
+
bucket: {
|
|
286
|
+
key: 'foo',
|
|
287
|
+
state: 'hidden',
|
|
288
|
+
count: 5,
|
|
289
|
+
},
|
|
290
|
+
negative: true,
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it('emits event when facet negative icon is unchecked', async () => {
|
|
295
|
+
const facetClickSpy = sinon.spy();
|
|
296
|
+
const bucket = {
|
|
297
|
+
key: 'foo',
|
|
298
|
+
state: 'hidden' as FacetState,
|
|
299
|
+
count: 5,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const el = await fixture<FacetRow>(
|
|
303
|
+
html`<facet-row
|
|
304
|
+
.facetType=${'subject'}
|
|
305
|
+
.bucket=${bucket}
|
|
306
|
+
@facetClick=${facetClickSpy}
|
|
307
|
+
></facet-row>`,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
const negativeFacetIcon = el.shadowRoot?.querySelector(
|
|
311
|
+
'.hide-facet-icon',
|
|
312
|
+
) as HTMLLabelElement;
|
|
313
|
+
expect(negativeFacetIcon).to.exist;
|
|
314
|
+
negativeFacetIcon.click();
|
|
315
|
+
|
|
316
|
+
expect(facetClickSpy.callCount).to.equal(1);
|
|
317
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
318
|
+
facetType: 'subject',
|
|
319
|
+
bucket: {
|
|
320
|
+
key: 'foo',
|
|
321
|
+
state: 'none',
|
|
322
|
+
count: 5,
|
|
323
|
+
},
|
|
324
|
+
negative: true,
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it('selects/deselects facet when label is clicked', async () => {
|
|
329
|
+
const facetClickSpy = sinon.spy();
|
|
330
|
+
const bucket = {
|
|
331
|
+
key: 'foo',
|
|
332
|
+
state: 'none' as FacetState,
|
|
333
|
+
count: 5,
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const el = await fixture<FacetRow>(
|
|
337
|
+
html`<facet-row
|
|
338
|
+
.facetType=${'subject'}
|
|
339
|
+
.bucket=${bucket}
|
|
340
|
+
@facetClick=${facetClickSpy}
|
|
341
|
+
></facet-row>`,
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const facetLabel = el.shadowRoot?.querySelector(
|
|
345
|
+
'.facet-info-display',
|
|
346
|
+
) as HTMLLabelElement;
|
|
347
|
+
expect(facetLabel).to.exist;
|
|
348
|
+
|
|
349
|
+
// Select facet by clicking label
|
|
350
|
+
facetLabel.click();
|
|
351
|
+
expect(facetClickSpy.callCount).to.equal(1);
|
|
352
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
353
|
+
facetType: 'subject',
|
|
354
|
+
bucket: {
|
|
355
|
+
key: 'foo',
|
|
356
|
+
state: 'selected',
|
|
357
|
+
count: 5,
|
|
358
|
+
},
|
|
359
|
+
negative: false,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
// Deselect facet by clicking label
|
|
363
|
+
facetLabel.click();
|
|
364
|
+
expect(facetClickSpy.callCount).to.equal(2);
|
|
365
|
+
expect(facetClickSpy.lastCall.args[0]?.detail).to.deep.equal({
|
|
366
|
+
facetType: 'subject',
|
|
367
|
+
bucket: {
|
|
368
|
+
key: 'foo',
|
|
369
|
+
state: 'none',
|
|
370
|
+
count: 5,
|
|
371
|
+
},
|
|
372
|
+
negative: false,
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
});
|