@internetarchive/collection-browser 2.10.1-alpha-webdev7479.10 → 2.12.0
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/assets/img/icons/close-circle-dark.d.ts +2 -0
- package/dist/src/assets/img/icons/close-circle-dark.js +5 -0
- package/dist/src/assets/img/icons/close-circle-dark.js.map +1 -0
- package/dist/src/collection-browser.d.ts +8 -0
- package/dist/src/collection-browser.js +33 -7
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.js +1 -1
- package/dist/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.d.ts +3 -2
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js +36 -13
- package/dist/src/collection-facets/smart-facets/smart-facet-bar.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js +26 -10
- package/dist/src/collection-facets/smart-facets/smart-facet-button.js.map +1 -1
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js +19 -9
- package/dist/src/collection-facets/smart-facets/smart-facet-dropdown.js.map +1 -1
- package/dist/src/data-source/collection-browser-data-source.js +4 -5
- package/dist/src/data-source/collection-browser-data-source.js.map +1 -1
- package/dist/src/tiles/grid/tile-stats.js +2 -2
- package/dist/src/tiles/grid/tile-stats.js.map +1 -1
- package/dist/test/collection-browser.test.js +55 -1
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +1 -0
- package/dist/test/mocks/mock-search-responses.js +46 -0
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.js +2 -1
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +40 -0
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/dist/test/tile-stats.test.js +39 -13
- package/dist/test/tile-stats.test.js.map +1 -1
- package/package.json +2 -2
- package/src/assets/img/icons/close-circle-dark.ts +5 -0
- package/src/collection-browser.ts +35 -7
- package/src/collection-facets/smart-facets/heuristics/wikidata/wikidata-heuristic.ts +4 -1
- package/src/collection-facets/smart-facets/smart-facet-bar.ts +38 -16
- package/src/collection-facets/smart-facets/smart-facet-button.ts +27 -10
- package/src/collection-facets/smart-facets/smart-facet-dropdown.ts +21 -10
- package/src/data-source/collection-browser-data-source.ts +8 -5
- package/src/tiles/grid/tile-stats.ts +2 -2
- package/test/collection-browser.test.ts +81 -1
- package/test/mocks/mock-search-responses.ts +50 -0
- package/test/mocks/mock-search-service.ts +2 -0
- package/test/restoration-state-handler.test.ts +59 -0
- package/test/tile-stats.test.ts +51 -13
|
@@ -369,6 +369,50 @@ describe('Collection Browser', () => {
|
|
|
369
369
|
).to.contains('Results');
|
|
370
370
|
});
|
|
371
371
|
|
|
372
|
+
it('queries the search service with a radio search', async () => {
|
|
373
|
+
const searchService = new MockSearchService();
|
|
374
|
+
|
|
375
|
+
const el = await fixture<CollectionBrowser>(
|
|
376
|
+
html` <collection-browser .searchService=${searchService}>
|
|
377
|
+
</collection-browser>`,
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
el.searchType = SearchType.RADIO;
|
|
381
|
+
await el.updateComplete;
|
|
382
|
+
|
|
383
|
+
el.baseQuery = 'collection:foo';
|
|
384
|
+
await el.updateComplete;
|
|
385
|
+
await el.initialSearchComplete;
|
|
386
|
+
|
|
387
|
+
expect(searchService.searchParams?.query).to.equal('collection:foo');
|
|
388
|
+
expect(searchService.searchType).to.equal(SearchType.RADIO);
|
|
389
|
+
expect(
|
|
390
|
+
el.shadowRoot?.querySelector('#big-results-label')?.textContent,
|
|
391
|
+
).to.contains('Results');
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
it('queries the search service with a TV search', async () => {
|
|
395
|
+
const searchService = new MockSearchService();
|
|
396
|
+
|
|
397
|
+
const el = await fixture<CollectionBrowser>(
|
|
398
|
+
html` <collection-browser .searchService=${searchService}>
|
|
399
|
+
</collection-browser>`,
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
el.searchType = SearchType.TV;
|
|
403
|
+
await el.updateComplete;
|
|
404
|
+
|
|
405
|
+
el.baseQuery = 'collection:foo';
|
|
406
|
+
await el.updateComplete;
|
|
407
|
+
await el.initialSearchComplete;
|
|
408
|
+
|
|
409
|
+
expect(searchService.searchParams?.query).to.equal('collection:foo');
|
|
410
|
+
expect(searchService.searchType).to.equal(SearchType.TV);
|
|
411
|
+
expect(
|
|
412
|
+
el.shadowRoot?.querySelector('#big-results-label')?.textContent,
|
|
413
|
+
).to.contains('Results');
|
|
414
|
+
});
|
|
415
|
+
|
|
372
416
|
it('queries the search service with facets selected/negated', async () => {
|
|
373
417
|
const searchService = new MockSearchService();
|
|
374
418
|
const selectedFacets: SelectedFacets = {
|
|
@@ -1306,6 +1350,23 @@ describe('Collection Browser', () => {
|
|
|
1306
1350
|
expect(el.dataSource.parentCollections).to.deep.equal(['foo', 'bar']);
|
|
1307
1351
|
});
|
|
1308
1352
|
|
|
1353
|
+
it('recognizes TV collections', async () => {
|
|
1354
|
+
const searchService = new MockSearchService();
|
|
1355
|
+
const el = await fixture<CollectionBrowser>(
|
|
1356
|
+
html`<collection-browser
|
|
1357
|
+
.searchService=${searchService}
|
|
1358
|
+
.withinCollection=${'TV-FOO'}
|
|
1359
|
+
></collection-browser>`,
|
|
1360
|
+
);
|
|
1361
|
+
|
|
1362
|
+
el.baseQuery = 'tv-collection';
|
|
1363
|
+
await el.updateComplete;
|
|
1364
|
+
await el.initialSearchComplete;
|
|
1365
|
+
await aTimeout(0);
|
|
1366
|
+
|
|
1367
|
+
expect(el.isTVCollection).to.be.true;
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1309
1370
|
it('refreshes when certain properties change - with some analytics event sampling', async () => {
|
|
1310
1371
|
const mockAnalyticsHandler = new MockAnalyticsHandler();
|
|
1311
1372
|
const searchService = new MockSearchService();
|
|
@@ -1512,7 +1573,7 @@ describe('Collection Browser', () => {
|
|
|
1512
1573
|
expect(el.withinProfile).to.equal('@foobar');
|
|
1513
1574
|
expect(el.profileElement).to.equal('uploads');
|
|
1514
1575
|
expect(el.baseQuery).to.equal('foo');
|
|
1515
|
-
expect(el.searchType).to.equal(SearchType.
|
|
1576
|
+
expect(el.searchType).to.equal(SearchType.DEFAULT);
|
|
1516
1577
|
expect(el.selectedFacets?.mediatype?.data?.state).to.equal('hidden');
|
|
1517
1578
|
expect(el.selectedFacets?.subject?.baz?.state).to.equal('selected');
|
|
1518
1579
|
expect(el.selectedTitleFilter).to.equal('X');
|
|
@@ -2044,4 +2105,23 @@ describe('Collection Browser', () => {
|
|
|
2044
2105
|
const initialResults = el.dataSource.getAllPages();
|
|
2045
2106
|
expect(Object.keys(initialResults).length).to.deep.equal(numberOfPages);
|
|
2046
2107
|
});
|
|
2108
|
+
|
|
2109
|
+
it('renders provided results header instead of default, when showing smart results', async () => {
|
|
2110
|
+
const searchService = new MockSearchService();
|
|
2111
|
+
|
|
2112
|
+
const el = await fixture<CollectionBrowser>(
|
|
2113
|
+
html`<collection-browser
|
|
2114
|
+
showSmartResults
|
|
2115
|
+
.searchService=${searchService}
|
|
2116
|
+
.resultsHeader=${'Foo Bar'}
|
|
2117
|
+
></collection-browser>`,
|
|
2118
|
+
);
|
|
2119
|
+
|
|
2120
|
+
el.baseQuery = 'foo';
|
|
2121
|
+
await el.updateComplete;
|
|
2122
|
+
await nextTick();
|
|
2123
|
+
|
|
2124
|
+
const header = el.shadowRoot?.querySelector('.results-section-heading');
|
|
2125
|
+
expect(header?.textContent?.trim()).to.equal('Foo Bar');
|
|
2126
|
+
});
|
|
2047
2127
|
});
|
|
@@ -98,12 +98,14 @@ export const getMockSuccessManyFields: () => Result<
|
|
|
98
98
|
mediatype: 'texts',
|
|
99
99
|
num_favorites: 12,
|
|
100
100
|
num_reviews: 23,
|
|
101
|
+
num_clips: 34,
|
|
101
102
|
source: 'foo bar',
|
|
102
103
|
subject: ['baz', 'quux'],
|
|
103
104
|
title: 'Foo Bar',
|
|
104
105
|
volume: 2,
|
|
105
106
|
week: 50,
|
|
106
107
|
__href__: 'https://archive.org/details/foo',
|
|
108
|
+
__img__: '//services/img/foo',
|
|
107
109
|
},
|
|
108
110
|
}),
|
|
109
111
|
],
|
|
@@ -897,6 +899,54 @@ export const getMockSuccessWithParentCollections: () => Result<
|
|
|
897
899
|
},
|
|
898
900
|
});
|
|
899
901
|
|
|
902
|
+
export const getMockSuccessForTvCollection: () => Result<
|
|
903
|
+
SearchResponse,
|
|
904
|
+
SearchServiceError
|
|
905
|
+
> = () => ({
|
|
906
|
+
success: {
|
|
907
|
+
request: {
|
|
908
|
+
kind: 'hits',
|
|
909
|
+
clientParameters: {
|
|
910
|
+
user_query: 'tv-collection',
|
|
911
|
+
sort: [],
|
|
912
|
+
},
|
|
913
|
+
backendRequests: {
|
|
914
|
+
primary: {
|
|
915
|
+
kind: 'hits',
|
|
916
|
+
finalized_parameters: {
|
|
917
|
+
user_query: 'tv-collection',
|
|
918
|
+
sort: [],
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
},
|
|
922
|
+
},
|
|
923
|
+
rawResponse: {},
|
|
924
|
+
sessionContext: {},
|
|
925
|
+
response: {
|
|
926
|
+
totalResults: 1,
|
|
927
|
+
returnedCount: 1,
|
|
928
|
+
results: [
|
|
929
|
+
new ItemHit({
|
|
930
|
+
fields: {
|
|
931
|
+
identifier: 'foo',
|
|
932
|
+
title: 'Foo',
|
|
933
|
+
},
|
|
934
|
+
}),
|
|
935
|
+
],
|
|
936
|
+
collectionExtraInfo: {
|
|
937
|
+
public_metadata: {
|
|
938
|
+
identifier: 'TV-FOO',
|
|
939
|
+
collection: ['tvarchive'],
|
|
940
|
+
},
|
|
941
|
+
},
|
|
942
|
+
},
|
|
943
|
+
responseHeader: {
|
|
944
|
+
succeeded: true,
|
|
945
|
+
query_time: 0,
|
|
946
|
+
},
|
|
947
|
+
},
|
|
948
|
+
});
|
|
949
|
+
|
|
900
950
|
export const getMockSuccessWithWebArchiveHits: () => Result<
|
|
901
951
|
SearchResponse,
|
|
902
952
|
SearchServiceError
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
getMockSuccessWithConciseDefaultSort,
|
|
27
27
|
getMockSuccessWithDefaultFavSort,
|
|
28
28
|
getMockSuccessWithParentCollections,
|
|
29
|
+
getMockSuccessForTvCollection,
|
|
29
30
|
getMockSuccessManyFields,
|
|
30
31
|
getMockSuccessNoResults,
|
|
31
32
|
getMockSuccessWithWebArchiveHits,
|
|
@@ -51,6 +52,7 @@ const responses: Record<
|
|
|
51
52
|
'default-sort-concise': getMockSuccessWithConciseDefaultSort,
|
|
52
53
|
'fav-sort': getMockSuccessWithDefaultFavSort,
|
|
53
54
|
'parent-collections': getMockSuccessWithParentCollections,
|
|
55
|
+
'tv-collection': getMockSuccessForTvCollection,
|
|
54
56
|
'web-archive': getMockSuccessWithWebArchiveHits,
|
|
55
57
|
'more-facets': getMockSuccessWithManyAggregations,
|
|
56
58
|
'many-fields': getMockSuccessManyFields,
|
|
@@ -48,6 +48,39 @@ describe('Restoration state handler', () => {
|
|
|
48
48
|
expect(restorationState.searchType).to.equal(SearchType.FULLTEXT);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
+
it('should restore radio search type from URL', async () => {
|
|
52
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
53
|
+
|
|
54
|
+
const url = new URL(window.location.href);
|
|
55
|
+
url.search = '?sin=RADIO';
|
|
56
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
57
|
+
|
|
58
|
+
const restorationState = handler.getRestorationState();
|
|
59
|
+
expect(restorationState.searchType).to.equal(SearchType.RADIO);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should restore TV search type from URL', async () => {
|
|
63
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
64
|
+
|
|
65
|
+
const url = new URL(window.location.href);
|
|
66
|
+
url.search = '?sin=TV';
|
|
67
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
68
|
+
|
|
69
|
+
const restorationState = handler.getRestorationState();
|
|
70
|
+
expect(restorationState.searchType).to.equal(SearchType.TV);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should restore metadata search type from URL', async () => {
|
|
74
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
75
|
+
|
|
76
|
+
const url = new URL(window.location.href);
|
|
77
|
+
url.search = '?sin=MD';
|
|
78
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
79
|
+
|
|
80
|
+
const restorationState = handler.getRestorationState();
|
|
81
|
+
expect(restorationState.searchType).to.equal(SearchType.METADATA);
|
|
82
|
+
});
|
|
83
|
+
|
|
51
84
|
it('should restore page number from URL', async () => {
|
|
52
85
|
const handler = new RestorationStateHandler({ context: 'search' });
|
|
53
86
|
|
|
@@ -364,6 +397,32 @@ describe('Restoration state handler', () => {
|
|
|
364
397
|
expect(window.location.search).to.equal('');
|
|
365
398
|
});
|
|
366
399
|
|
|
400
|
+
it('should persist metadata search type only when option is true', async () => {
|
|
401
|
+
const url = new URL(window.location.href);
|
|
402
|
+
url.search = '?sin=';
|
|
403
|
+
window.history.replaceState({ path: url.href }, '', url.href);
|
|
404
|
+
|
|
405
|
+
const handler = new RestorationStateHandler({ context: 'search' });
|
|
406
|
+
|
|
407
|
+
handler.persistState(
|
|
408
|
+
{
|
|
409
|
+
selectedFacets: getDefaultSelectedFacets(),
|
|
410
|
+
searchType: SearchType.METADATA,
|
|
411
|
+
},
|
|
412
|
+
{ persistMetadataSearchType: false },
|
|
413
|
+
);
|
|
414
|
+
expect(window.location.search).to.equal('');
|
|
415
|
+
|
|
416
|
+
handler.persistState(
|
|
417
|
+
{
|
|
418
|
+
selectedFacets: getDefaultSelectedFacets(),
|
|
419
|
+
searchType: SearchType.METADATA,
|
|
420
|
+
},
|
|
421
|
+
{ persistMetadataSearchType: true },
|
|
422
|
+
);
|
|
423
|
+
expect(window.location.search).to.equal('?sin=MD');
|
|
424
|
+
});
|
|
425
|
+
|
|
367
426
|
it('round trip load/persist should erase numbers in square brackets', async () => {
|
|
368
427
|
const handler = new RestorationStateHandler({ context: 'search' });
|
|
369
428
|
|
package/test/tile-stats.test.ts
CHANGED
|
@@ -17,7 +17,7 @@ describe('Tile Stats', () => {
|
|
|
17
17
|
expect(statsRowCount).to.equal(4);
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
it('should render component with
|
|
20
|
+
it('should render component with values', async () => {
|
|
21
21
|
const el = await fixture<TileStats>(html`
|
|
22
22
|
<tile-stats
|
|
23
23
|
.mediatype=${'account'}
|
|
@@ -48,9 +48,47 @@ describe('Tile Stats', () => {
|
|
|
48
48
|
?.textContent?.trim();
|
|
49
49
|
|
|
50
50
|
expect(mediatypeStat).to.exist;
|
|
51
|
-
expect(itemStatCount).to.match(/
|
|
52
|
-
expect(favoritesStatCount).to.match(/
|
|
53
|
-
expect(reviewsStatCount).to.match(/
|
|
51
|
+
expect(itemStatCount).to.match(/uploads:\s+1/);
|
|
52
|
+
expect(favoritesStatCount).to.match(/favorites:\s+2/);
|
|
53
|
+
expect(reviewsStatCount).to.match(/reviews:\s+3/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should render component with tv clips', async () => {
|
|
57
|
+
const el = await fixture<TileStats>(html`
|
|
58
|
+
<tile-stats
|
|
59
|
+
showTvClips
|
|
60
|
+
.mediatype=${'texts'}
|
|
61
|
+
.viewCount=${1}
|
|
62
|
+
.favCount=${2}
|
|
63
|
+
.commentCount=${3}
|
|
64
|
+
.tvClipCount=${4}
|
|
65
|
+
>
|
|
66
|
+
</tile-stats>
|
|
67
|
+
`);
|
|
68
|
+
|
|
69
|
+
const statsRow = el.shadowRoot?.querySelector('#stats-row');
|
|
70
|
+
|
|
71
|
+
const mediatypeStat = statsRow?.children.item(0);
|
|
72
|
+
// get second column item in stats row
|
|
73
|
+
const itemStatCount = statsRow?.children
|
|
74
|
+
.item(1)
|
|
75
|
+
?.querySelector('.status-text')
|
|
76
|
+
?.textContent?.trim();
|
|
77
|
+
// get third column item in stats row
|
|
78
|
+
const favoritesStatCount = statsRow?.children
|
|
79
|
+
.item(2)
|
|
80
|
+
?.querySelector('.status-text')
|
|
81
|
+
?.textContent?.trim();
|
|
82
|
+
// get fourth column item in stats row
|
|
83
|
+
const clipsStatCount = statsRow?.children
|
|
84
|
+
.item(3)
|
|
85
|
+
?.querySelector('.status-text')
|
|
86
|
+
?.textContent?.trim();
|
|
87
|
+
|
|
88
|
+
expect(mediatypeStat).to.exist;
|
|
89
|
+
expect(itemStatCount).to.match(/views:\s+1/);
|
|
90
|
+
expect(favoritesStatCount).to.match(/favorites:\s+2/);
|
|
91
|
+
expect(clipsStatCount).to.match(/clips:\s+4/);
|
|
54
92
|
});
|
|
55
93
|
|
|
56
94
|
it('should render view count for non-account items', async () => {
|
|
@@ -84,9 +122,9 @@ describe('Tile Stats', () => {
|
|
|
84
122
|
?.textContent?.trim();
|
|
85
123
|
|
|
86
124
|
expect(mediatypeStat).to.exist;
|
|
87
|
-
expect(viewStatCount).to.match(/
|
|
88
|
-
expect(favoritesStatCount).to.match(/
|
|
89
|
-
expect(reviewsStatCount).to.match(/
|
|
125
|
+
expect(viewStatCount).to.match(/views:\s+4/);
|
|
126
|
+
expect(favoritesStatCount).to.match(/favorites:\s+5/);
|
|
127
|
+
expect(reviewsStatCount).to.match(/reviews:\s+6/);
|
|
90
128
|
});
|
|
91
129
|
|
|
92
130
|
it('handles missing counts gracefully', async () => {
|
|
@@ -115,9 +153,9 @@ describe('Tile Stats', () => {
|
|
|
115
153
|
?.textContent?.trim();
|
|
116
154
|
|
|
117
155
|
expect(mediatypeStat).to.exist;
|
|
118
|
-
expect(viewStatCount).to.match(/
|
|
119
|
-
expect(favoritesStatCount).to.match(/
|
|
120
|
-
expect(reviewsStatCount).to.match(/
|
|
156
|
+
expect(viewStatCount).to.match(/views:\s+0/);
|
|
157
|
+
expect(favoritesStatCount).to.match(/favorites:\s+5/);
|
|
158
|
+
expect(reviewsStatCount).to.match(/reviews:\s+6/);
|
|
121
159
|
});
|
|
122
160
|
|
|
123
161
|
it('handles missing counts gracefully for accounts', async () => {
|
|
@@ -146,8 +184,8 @@ describe('Tile Stats', () => {
|
|
|
146
184
|
?.textContent?.trim();
|
|
147
185
|
|
|
148
186
|
expect(mediatypeStat).to.exist;
|
|
149
|
-
expect(itemStatCount).to.match(/
|
|
150
|
-
expect(favoritesStatCount).to.match(/
|
|
151
|
-
expect(reviewsStatCount).to.match(/
|
|
187
|
+
expect(itemStatCount).to.match(/uploads:\s+0/);
|
|
188
|
+
expect(favoritesStatCount).to.match(/favorites:\s+5/);
|
|
189
|
+
expect(reviewsStatCount).to.match(/reviews:\s+6/);
|
|
152
190
|
});
|
|
153
191
|
});
|