Skip to content

Commit 12f72f6

Browse files
committed
Small fix for web archive results beyond first page + tests
1 parent cbc8e14 commit 12f72f6

File tree

7 files changed

+157
-7
lines changed

7 files changed

+157
-7
lines changed

src/data-source/collection-browser-data-source-interface.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ export interface CollectionBrowserDataSourceInterface
219219
*/
220220
refreshLetterCounts(): void;
221221

222+
/**
223+
* Returns the current page size of the data source.
224+
*/
225+
getPageSize(): number;
226+
222227
/**
223228
* Changes the page size used by the data source, discarding any previously-fetched pages.
224229
*

src/data-source/collection-browser-data-source.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
SortField,
2323
SORT_OPTIONS,
2424
} from '../models';
25-
import type { PageSpecifierParams } from './models';
25+
import { FACETLESS_PAGE_ELEMENTS, type PageSpecifierParams } from './models';
2626
import type { CollectionBrowserDataSourceInterface } from './collection-browser-data-source-interface';
2727
import type { CollectionBrowserSearchInterface } from './collection-browser-query-state';
2828
import { sha1 } from '../utils/sha1';
@@ -31,10 +31,21 @@ import { log } from '../utils/log';
3131
export class CollectionBrowserDataSource
3232
implements CollectionBrowserDataSourceInterface
3333
{
34+
/**
35+
* All pages of tile models that have been fetched so far, indexed by their page
36+
* number (with the first being page 1).
37+
*/
3438
private pages: Record<string, TileModel[]> = {};
3539

40+
/**
41+
* Tile offset to apply when looking up tiles in the pages, in order to maintain
42+
* page alignment after tiles are removed.
43+
*/
3644
private offset = 0;
3745

46+
/**
47+
* Total number of tile models stored in this data source's pages
48+
*/
3849
private numTileModels = 0;
3950

4051
/**
@@ -48,10 +59,21 @@ export class CollectionBrowserDataSource
4859
*/
4960
private previousQueryKey: string = '';
5061

62+
/**
63+
* Whether the initial page of search results for the current query state
64+
* is presently being fetched.
65+
*/
5166
private searchResultsLoading = false;
5267

68+
/**
69+
* Whether the facets (aggregations) for the current query state are
70+
* presently being fetched.
71+
*/
5372
private facetsLoading = false;
5473

74+
/**
75+
* Whether further query changes should be ignored and not trigger fetches
76+
*/
5577
private suppressFetches = false;
5678

5779
/**
@@ -265,6 +287,13 @@ export class CollectionBrowserDataSource
265287
return Object.values(this.pages).flat().indexOf(tile);
266288
}
267289

290+
/**
291+
* @inheritdoc
292+
*/
293+
getPageSize(): number {
294+
return this.pageSize;
295+
}
296+
268297
/**
269298
* @inheritdoc
270299
*/
@@ -294,11 +323,15 @@ export class CollectionBrowserDataSource
294323
this._initialSearchCompleteResolver = res;
295324
});
296325

326+
const shouldFetchFacets =
327+
!this.host.suppressFacets &&
328+
!FACETLESS_PAGE_ELEMENTS.includes(this.host.profileElement!);
329+
297330
// Fire the initial page & facet requests
298331
this.queryInitialized = true;
299332
await Promise.all([
300333
this.doInitialPageFetch(),
301-
this.host.suppressFacets ? null : this.fetchFacets(),
334+
shouldFetchFacets ? this.fetchFacets() : null,
302335
]);
303336

304337
// Resolve the `initialSearchComplete` promise for this search
@@ -876,7 +909,7 @@ export class CollectionBrowserDataSource
876909

877910
// Batch multiple initial page requests together if needed (e.g., can request
878911
// pages 1 and 2 together in a single request).
879-
const numPages = pageNumber === 1 ? numInitialPages : 1;
912+
let numPages = pageNumber === 1 ? numInitialPages : 1;
880913
const numRows = this.pageSize * numPages;
881914

