@internetarchive/collection-browser 0.4.15-alpha.9 → 0.4.15
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 +5 -2
- package/dist/src/app-root.js.map +1 -1
- package/dist/src/collection-browser.d.ts +10 -0
- package/dist/src/collection-browser.js +61 -49
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/restoration-state-handler.js +3 -12
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/test/collection-browser.test.js +77 -10
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/mocks/mock-search-responses.d.ts +11 -9
- package/dist/test/mocks/mock-search-responses.js +26 -19
- package/dist/test/mocks/mock-search-responses.js.map +1 -1
- package/dist/test/mocks/mock-search-service.d.ts +3 -1
- package/dist/test/mocks/mock-search-service.js +26 -24
- package/dist/test/mocks/mock-search-service.js.map +1 -1
- package/dist/test/restoration-state-handler.test.js +1 -9
- package/dist/test/restoration-state-handler.test.js.map +1 -1
- package/package.json +1 -1
- package/src/app-root.ts +6 -2
- package/src/collection-browser.ts +68 -50
- package/src/restoration-state-handler.ts +3 -13
- package/test/collection-browser.test.ts +109 -10
- package/test/mocks/mock-search-responses.ts +42 -27
- package/test/mocks/mock-search-service.ts +50 -32
- package/test/restoration-state-handler.test.ts +1 -12
|
@@ -280,11 +280,9 @@ export class CollectionBrowser
|
|
|
280
280
|
letterFilters = true,
|
|
281
281
|
sort = false,
|
|
282
282
|
} = {}): void {
|
|
283
|
-
console.log('clearing filters');
|
|
284
283
|
// Don't bother clearing facets if none are checked, so that we don't
|
|
285
284
|
// trigger unnecessary update cycles.
|
|
286
285
|
if (facets && this.hasCheckedFacets) {
|
|
287
|
-
console.log('clearing facets');
|
|
288
286
|
this.selectedFacets = getDefaultSelectedFacets();
|
|
289
287
|
}
|
|
290
288
|
|
|
@@ -323,6 +321,14 @@ export class CollectionBrowser
|
|
|
323
321
|
return false;
|
|
324
322
|
}
|
|
325
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Manually requests to perform a search, which will only be executed if one of
|
|
326
|
+
* the query, the search type, or the sort has changed.
|
|
327
|
+
*/
|
|
328
|
+
requestSearch() {
|
|
329
|
+
this.handleQueryChange();
|
|
330
|
+
}
|
|
331
|
+
|
|
326
332
|
render() {
|
|
327
333
|
this.setPlaceholderType();
|
|
328
334
|
return html`
|
|
@@ -339,7 +345,7 @@ export class CollectionBrowser
|
|
|
339
345
|
|
|
340
346
|
private setPlaceholderType() {
|
|
341
347
|
this.placeholderType = null;
|
|
342
|
-
if (!this.baseQuery) {
|
|
348
|
+
if (!this.baseQuery?.trim()) {
|
|
343
349
|
this.placeholderType = 'empty-query';
|
|
344
350
|
}
|
|
345
351
|
|
|
@@ -681,13 +687,10 @@ export class CollectionBrowser
|
|
|
681
687
|
}
|
|
682
688
|
|
|
683
689
|
if (changed.has('baseQuery') || changed.has('searchType')) {
|
|
684
|
-
|
|
685
|
-
// Unless this query/search type update is from the initial page load or the
|
|
686
|
-
// result of hitting the back button,
|
|
690
|
+
// Unless this query/search type update is the result of hitting the back button,
|
|
687
691
|
// we need to clear any existing filters since they may no longer be valid for
|
|
688
692
|
// the new set of search results.
|
|
689
|
-
if (!this.historyPopOccurred
|
|
690
|
-
console.log('will clear filters from query change');
|
|
693
|
+
if (!this.historyPopOccurred) {
|
|
691
694
|
// Only clear filters that haven't been simultaneously applied in this update
|
|
692
695
|
this.clearFilters({
|
|
693
696
|
facets: !changed.has('selectedFacets'),
|
|
@@ -801,7 +804,6 @@ export class CollectionBrowser
|
|
|
801
804
|
}
|
|
802
805
|
|
|
803
806
|
private emitSearchTypeChanged() {
|
|
804
|
-
console.log('emitting search type change', this.searchType);
|
|
805
807
|
this.dispatchEvent(
|
|
806
808
|
new CustomEvent<SearchType>('searchTypeChanged', {
|
|
807
809
|
detail: this.searchType,
|
|
@@ -1006,20 +1008,20 @@ export class CollectionBrowser
|
|
|
1006
1008
|
/** The base query joined with any title/creator letter filters */
|
|
1007
1009
|
private get filteredQuery(): string | undefined {
|
|
1008
1010
|
if (!this.baseQuery) return undefined;
|
|
1009
|
-
let filteredQuery = this.baseQuery;
|
|
1011
|
+
let filteredQuery = this.baseQuery.trim();
|
|
1010
1012
|
|
|
1011
1013
|
const { sortFilterQueries } = this;
|
|
1012
1014
|
if (sortFilterQueries) {
|
|
1013
1015
|
filteredQuery += ` AND ${sortFilterQueries}`;
|
|
1014
1016
|
}
|
|
1015
1017
|
|
|
1016
|
-
return filteredQuery;
|
|
1018
|
+
return filteredQuery.trim();
|
|
1017
1019
|
}
|
|
1018
1020
|
|
|
1019
1021
|
/** The full query, including year facets and date range clauses */
|
|
1020
1022
|
private get fullQuery(): string | undefined {
|
|
1021
1023
|
if (!this.baseQuery) return undefined;
|
|
1022
|
-
let fullQuery = this.baseQuery;
|
|
1024
|
+
let fullQuery = this.baseQuery.trim();
|
|
1023
1025
|
|
|
1024
1026
|
const { facetQuery, dateRangeQueryClause, sortFilterQueries } = this;
|
|
1025
1027
|
|
|
@@ -1032,13 +1034,13 @@ export class CollectionBrowser
|
|
|
1032
1034
|
if (sortFilterQueries) {
|
|
1033
1035
|
fullQuery += ` AND ${sortFilterQueries}`;
|
|
1034
1036
|
}
|
|
1035
|
-
return fullQuery;
|
|
1037
|
+
return fullQuery.trim();
|
|
1036
1038
|
}
|
|
1037
1039
|
|
|
1038
1040
|
/** The full query without any title/creator letter filters */
|
|
1039
1041
|
private get fullQueryWithoutAlphaFilters(): string | undefined {
|
|
1040
1042
|
if (!this.baseQuery) return undefined;
|
|
1041
|
-
let fullQuery = this.baseQuery;
|
|
1043
|
+
let fullQuery = this.baseQuery.trim();
|
|
1042
1044
|
|
|
1043
1045
|
const { facetQuery, dateRangeQueryClause } = this;
|
|
1044
1046
|
|
|
@@ -1048,7 +1050,7 @@ export class CollectionBrowser
|
|
|
1048
1050
|
if (dateRangeQueryClause) {
|
|
1049
1051
|
fullQuery += ` AND ${dateRangeQueryClause}`;
|
|
1050
1052
|
}
|
|
1051
|
-
return fullQuery;
|
|
1053
|
+
return fullQuery.trim();
|
|
1052
1054
|
}
|
|
1053
1055
|
|
|
1054
1056
|
/**
|
|
@@ -1064,7 +1066,7 @@ export class CollectionBrowser
|
|
|
1064
1066
|
)) {
|
|
1065
1067
|
facetClauses.push(this.buildFacetClause(facetName, facetValues));
|
|
1066
1068
|
}
|
|
1067
|
-
return this.joinFacetClauses(facetClauses);
|
|
1069
|
+
return this.joinFacetClauses(facetClauses)?.trim();
|
|
1068
1070
|
}
|
|
1069
1071
|
|
|
1070
1072
|
/**
|
|
@@ -1176,17 +1178,43 @@ export class CollectionBrowser
|
|
|
1176
1178
|
aggregationsSize: 10,
|
|
1177
1179
|
// Note: we don't need an aggregations param to fetch the default aggregations from the PPS.
|
|
1178
1180
|
// The default aggregations for the search_results page type should be what we need here.
|
|
1181
|
+
uid: this.facetFetchQueryKey,
|
|
1179
1182
|
};
|
|
1180
1183
|
|
|
1181
1184
|
this.facetsLoading = true;
|
|
1182
|
-
const
|
|
1185
|
+
const searchResponse = await this.searchService?.search(
|
|
1186
|
+
params,
|
|
1187
|
+
this.searchType
|
|
1188
|
+
);
|
|
1189
|
+
const success = searchResponse?.success;
|
|
1183
1190
|
this.facetsLoading = false;
|
|
1184
1191
|
|
|
1185
|
-
|
|
1192
|
+
if (!success) {
|
|
1193
|
+
const errorMsg = searchResponse?.error?.message;
|
|
1194
|
+
const detailMsg = searchResponse?.error?.details?.message;
|
|
1195
|
+
|
|
1196
|
+
if (!errorMsg && !detailMsg) {
|
|
1197
|
+
// @ts-ignore: Property 'Sentry' does not exist on type 'Window & typeof globalThis'
|
|
1198
|
+
window?.Sentry?.captureMessage?.(
|
|
1199
|
+
'Missing or malformed facet response from backend',
|
|
1200
|
+
'error'
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// This is checking to see if the query has changed since the data was fetched.
|
|
1208
|
+
// If so, we just want to discard this set of aggregations because they are
|
|
1209
|
+
// likely no longer valid for the newer query.
|
|
1210
|
+
const returnedUid = (success.request.clientParameters as any).uid;
|
|
1211
|
+
const queryChangedSinceFetch = returnedUid !== this.facetFetchQueryKey;
|
|
1212
|
+
if (queryChangedSinceFetch) return;
|
|
1213
|
+
|
|
1214
|
+
this.aggregations = success?.response.aggregations;
|
|
1186
1215
|
|
|
1187
1216
|
this.fullYearsHistogramAggregation =
|
|
1188
|
-
|
|
1189
|
-
results?.success?.response?.aggregations?.['year-histogram']; // Temp fix until PPS FTS key is fixed to use underscore
|
|
1217
|
+
success?.response?.aggregations?.year_histogram;
|
|
1190
1218
|
}
|
|
1191
1219
|
|
|
1192
1220
|
private scrollToPage(pageNumber: number): Promise<void> {
|
|
@@ -1223,8 +1251,18 @@ export class CollectionBrowser
|
|
|
1223
1251
|
* This lets us keep track of queries so we don't persist data that's
|
|
1224
1252
|
* no longer relevant.
|
|
1225
1253
|
*/
|
|
1226
|
-
private get pageFetchQueryKey() {
|
|
1227
|
-
|
|
1254
|
+
private get pageFetchQueryKey(): string {
|
|
1255
|
+
const sortField = this.sortParam?.field ?? 'none';
|
|
1256
|
+
const sortDirection = this.sortParam?.direction ?? 'none';
|
|
1257
|
+
return `${this.fullQuery}-${this.searchType}-${sortField}-${sortDirection}`;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* Similar to `pageFetchQueryKey` above, but excludes sort fields since they
|
|
1262
|
+
* are not relevant in determining aggregation queries.
|
|
1263
|
+
*/
|
|
1264
|
+
private get facetFetchQueryKey(): string {
|
|
1265
|
+
return `${this.fullQuery}-${this.searchType}`;
|
|
1228
1266
|
}
|
|
1229
1267
|
|
|
1230
1268
|
// this maps the query to the pages being fetched for that query
|
|
@@ -1254,6 +1292,7 @@ export class CollectionBrowser
|
|
|
1254
1292
|
sort: sortParams,
|
|
1255
1293
|
filters: this.filterMap,
|
|
1256
1294
|
aggregations: { omit: true },
|
|
1295
|
+
uid: this.pageFetchQueryKey,
|
|
1257
1296
|
};
|
|
1258
1297
|
const searchResponse = await this.searchService?.search(
|
|
1259
1298
|
params,
|
|
@@ -1278,36 +1317,15 @@ export class CollectionBrowser
|
|
|
1278
1317
|
return;
|
|
1279
1318
|
}
|
|
1280
1319
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
//
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
const searchQuery = success.request.clientParameters.user_query;
|
|
1287
|
-
const searchSort = success.request.clientParameters.sort;
|
|
1288
|
-
let sortChanged = false;
|
|
1289
|
-
if (!searchSort || searchSort.length === 0) {
|
|
1290
|
-
// if we went from no sort to sort, the sort has changed
|
|
1291
|
-
if (this.sortParam) {
|
|
1292
|
-
sortChanged = true;
|
|
1293
|
-
}
|
|
1294
|
-
} else {
|
|
1295
|
-
// check if the sort has changed
|
|
1296
|
-
for (const sortType of searchSort) {
|
|
1297
|
-
const [field, direction] = sortType.split(':');
|
|
1298
|
-
if (
|
|
1299
|
-
field !== this.sortParam?.field ||
|
|
1300
|
-
direction !== this.sortParam?.direction
|
|
1301
|
-
) {
|
|
1302
|
-
sortChanged = true;
|
|
1303
|
-
break;
|
|
1304
|
-
}
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
const queryChangedSinceFetch =
|
|
1308
|
-
searchQuery !== this.filteredQuery || sortChanged;
|
|
1320
|
+
// This is checking to see if the query has changed since the data was fetched.
|
|
1321
|
+
// If so, we just want to discard the data since there should be a new query
|
|
1322
|
+
// right behind it.
|
|
1323
|
+
const returnedUid = (success.request.clientParameters as any).uid;
|
|
1324
|
+
const queryChangedSinceFetch = returnedUid !== this.pageFetchQueryKey;
|
|
1309
1325
|
if (queryChangedSinceFetch) return;
|
|
1310
1326
|
|
|
1327
|
+
this.totalResults = success.response.totalResults;
|
|
1328
|
+
|
|
1311
1329
|
const { results } = success.response;
|
|
1312
1330
|
if (results && results.length > 0) {
|
|
1313
1331
|
this.preloadCollectionNames(results);
|
|
@@ -93,7 +93,6 @@ export class RestorationStateHandler
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
private persistQueryStateToUrl(state: RestorationState) {
|
|
96
|
-
console.log('persisting...', window.location.href, state);
|
|
97
96
|
const url = new URL(window.location.href);
|
|
98
97
|
const oldParams = new URLSearchParams(url.searchParams);
|
|
99
98
|
const newParams = this.removeRecognizedParams(url.searchParams);
|
|
@@ -206,12 +205,9 @@ export class RestorationStateHandler
|
|
|
206
205
|
'',
|
|
207
206
|
url
|
|
208
207
|
);
|
|
209
|
-
|
|
210
|
-
console.log('persisted', window.location.href, state);
|
|
211
208
|
}
|
|
212
209
|
|
|
213
210
|
private loadQueryStateFromUrl(): RestorationState {
|
|
214
|
-
console.log('loading...', window.location.href);
|
|
215
211
|
const url = new URL(window.location.href);
|
|
216
212
|
const searchInside = url.searchParams.get('sin');
|
|
217
213
|
const pageNumber = url.searchParams.get('page');
|
|
@@ -237,14 +233,9 @@ export class RestorationStateHandler
|
|
|
237
233
|
restorationState.baseQuery = legacySearchQuery;
|
|
238
234
|
}
|
|
239
235
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
restorationState.searchType = SearchType.FULLTEXT;
|
|
244
|
-
break;
|
|
245
|
-
default:
|
|
246
|
-
restorationState.searchType = SearchType.METADATA;
|
|
247
|
-
break;
|
|
236
|
+
if (searchInside) {
|
|
237
|
+
restorationState.searchType =
|
|
238
|
+
searchInside === 'TXT' ? SearchType.FULLTEXT : SearchType.METADATA;
|
|
248
239
|
}
|
|
249
240
|
|
|
250
241
|
if (pageNumber) {
|
|
@@ -345,7 +336,6 @@ export class RestorationStateHandler
|
|
|
345
336
|
});
|
|
346
337
|
}
|
|
347
338
|
|
|
348
|
-
console.log('loaded', window.location.href, restorationState);
|
|
349
339
|
return restorationState;
|
|
350
340
|
}
|
|
351
341
|
|
|
@@ -19,6 +19,7 @@ import { MockAnalyticsHandler } from './mocks/mock-analytics-handler';
|
|
|
19
19
|
import { analyticsCategories } from '../src/utils/analytics-events';
|
|
20
20
|
import type { TileDispatcher } from '../src/tiles/tile-dispatcher';
|
|
21
21
|
import type { CollectionFacets } from '../src/collection-facets';
|
|
22
|
+
import type { EmptyPlaceholder } from '../src/empty-placeholder';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Wait for the next tick of the event loop.
|
|
@@ -278,7 +279,7 @@ describe('Collection Browser', () => {
|
|
|
278
279
|
).to.contains('Results');
|
|
279
280
|
});
|
|
280
281
|
|
|
281
|
-
it('can
|
|
282
|
+
it('can request a search when changing search type', async () => {
|
|
282
283
|
const searchService = new MockSearchService();
|
|
283
284
|
const el = await fixture<CollectionBrowser>(
|
|
284
285
|
html`<collection-browser .searchService=${searchService}>
|
|
@@ -289,6 +290,7 @@ describe('Collection Browser', () => {
|
|
|
289
290
|
await el.updateComplete;
|
|
290
291
|
|
|
291
292
|
el.searchType = SearchType.FULLTEXT;
|
|
293
|
+
el.requestSearch();
|
|
292
294
|
await el.updateComplete;
|
|
293
295
|
await nextTick();
|
|
294
296
|
|
|
@@ -499,6 +501,59 @@ describe('Collection Browser', () => {
|
|
|
499
501
|
expect(searchService.searchType).to.equal(SearchType.FULLTEXT);
|
|
500
502
|
});
|
|
501
503
|
|
|
504
|
+
it('trims queries of leading/trailing whitespace', async () => {
|
|
505
|
+
const searchService = new MockSearchService();
|
|
506
|
+
const el = await fixture<CollectionBrowser>(
|
|
507
|
+
html`<collection-browser
|
|
508
|
+
.searchService=${searchService}
|
|
509
|
+
></collection-browser>`
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
el.baseQuery = ' collection:foo ';
|
|
513
|
+
await el.updateComplete;
|
|
514
|
+
|
|
515
|
+
expect(searchService.searchParams?.query).to.equal('collection:foo');
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('shows error message when error response received', async () => {
|
|
519
|
+
const searchService = new MockSearchService();
|
|
520
|
+
const el = await fixture<CollectionBrowser>(
|
|
521
|
+
html`<collection-browser
|
|
522
|
+
.searchService=${searchService}
|
|
523
|
+
></collection-browser>`
|
|
524
|
+
);
|
|
525
|
+
|
|
526
|
+
el.baseQuery = 'error';
|
|
527
|
+
await el.updateComplete;
|
|
528
|
+
await nextTick();
|
|
529
|
+
|
|
530
|
+
const errorPlaceholder = el.shadowRoot?.querySelector(
|
|
531
|
+
'empty-placeholder'
|
|
532
|
+
) as EmptyPlaceholder;
|
|
533
|
+
const errorDetails = errorPlaceholder?.shadowRoot?.querySelector(
|
|
534
|
+
'.error-details'
|
|
535
|
+
) as HTMLParagraphElement;
|
|
536
|
+
|
|
537
|
+
expect(errorDetails).to.exist;
|
|
538
|
+
expect(errorDetails.textContent).to.contain('foo');
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('reports malformed response errors to Sentry', async () => {
|
|
542
|
+
const sentrySpy = sinon.spy();
|
|
543
|
+
(window as any).Sentry = { captureMessage: sentrySpy };
|
|
544
|
+
const searchService = new MockSearchService();
|
|
545
|
+
const el = await fixture<CollectionBrowser>(
|
|
546
|
+
html`<collection-browser
|
|
547
|
+
.searchService=${searchService}
|
|
548
|
+
></collection-browser>`
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
el.baseQuery = 'malformed';
|
|
552
|
+
await el.updateComplete;
|
|
553
|
+
|
|
554
|
+
expect(sentrySpy.callCount).to.be.greaterThanOrEqual(1);
|
|
555
|
+
});
|
|
556
|
+
|
|
502
557
|
it('queries for collection names after a fetch', async () => {
|
|
503
558
|
const searchService = new MockSearchService();
|
|
504
559
|
const collectionNameCache = new MockCollectionNameCache();
|
|
@@ -561,12 +616,16 @@ describe('Collection Browser', () => {
|
|
|
561
616
|
el.sortParam = { field: 'foo', direction: 'asc' };
|
|
562
617
|
await el.updateComplete;
|
|
563
618
|
|
|
564
|
-
|
|
619
|
+
// We want to spy exclusively on the first set of results, not the second
|
|
620
|
+
searchService.asyncResponse = false;
|
|
621
|
+
searchService.resultsSpy = () => {};
|
|
622
|
+
|
|
565
623
|
el.sortParam = { field: 'foo', direction: 'desc' };
|
|
566
|
-
await
|
|
624
|
+
await el.updateComplete;
|
|
625
|
+
await nextTick();
|
|
567
626
|
|
|
568
627
|
// If the different sort param causes the results to be discarded,
|
|
569
|
-
// the results array should never be read.
|
|
628
|
+
// the first results array should never be read.
|
|
570
629
|
expect(resultsSpy.callCount).to.equal(0);
|
|
571
630
|
});
|
|
572
631
|
|
|
@@ -585,12 +644,16 @@ describe('Collection Browser', () => {
|
|
|
585
644
|
el.baseQuery = 'single-result';
|
|
586
645
|
await el.updateComplete;
|
|
587
646
|
|
|
588
|
-
|
|
647
|
+
// We want to spy exclusively on the first set of results, not the second
|
|
648
|
+
searchService.asyncResponse = false;
|
|
649
|
+
searchService.resultsSpy = () => {};
|
|
650
|
+
|
|
589
651
|
el.sortParam = { field: 'foo', direction: 'asc' };
|
|
590
|
-
await
|
|
652
|
+
await el.updateComplete;
|
|
653
|
+
await nextTick();
|
|
591
654
|
|
|
592
655
|
// If the different sort param causes the results to be discarded,
|
|
593
|
-
// the results array should never be read.
|
|
656
|
+
// the first results array should never be read.
|
|
594
657
|
expect(resultsSpy.callCount).to.equal(0);
|
|
595
658
|
});
|
|
596
659
|
|
|
@@ -607,14 +670,19 @@ describe('Collection Browser', () => {
|
|
|
607
670
|
);
|
|
608
671
|
|
|
609
672
|
el.baseQuery = 'with-sort';
|
|
673
|
+
el.sortParam = { field: 'foo', direction: 'asc' };
|
|
610
674
|
await el.updateComplete;
|
|
611
675
|
|
|
612
|
-
|
|
676
|
+
// We want to spy exclusively on the first set of results, not the second
|
|
677
|
+
searchService.asyncResponse = false;
|
|
678
|
+
searchService.resultsSpy = () => {};
|
|
679
|
+
|
|
613
680
|
el.sortParam = null;
|
|
614
|
-
await
|
|
681
|
+
await el.updateComplete;
|
|
682
|
+
await nextTick();
|
|
615
683
|
|
|
616
684
|
// If the different sort param causes the results to be discarded,
|
|
617
|
-
// the results array should never be read.
|
|
685
|
+
// the first results array should never be read.
|
|
618
686
|
expect(resultsSpy.callCount).to.equal(0);
|
|
619
687
|
});
|
|
620
688
|
|
|
@@ -801,6 +869,37 @@ describe('Collection Browser', () => {
|
|
|
801
869
|
infiniteScroller.scrollToCell = oldScrollToCell;
|
|
802
870
|
});
|
|
803
871
|
|
|
872
|
+
it('shows mobile facets in mobile view', async () => {
|
|
873
|
+
const searchService = new MockSearchService();
|
|
874
|
+
const el = await fixture<CollectionBrowser>(
|
|
875
|
+
html`<collection-browser
|
|
876
|
+
.searchService=${searchService}
|
|
877
|
+
.mobileBreakpoint=${9999}
|
|
878
|
+
></collection-browser>`
|
|
879
|
+
);
|
|
880
|
+
|
|
881
|
+
el.baseQuery = 'collection:foo';
|
|
882
|
+
await el.updateComplete;
|
|
883
|
+
|
|
884
|
+
const contentContainer = el.shadowRoot?.querySelector(
|
|
885
|
+
'#content-container'
|
|
886
|
+
) as HTMLElement;
|
|
887
|
+
|
|
888
|
+
el.handleResize({
|
|
889
|
+
target: contentContainer,
|
|
890
|
+
contentRect: contentContainer.getBoundingClientRect(),
|
|
891
|
+
borderBoxSize: [],
|
|
892
|
+
contentBoxSize: [],
|
|
893
|
+
devicePixelContentBoxSize: [],
|
|
894
|
+
});
|
|
895
|
+
await el.updateComplete;
|
|
896
|
+
|
|
897
|
+
const mobileFacets = el.shadowRoot?.querySelector(
|
|
898
|
+
'#mobile-filter-collapse'
|
|
899
|
+
);
|
|
900
|
+
expect(mobileFacets).to.exist;
|
|
901
|
+
});
|
|
902
|
+
|
|
804
903
|
it('refreshes when certain properties change - with some analytics event sampling', async () => {
|
|
805
904
|
const mockAnalyticsHandler = new MockAnalyticsHandler();
|
|
806
905
|
const searchService = new MockSearchService();
|
|
@@ -5,11 +5,12 @@ import {
|
|
|
5
5
|
SearchResponse,
|
|
6
6
|
SearchServiceError,
|
|
7
7
|
} from '@internetarchive/search-service';
|
|
8
|
+
import { SearchServiceErrorType } from '@internetarchive/search-service/dist/src/search-service-error';
|
|
8
9
|
|
|
9
|
-
export const
|
|
10
|
+
export const getMockSuccessSingleResult: () => Result<
|
|
10
11
|
SearchResponse,
|
|
11
12
|
SearchServiceError
|
|
12
|
-
> = {
|
|
13
|
+
> = () => ({
|
|
13
14
|
success: {
|
|
14
15
|
request: {
|
|
15
16
|
clientParameters: {
|
|
@@ -39,12 +40,12 @@ export const mockSuccessSingleResult: Result<
|
|
|
39
40
|
query_time: 0,
|
|
40
41
|
},
|
|
41
42
|
},
|
|
42
|
-
};
|
|
43
|
+
});
|
|
43
44
|
|
|
44
|
-
export const
|
|
45
|
+
export const getMockSuccessWithYearHistogramAggs: () => Result<
|
|
45
46
|
SearchResponse,
|
|
46
47
|
SearchServiceError
|
|
47
|
-
> = {
|
|
48
|
+
> = () => ({
|
|
48
49
|
success: {
|
|
49
50
|
request: {
|
|
50
51
|
clientParameters: {
|
|
@@ -84,12 +85,12 @@ export const mockSuccessWithYearHistogramAggs: Result<
|
|
|
84
85
|
query_time: 0,
|
|
85
86
|
},
|
|
86
87
|
},
|
|
87
|
-
};
|
|
88
|
+
});
|
|
88
89
|
|
|
89
|
-
export const
|
|
90
|
+
export const getMockSuccessLoggedInResult: () => Result<
|
|
90
91
|
SearchResponse,
|
|
91
92
|
SearchServiceError
|
|
92
|
-
> = {
|
|
93
|
+
> = () => ({
|
|
93
94
|
success: {
|
|
94
95
|
request: {
|
|
95
96
|
clientParameters: {
|
|
@@ -121,12 +122,12 @@ export const mockSuccessLoggedInResult: Result<
|
|
|
121
122
|
query_time: 0,
|
|
122
123
|
},
|
|
123
124
|
},
|
|
124
|
-
};
|
|
125
|
+
});
|
|
125
126
|
|
|
126
|
-
export const
|
|
127
|
+
export const getMockSuccessNoPreviewResult: () => Result<
|
|
127
128
|
SearchResponse,
|
|
128
129
|
SearchServiceError
|
|
129
|
-
> = {
|
|
130
|
+
> = () => ({
|
|
130
131
|
success: {
|
|
131
132
|
request: {
|
|
132
133
|
clientParameters: {
|
|
@@ -156,12 +157,12 @@ export const mockSuccessNoPreviewResult: Result<
|
|
|
156
157
|
query_time: 0,
|
|
157
158
|
},
|
|
158
159
|
},
|
|
159
|
-
};
|
|
160
|
+
});
|
|
160
161
|
|
|
161
|
-
export const
|
|
162
|
+
export const getMockSuccessLoggedInAndNoPreviewResult: () => Result<
|
|
162
163
|
SearchResponse,
|
|
163
164
|
SearchServiceError
|
|
164
|
-
> = {
|
|
165
|
+
> = () => ({
|
|
165
166
|
success: {
|
|
166
167
|
request: {
|
|
167
168
|
clientParameters: {
|
|
@@ -191,12 +192,12 @@ export const mockSuccessLoggedInAndNoPreviewResult: Result<
|
|
|
191
192
|
query_time: 0,
|
|
192
193
|
},
|
|
193
194
|
},
|
|
194
|
-
};
|
|
195
|
+
});
|
|
195
196
|
|
|
196
|
-
export const
|
|
197
|
+
export const getMockSuccessFirstTitleResult: () => Result<
|
|
197
198
|
SearchResponse,
|
|
198
199
|
SearchServiceError
|
|
199
|
-
> = {
|
|
200
|
+
> = () => ({
|
|
200
201
|
success: {
|
|
201
202
|
request: {
|
|
202
203
|
clientParameters: {
|
|
@@ -230,12 +231,12 @@ export const mockSuccessFirstTitleResult: Result<
|
|
|
230
231
|
query_time: 0,
|
|
231
232
|
},
|
|
232
233
|
},
|
|
233
|
-
};
|
|
234
|
+
});
|
|
234
235
|
|
|
235
|
-
export const
|
|
236
|
+
export const getMockSuccessFirstCreatorResult: () => Result<
|
|
236
237
|
SearchResponse,
|
|
237
238
|
SearchServiceError
|
|
238
|
-
> = {
|
|
239
|
+
> = () => ({
|
|
239
240
|
success: {
|
|
240
241
|
request: {
|
|
241
242
|
clientParameters: {
|
|
@@ -269,7 +270,7 @@ export const mockSuccessFirstCreatorResult: Result<
|
|
|
269
270
|
query_time: 0,
|
|
270
271
|
},
|
|
271
272
|
},
|
|
272
|
-
};
|
|
273
|
+
});
|
|
273
274
|
|
|
274
275
|
export const getMockSuccessSingleResultWithSort: (
|
|
275
276
|
resultsSpy: Function
|
|
@@ -308,10 +309,10 @@ export const getMockSuccessSingleResultWithSort: (
|
|
|
308
309
|
},
|
|
309
310
|
});
|
|
310
311
|
|
|
311
|
-
export const
|
|
312
|
+
export const getMockSuccessMultipleResults: () => Result<
|
|
312
313
|
SearchResponse,
|
|
313
314
|
SearchServiceError
|
|
314
|
-
> = {
|
|
315
|
+
> = () => ({
|
|
315
316
|
success: {
|
|
316
317
|
request: {
|
|
317
318
|
clientParameters: {
|
|
@@ -347,12 +348,12 @@ export const mockSuccessMultipleResults: Result<
|
|
|
347
348
|
query_time: 0,
|
|
348
349
|
},
|
|
349
350
|
},
|
|
350
|
-
};
|
|
351
|
+
});
|
|
351
352
|
|
|
352
|
-
export const
|
|
353
|
+
export const getMockSuccessMultiLineDescription: () => Result<
|
|
353
354
|
SearchResponse,
|
|
354
355
|
SearchServiceError
|
|
355
|
-
> = {
|
|
356
|
+
> = () => ({
|
|
356
357
|
success: {
|
|
357
358
|
request: {
|
|
358
359
|
clientParameters: {
|
|
@@ -383,4 +384,18 @@ export const mockSuccessMultiLineDescription: Result<
|
|
|
383
384
|
query_time: 0,
|
|
384
385
|
},
|
|
385
386
|
},
|
|
386
|
-
};
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
export const getMockErrorResult: () => Result<
|
|
390
|
+
SearchResponse,
|
|
391
|
+
SearchServiceError
|
|
392
|
+
> = () => ({
|
|
393
|
+
error: new SearchServiceError(SearchServiceErrorType.networkError, 'foo', {
|
|
394
|
+
message: 'bar',
|
|
395
|
+
}),
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
export const getMockMalformedResult: () => Result<
|
|
399
|
+
SearchResponse,
|
|
400
|
+
SearchServiceError
|
|
401
|
+
> = () => ({});
|