882915
// if a fetch is already in progress for this query and page, don't fetch again
@@ -990,7 +1023,16 @@ export class CollectionBrowserDataSource
9901023
}
9911024
}
9921025

993-
// Update the data source for each returned page
1026+
// Update the data source for each returned page.
1027+
// For loans and web archives, we must account for receiving more pages than we asked for.
1028+
if (
1029+
this.host.profileElement === 'lending' ||
1030+
this.host.profileElement === 'web_archives'
1031+
) {
1032+
numPages = Math.ceil(results.length / this.pageSize);
1033+
this.endOfDataReached = true;
1034+
if (this.activeOnHost) this.host.setTileCount(this.totalResults);
1035+
}
9941036
for (let i = 0; i < numPages; i += 1) {
9951037
const pageStartIndex = this.pageSize * i;
9961038
this.addTilesToDataSource(

src/data-source/models.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,12 @@ export type PageSpecifierParams = {
2727
*/
2828
pageElements?: PageElementName[];
2929
};
30+
31+
/**
32+
* List of profile page elements that do not currently allow faceting
33+
*/
34+
export const FACETLESS_PAGE_ELEMENTS: PageElementName[] = [
35+
'forum_posts',
36+
'lending',
37+
'web_archives',
38+
];

test/collection-browser.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,37 @@ describe('Collection Browser', () => {
15621562
expect(el.maxSelectedDate).not.to.exist;
15631563
});
15641564

1565+
it('correctly retrieves web archive hits', async () => {
1566+
const searchService = new MockSearchService();
1567+
const el = await fixture<CollectionBrowser>(
1568+
html`<collection-browser
1569+
.searchService=${searchService}
1570+
.withinProfile=${'@foo'}
1571+
.profileElement=${'web_archives'}
1572+
>
1573+
</collection-browser>`
1574+
);
1575+
1576+
el.baseQuery = 'web-archive';
1577+
await el.updateComplete;
1578+
await el.initialSearchComplete;
1579+
await nextTick();
1580+
1581+
console.log(
1582+
'\n\n*****\n\n*****\n\n',
1583+
el.dataSource.getAllPages(),
1584+
'\n\n*****\n\n*****\n\n'
1585+
);
1586+
expect(el.dataSource.totalResults, 'total results').to.equal(1);
1587+
expect(el.dataSource.getTileModelAt(0)?.title).to.equal(
1588+
'https://example.com'
1589+
);
1590+
expect(
1591+
el.dataSource.getTileModelAt(0)?.captureDates?.length,
1592+
'capture dates'
1593+
).to.equal(1);
1594+
});
1595+
15651596
it('shows temporarily unavailable message when facets suppressed', async () => {
15661597
const searchService = new MockSearchService();
15671598
const el = await fixture<CollectionBrowser>(

test/data-source/collection-browser-data-source.test.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect, fixture } from '@open-wc/testing';
22
import { html } from 'lit';
3+
import sinon from 'sinon';
34
import { ItemHit, SearchType } from '@internetarchive/search-service';
45
import { CollectionBrowserDataSource } from '../../src/data-source/collection-browser-data-source';
56
import { TileModel } from '../../src/models';
67
import type { CollectionBrowser } from '../../src/collection-browser';
78
import '../../src/collection-browser';
9+
import { MockSearchService } from '../mocks/mock-search-service';
810

911
const dataPage: TileModel[] = [
1012
new TileModel(
@@ -32,7 +34,7 @@ describe('Collection Browser Data Source', () => {
3234
`);
3335
});
3436

35-
it('can add and retrieve data pages', async () => {
37+
it('can add and retrieve data pages', () => {
3638
const dataSource = new CollectionBrowserDataSource(host);
3739
dataSource.addPage(1, dataPage);
3840

@@ -42,12 +44,13 @@ describe('Collection Browser Data Source', () => {
4244
expect(dataSource.getPage(1)[1].identifier).to.equal('bar');
4345
});
4446

45-
it('resets data when changing page size', async () => {
47+
it('resets data when changing page size', () => {
4648
const dataSource = new CollectionBrowserDataSource(host);
4749
dataSource.addPage(1, dataPage);
4850

4951
dataSource.setPageSize(100);
5052
expect(Object.keys(dataSource.getAllPages()).length).to.equal(0);
53+
expect(dataSource.getPageSize()).to.equal(100);
5154
});
5255

5356
it('can be installed on the host', async () => {
@@ -70,7 +73,21 @@ describe('Collection Browser Data Source', () => {
7073
host.removeController(dataSource);
7174
});
7275

73-
it('refreshes prefix filter counts', async () => {
76+
it('can suppress further fetches', async () => {
77+
host.searchService = new MockSearchService();
78+
79+
const pageFetchSpy = sinon.spy();
80+
const dataSource = new CollectionBrowserDataSource(host);
81+
dataSource.fetchPage = pageFetchSpy;
82+
83+
dataSource.addPage(1, dataPage);
84+
dataSource.setFetchesSuppressed(true);
85+
dataSource.handleQueryChange();
86+
87+
expect(pageFetchSpy.callCount).to.equal(0);
88+
});
89+
90+
it('refreshes prefix filter counts', () => {
7491
const dataSource = new CollectionBrowserDataSource(host);
7592
dataSource.addPage(1, dataPage);
7693

test/mocks/mock-search-responses.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
SearchServiceError,
77
TextHit,
88
} from '@internetarchive/search-service';
9+
import { WebArchiveHit } from '@internetarchive/search-service/dist/src/models/hit-types/web-archive-hit';
910
import { SearchServiceErrorType } from '@internetarchive/search-service/dist/src/search-service-error';
1011

1112
export const getMockSuccessSingleResult: () => Result<
@@ -876,6 +877,49 @@ export const getMockSuccessWithParentCollections: () => Result<
876877
},
877878
});
878879

880+
export const getMockSuccessWithWebArchiveHits: () => Result<
881+
SearchResponse,
882+
SearchServiceError
883+
> = () => ({
884+
success: {
885+
request: {
886+
kind: 'hits',
887+
clientParameters: {
888+
user_query: 'web-archive',
889+
sort: [],
890+
},
891+
backendRequests: {
892+
primary: {
893+
kind: 'hits',
894+
finalized_parameters: {
895+
user_query: 'web-archive',
896+
sort: [],
897+
},
898+
},
899+
},
900+
},
901+
rawResponse: {},
902+
response: {
903+
totalResults: 1,
904+
returnedCount: 1,
905+
results: [
906+
new WebArchiveHit({
907+
fields: {
908+
url: 'https://example.com',
909+
capture_dates: ['2010-01-02T03:04:05Z'],
910+
__href__:
911+
'https://web.archive.org/web/20100102030405/https%3A%2F%2Fexample.com',
912+
},
913+
}),
914+
],
915+
},
916+
responseHeader: {
917+
succeeded: true,
918+
query_time: 0,
919+
},
920+
},
921+
});
922+
879923
export const getMockErrorResult: () => Result<
880924
SearchResponse,
881925
SearchServiceError

test/mocks/mock-search-service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
getMockSuccessWithParentCollections,
2929
getMockSuccessManyFields,
3030
getMockSuccessNoResults,
31+
getMockSuccessWithWebArchiveHits,
3132
} from './mock-search-responses';
3233

3334
const responses: Record<
@@ -49,6 +50,7 @@ const responses: Record<
4950
'default-sort-concise': getMockSuccessWithConciseDefaultSort,
5051
'fav-sort': getMockSuccessWithDefaultFavSort,
5152
'parent-collections': getMockSuccessWithParentCollections,
53+
'web-archive': getMockSuccessWithWebArchiveHits,
5254
'many-fields': getMockSuccessManyFields,
5355
'no-results': getMockSuccessNoResults,
5456
error: getMockErrorResult,

0 commit comments

Comments
 (0)