@internetarchive/collection-browser 0.4.13 → 0.4.14-alpha.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 +4 -4
- package/dist/src/collection-browser.js +22 -23
- package/dist/src/collection-browser.js.map +1 -1
- package/dist/src/restoration-state-handler.js +24 -12
- package/dist/src/restoration-state-handler.js.map +1 -1
- package/dist/src/utils/array-equals.d.ts +4 -0
- package/dist/src/utils/array-equals.js +11 -0
- package/dist/src/utils/array-equals.js.map +1 -0
- package/dist/test/collection-browser.test.js +7 -7
- package/dist/test/collection-browser.test.js.map +1 -1
- package/dist/test/utils/array-equals.test.d.ts +1 -0
- package/dist/test/utils/array-equals.test.js +27 -0
- package/dist/test/utils/array-equals.test.js.map +1 -0
- package/package.json +1 -1
- package/src/collection-browser.ts +26 -26
- package/src/restoration-state-handler.ts +38 -14
- package/src/utils/array-equals.ts +8 -0
- package/test/collection-browser.test.ts +7 -7
- package/test/utils/array-equals.test.ts +31 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SearchType, } from '@internetarchive/search-service';
|
|
2
2
|
import { getCookie, setCookie } from 'typescript-cookie';
|
|
3
3
|
import { MetadataFieldToSortField, } from './models';
|
|
4
|
+
import { arrayEquals } from './utils/array-equals';
|
|
4
5
|
export class RestorationStateHandler {
|
|
5
6
|
constructor(options) {
|
|
6
7
|
this.cookieDomain = '.archive.org';
|
|
@@ -45,22 +46,19 @@ export class RestorationStateHandler {
|
|
|
45
46
|
persistQueryStateToUrl(state) {
|
|
46
47
|
const url = new URL(window.location.href);
|
|
47
48
|
const { searchParams } = url;
|
|
48
|
-
searchParams
|
|
49
|
-
searchParams.delete('sort');
|
|
49
|
+
const oldParams = new URLSearchParams(searchParams);
|
|
50
50
|
searchParams.delete('query');
|
|
51
|
+
searchParams.delete('sin');
|
|
51
52
|
searchParams.delete('page');
|
|
53
|
+
searchParams.delete('sort');
|
|
52
54
|
searchParams.delete('and[]');
|
|
53
55
|
searchParams.delete('not[]');
|
|
54
|
-
if (state.searchType) {
|
|
55
|
-
searchParams.set('sin', state.searchType === SearchType.FULLTEXT ? 'TXT' : '');
|
|
56
|
-
}
|
|
57
|
-
if (state.sortParam) {
|
|
58
|
-
const prefix = state.sortParam.direction === 'desc' ? '-' : '';
|
|
59
|
-
searchParams.set('sort', `${prefix}${state.sortParam.field}`);
|
|
60
|
-
}
|
|
61
56
|
if (state.baseQuery) {
|
|
62
57
|
searchParams.set('query', state.baseQuery);
|
|
63
58
|
}
|
|
59
|
+
if (state.searchType) {
|
|
60
|
+
searchParams.set('sin', state.searchType === SearchType.FULLTEXT ? 'TXT' : '');
|
|
61
|
+
}
|
|
64
62
|
if (state.currentPage) {
|
|
65
63
|
if (state.currentPage > 1) {
|
|
66
64
|
searchParams.set('page', state.currentPage.toString());
|
|
@@ -69,6 +67,10 @@ export class RestorationStateHandler {
|
|
|
69
67
|
searchParams.delete('page');
|
|
70
68
|
}
|
|
71
69
|
}
|
|
70
|
+
if (state.sortParam) {
|
|
71
|
+
const prefix = state.sortParam.direction === 'desc' ? '-' : '';
|
|
72
|
+
searchParams.set('sort', `${prefix}${state.sortParam.field}`);
|
|
73
|
+
}
|
|
72
74
|
if (state.selectedFacets) {
|
|
73
75
|
for (const [facetName, facetValues] of Object.entries(state.selectedFacets)) {
|
|
74
76
|
const facetEntries = Object.entries(facetValues);
|
|
@@ -96,14 +98,24 @@ export class RestorationStateHandler {
|
|
|
96
98
|
if (state.creatorQuery) {
|
|
97
99
|
searchParams.append('and[]', state.creatorQuery);
|
|
98
100
|
}
|
|
101
|
+
// Ensure we aren't pushing an identical state to the stack.
|
|
102
|
+
// Note: page number is not included in this condition, because we
|
|
103
|
+
// don't want a separate history entry for each page scrolled through.
|
|
104
|
+
if (oldParams.get('query') === searchParams.get('query') &&
|
|
105
|
+
oldParams.get('sin') === searchParams.get('sin') &&
|
|
106
|
+
oldParams.get('sort') === searchParams.get('sort') &&
|
|
107
|
+
arrayEquals(oldParams.getAll('and[]').sort(), searchParams.getAll('and[]').sort()) &&
|
|
108
|
+
arrayEquals(oldParams.getAll('not[]').sort(), searchParams.getAll('not[]').sort())) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
99
111
|
window.history.pushState({
|
|
100
|
-
sort: state.sortParam,
|
|
101
112
|
query: state.baseQuery,
|
|
113
|
+
searchType: state.searchType,
|
|
102
114
|
page: state.currentPage,
|
|
103
|
-
|
|
104
|
-
not: state.selectedFacets,
|
|
115
|
+
sort: state.sortParam,
|
|
105
116
|
minDate: state.minSelectedDate,
|
|
106
117
|
maxDate: state.maxSelectedDate,
|
|
118
|
+
facets: state.selectedFacets,
|
|
107
119
|
}, '', url);
|
|
108
120
|
}
|
|
109
121
|
loadQueryStateFromUrl() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n MetadataFieldToSortField,\n MetadataSortField,\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n} from './models';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n sortParam?: SortParam;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(state: RestorationState): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(state: RestorationState): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(state: RestorationState) {\n const url = new URL(window.location.href);\n const { searchParams } = url;\n searchParams.delete('sin');\n searchParams.delete('sort');\n searchParams.delete('query');\n searchParams.delete('page');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n if (state.searchType) {\n searchParams.set(\n 'sin',\n state.searchType === SearchType.FULLTEXT ? 'TXT' : ''\n );\n }\n\n if (state.sortParam) {\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\n searchParams.set('sort', `${prefix}${state.sortParam.field}`);\n }\n\n if (state.baseQuery) {\n searchParams.set('query', state.baseQuery);\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n searchParams.set('page', state.currentPage.toString());\n } else {\n searchParams.delete('page');\n }\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets\n )) {\n const facetEntries = Object.entries(facetValues);\n // eslint-disable-next-line no-continue\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n searchParams.append('not[]', paramValue);\n } else {\n searchParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n searchParams.append(\n 'and[]',\n `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`\n );\n }\n if (state.titleQuery) {\n searchParams.append('and[]', state.titleQuery);\n }\n if (state.creatorQuery) {\n searchParams.append('and[]', state.creatorQuery);\n }\n\n window.history.pushState(\n {\n sort: state.sortParam,\n query: state.baseQuery,\n page: state.currentPage,\n and: state.selectedFacets,\n not: state.selectedFacets,\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n },\n '',\n url\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n const restorationState: RestorationState = {\n selectedFacets: {\n subject: {},\n lending: {},\n creator: {},\n mediatype: {},\n language: {},\n collection: {},\n year: {},\n },\n };\n\n if (searchInside) {\n restorationState.searchType =\n searchInside === 'TXT' ? SearchType.FULLTEXT : SearchType.METADATA;\n }\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n }\n if (sortQuery) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortQuery.indexOf(' ') > -1;\n if (hasSpace) {\n const [field, direction] = sortQuery.split(' ');\n const metadataField =\n MetadataFieldToSortField[field as MetadataSortField];\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n }\n if (direction === 'desc' || direction === 'asc') {\n restorationState.sortDirection = direction as SortDirection;\n }\n } else {\n const sortDirection = sortQuery.startsWith('-') ? 'desc' : 'asc';\n const sortField = sortQuery.startsWith('-')\n ? sortQuery.slice(1)\n : sortQuery;\n const metadataField =\n MetadataFieldToSortField[sortField as MetadataSortField];\n if (metadataField) restorationState.selectedSort = metadataField;\n restorationState.sortDirection = sortDirection as SortDirection;\n }\n }\n if (facetAnds) {\n facetAnds.forEach(and => {\n const [field, value] = and.split(':');\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n });\n }\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden'\n );\n });\n }\n return restorationState;\n }\n\n // remove optional opening and closing quotes from a string\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n return value;\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState\n ): void {\n const facet = selectedFacets[field];\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"restoration-state-handler.js","sourceRoot":"","sources":["../../src/restoration-state-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SearchType,\n SortDirection,\n SortParam,\n} from '@internetarchive/search-service';\nimport { getCookie, setCookie } from 'typescript-cookie';\nimport {\n MetadataFieldToSortField,\n MetadataSortField,\n FacetOption,\n CollectionBrowserContext,\n CollectionDisplayMode,\n SelectedFacets,\n SortField,\n FacetBucket,\n FacetState,\n} from './models';\nimport { arrayEquals } from './utils/array-equals';\n\nexport interface RestorationState {\n displayMode?: CollectionDisplayMode;\n searchType?: SearchType;\n sortParam?: SortParam;\n selectedSort?: SortField;\n sortDirection?: SortDirection;\n selectedFacets: SelectedFacets;\n baseQuery?: string;\n currentPage?: number;\n titleQuery?: string;\n creatorQuery?: string;\n minSelectedDate?: string;\n maxSelectedDate?: string;\n selectedTitleFilter?: string;\n selectedCreatorFilter?: string;\n}\n\nexport interface RestorationStateHandlerInterface {\n persistState(state: RestorationState): void;\n getRestorationState(): RestorationState;\n}\n\nexport class RestorationStateHandler\n implements RestorationStateHandlerInterface\n{\n private context: CollectionBrowserContext;\n\n private cookieDomain = '.archive.org';\n\n private cookieExpiration = 30;\n\n private cookiePath = '/';\n\n constructor(options: { context: CollectionBrowserContext }) {\n this.context = options.context;\n }\n\n persistState(state: RestorationState): void {\n if (state.displayMode) this.persistViewStateToCookies(state.displayMode);\n this.persistQueryStateToUrl(state);\n }\n\n getRestorationState(): RestorationState {\n const restorationState = this.loadQueryStateFromUrl();\n const displayMode = this.loadTileViewStateFromCookies();\n restorationState.displayMode = displayMode;\n return restorationState;\n }\n\n private persistViewStateToCookies(displayMode: CollectionDisplayMode) {\n const gridState = displayMode === 'grid' ? 'tiles' : 'lists';\n setCookie(`view-${this.context}`, gridState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n const detailsState = displayMode === 'list-detail' ? 'showdetails' : '';\n setCookie(`showdetails-${this.context}`, detailsState, {\n domain: this.cookieDomain,\n expires: this.cookieExpiration,\n path: this.cookiePath,\n });\n }\n\n private loadTileViewStateFromCookies(): CollectionDisplayMode {\n const viewState = getCookie(`view-${this.context}`);\n const detailsState = getCookie(`showdetails-${this.context}`);\n if (viewState === 'tiles' || viewState === undefined) return 'grid';\n if (detailsState === 'showdetails') return 'list-detail';\n return 'list-compact';\n }\n\n private persistQueryStateToUrl(state: RestorationState) {\n const url = new URL(window.location.href);\n const { searchParams } = url;\n const oldParams = new URLSearchParams(searchParams);\n\n searchParams.delete('query');\n searchParams.delete('sin');\n searchParams.delete('page');\n searchParams.delete('sort');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n\n if (state.baseQuery) {\n searchParams.set('query', state.baseQuery);\n }\n\n if (state.searchType) {\n searchParams.set(\n 'sin',\n state.searchType === SearchType.FULLTEXT ? 'TXT' : ''\n );\n }\n\n if (state.currentPage) {\n if (state.currentPage > 1) {\n searchParams.set('page', state.currentPage.toString());\n } else {\n searchParams.delete('page');\n }\n }\n\n if (state.sortParam) {\n const prefix = state.sortParam.direction === 'desc' ? '-' : '';\n searchParams.set('sort', `${prefix}${state.sortParam.field}`);\n }\n\n if (state.selectedFacets) {\n for (const [facetName, facetValues] of Object.entries(\n state.selectedFacets\n )) {\n const facetEntries = Object.entries(facetValues);\n // eslint-disable-next-line no-continue\n if (facetEntries.length === 0) continue;\n for (const [key, data] of facetEntries) {\n const notValue = data.state === 'hidden';\n const paramValue = `${facetName}:\"${key}\"`;\n if (notValue) {\n searchParams.append('not[]', paramValue);\n } else {\n searchParams.append('and[]', paramValue);\n }\n }\n }\n }\n\n if (state.minSelectedDate && state.maxSelectedDate) {\n searchParams.append(\n 'and[]',\n `year:[${state.minSelectedDate} TO ${state.maxSelectedDate}]`\n );\n }\n\n if (state.titleQuery) {\n searchParams.append('and[]', state.titleQuery);\n }\n\n if (state.creatorQuery) {\n searchParams.append('and[]', state.creatorQuery);\n }\n\n // Ensure we aren't pushing an identical state to the stack.\n // Note: page number is not included in this condition, because we\n // don't want a separate history entry for each page scrolled through.\n if (\n oldParams.get('query') === searchParams.get('query') &&\n oldParams.get('sin') === searchParams.get('sin') &&\n oldParams.get('sort') === searchParams.get('sort') &&\n arrayEquals(\n oldParams.getAll('and[]').sort(),\n searchParams.getAll('and[]').sort()\n ) &&\n arrayEquals(\n oldParams.getAll('not[]').sort(),\n searchParams.getAll('not[]').sort()\n )\n ) {\n return;\n }\n\n window.history.pushState(\n {\n query: state.baseQuery,\n searchType: state.searchType,\n page: state.currentPage,\n sort: state.sortParam,\n minDate: state.minSelectedDate,\n maxDate: state.maxSelectedDate,\n facets: state.selectedFacets,\n },\n '',\n url\n );\n }\n\n private loadQueryStateFromUrl(): RestorationState {\n const url = new URL(window.location.href);\n const searchInside = url.searchParams.get('sin');\n const pageNumber = url.searchParams.get('page');\n const searchQuery = url.searchParams.get('query');\n const sortQuery = url.searchParams.get('sort');\n const facetAnds = url.searchParams.getAll('and[]');\n const facetNots = url.searchParams.getAll('not[]');\n\n const restorationState: RestorationState = {\n selectedFacets: {\n subject: {},\n lending: {},\n creator: {},\n mediatype: {},\n language: {},\n collection: {},\n year: {},\n },\n };\n\n if (searchInside) {\n restorationState.searchType =\n searchInside === 'TXT' ? SearchType.FULLTEXT : SearchType.METADATA;\n }\n if (pageNumber) {\n const parsed = parseInt(pageNumber, 10);\n restorationState.currentPage = parsed;\n } else {\n restorationState.currentPage = 1;\n }\n if (searchQuery) {\n restorationState.baseQuery = searchQuery;\n }\n if (sortQuery) {\n // check for two different sort formats: `date desc` and `-date`\n const hasSpace = sortQuery.indexOf(' ') > -1;\n if (hasSpace) {\n const [field, direction] = sortQuery.split(' ');\n const metadataField =\n MetadataFieldToSortField[field as MetadataSortField];\n if (metadataField) {\n restorationState.selectedSort = metadataField;\n }\n if (direction === 'desc' || direction === 'asc') {\n restorationState.sortDirection = direction as SortDirection;\n }\n } else {\n const sortDirection = sortQuery.startsWith('-') ? 'desc' : 'asc';\n const sortField = sortQuery.startsWith('-')\n ? sortQuery.slice(1)\n : sortQuery;\n const metadataField =\n MetadataFieldToSortField[sortField as MetadataSortField];\n if (metadataField) restorationState.selectedSort = metadataField;\n restorationState.sortDirection = sortDirection as SortDirection;\n }\n }\n if (facetAnds) {\n facetAnds.forEach(and => {\n const [field, value] = and.split(':');\n\n switch (field) {\n case 'year': {\n const [minDate, maxDate] = value.split(' TO ');\n // we have two potential ways of filtering by date:\n // the range with \"date TO date\" or the single date with \"date\"\n // this is checking for the range case and if we don't have those, fall\n // back to the single date case\n if (minDate && maxDate) {\n restorationState.minSelectedDate = minDate.substring(\n 1,\n minDate.length\n );\n restorationState.maxSelectedDate = maxDate.substring(\n 0,\n maxDate.length - 1\n );\n } else {\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n break;\n }\n case 'firstTitle':\n restorationState.selectedTitleFilter = value;\n break;\n case 'firstCreator':\n restorationState.selectedCreatorFilter = value;\n break;\n default:\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'selected'\n );\n }\n });\n }\n if (facetNots) {\n facetNots.forEach(not => {\n const [field, value] = not.split(':');\n this.setSelectedFacetState(\n restorationState.selectedFacets,\n field as FacetOption,\n value,\n 'hidden'\n );\n });\n }\n return restorationState;\n }\n\n // remove optional opening and closing quotes from a string\n private stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.substring(1, value.length - 1);\n }\n return value;\n }\n\n /**\n * Sets the facet state for the given field & value to the given state,\n * creating any previously-undefined buckets as needed.\n */\n private setSelectedFacetState(\n selectedFacets: SelectedFacets,\n field: FacetOption,\n value: string,\n state: FacetState\n ): void {\n const facet = selectedFacets[field];\n const unQuotedValue = this.stripQuotes(value);\n facet[unQuotedValue] ??= this.getDefaultBucket(value);\n facet[unQuotedValue].state = state;\n }\n\n /** Returns a default bucket with the given key, count of 0, and state 'none'. */\n private getDefaultBucket(key: string): FacetBucket {\n return {\n key,\n count: 0,\n state: 'none',\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines whether two arrays have the same (shallow) contents in the same order
|
|
3
|
+
*/
|
|
4
|
+
export function arrayEquals(arr1, arr2) {
|
|
5
|
+
if (arr1 === arr2)
|
|
6
|
+
return true;
|
|
7
|
+
if (arr1.length !== arr2.length)
|
|
8
|
+
return false;
|
|
9
|
+
return arr1.every((val, i) => val === arr2[i]);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=array-equals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-equals.js","sourceRoot":"","sources":["../../../src/utils/array-equals.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAe,EAAE,IAAe;IAC1D,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC","sourcesContent":["/**\n * Determines whether two arrays have the same (shallow) contents in the same order\n */\nexport function arrayEquals(arr1: unknown[], arr2: unknown[]): boolean {\n if (arr1 === arr2) return true;\n if (arr1.length !== arr2.length) return false;\n return arr1.every((val, i) => val === arr2[i]);\n}\n"]}
|
|
@@ -43,10 +43,10 @@ describe('Collection Browser', () => {
|
|
|
43
43
|
el.clearFilters();
|
|
44
44
|
expect(el.selectedFacets).to.equal(defaultSelectedFacets);
|
|
45
45
|
expect(el.selectedSort).to.equal('relevance');
|
|
46
|
-
expect(el.sortDirection).to.
|
|
47
|
-
expect(el.sortParam).to.
|
|
48
|
-
expect(el.selectedCreatorFilter).to.
|
|
49
|
-
expect(el.selectedTitleFilter).to.
|
|
46
|
+
expect(el.sortDirection).to.be.undefined;
|
|
47
|
+
expect(el.sortParam).to.be.undefined;
|
|
48
|
+
expect(el.selectedCreatorFilter).to.be.undefined;
|
|
49
|
+
expect(el.selectedTitleFilter).to.be.undefined;
|
|
50
50
|
});
|
|
51
51
|
it('filterBy creator with analytics', async () => {
|
|
52
52
|
const mockAnalyticsHandler = new MockAnalyticsHandler();
|
|
@@ -62,7 +62,7 @@ describe('Collection Browser', () => {
|
|
|
62
62
|
expect(mockAnalyticsHandler.callLabel).to.equal('start-A');
|
|
63
63
|
el.clearFilters();
|
|
64
64
|
await el.updateComplete;
|
|
65
|
-
expect(el.selectedTitleFilter).to.
|
|
65
|
+
expect(el.selectedTitleFilter).to.be.undefined;
|
|
66
66
|
expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');
|
|
67
67
|
expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');
|
|
68
68
|
expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');
|
|
@@ -81,7 +81,7 @@ describe('Collection Browser', () => {
|
|
|
81
81
|
expect(mockAnalyticsHandler.callLabel).to.equal('start-A');
|
|
82
82
|
el.clearFilters();
|
|
83
83
|
await el.updateComplete;
|
|
84
|
-
expect(el.selectedTitleFilter).to.
|
|
84
|
+
expect(el.selectedTitleFilter).to.be.undefined;
|
|
85
85
|
expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');
|
|
86
86
|
expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');
|
|
87
87
|
expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');
|
|
@@ -409,7 +409,7 @@ describe('Collection Browser', () => {
|
|
|
409
409
|
el.baseQuery = 'with-sort';
|
|
410
410
|
await el.updateComplete;
|
|
411
411
|
const fetchPromise = el.fetchPage(2);
|
|
412
|
-
el.sortParam =
|
|
412
|
+
el.sortParam = undefined;
|
|
413
413
|
await fetchPromise;
|
|
414
414
|
// If the different sort param causes the results to be discarded,
|
|
415
415
|
// the results array should never be read.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection-browser.test.js","sourceRoot":"","sources":["../../test/collection-browser.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable import/no-duplicates */\nimport { expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\nimport sinon from 'sinon';\nimport type { InfiniteScroller } from '@internetarchive/infinite-scroller';\nimport { SearchType } from '@internetarchive/search-service';\nimport type { HistogramDateRange } from '@internetarchive/histogram-date-range';\nimport type { CollectionBrowser } from '../src/collection-browser';\nimport '../src/collection-browser';\nimport {\n defaultSelectedFacets,\n FacetBucket,\n SelectedFacets,\n SortField,\n} from '../src/models';\nimport { MockSearchService } from './mocks/mock-search-service';\nimport { MockCollectionNameCache } from './mocks/mock-collection-name-cache';\nimport { MockAnalyticsHandler } from './mocks/mock-analytics-handler';\nimport { analyticsCategories } from '../src/utils/analytics-events';\nimport type { TileDispatcher } from '../src/tiles/tile-dispatcher';\nimport type { CollectionFacets } from '../src/collection-facets';\n\n/**\n * Wait for the next tick of the event loop.\n *\n * This is necessary in some of the tests because certain collection browser\n * updates take more than one tick to render (e.g., date picker & query changes).\n * These delays are non-ideal and should eventually be investigated and fixed,\n * but they are minor enough that waiting for the next tick is a reasonable\n * testing solution for now.\n */\nconst nextTick = () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n });\n\ndescribe('Collection Browser', () => {\n beforeEach(async () => {\n // Apparently query params set by one test can bleed into other tests.\n // Since collection browser restores its state from certain query params, we need\n // to clear these before each test to ensure they run in isolation from one another.\n const url = new URL(window.location.href);\n const { searchParams } = url;\n searchParams.delete('sin');\n searchParams.delete('sort');\n searchParams.delete('query');\n searchParams.delete('page');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n window.history.replaceState({}, '', url);\n });\n\n it('clear existing filter for facets & sort-bar', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n el.selectedSort = 'title' as SortField;\n await el.updateComplete;\n el.clearFilters();\n\n expect(el.selectedFacets).to.equal(defaultSelectedFacets);\n expect(el.selectedSort).to.equal('relevance');\n expect(el.sortDirection).to.null;\n expect(el.sortParam).to.null;\n expect(el.selectedCreatorFilter).to.null;\n expect(el.selectedTitleFilter).to.null;\n });\n\n it('filterBy creator with analytics', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'betaSearchService';\n el.selectedSort = 'creator' as SortField;\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'A';\n await el.updateComplete;\n\n expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');\n expect(mockAnalyticsHandler.callLabel).to.equal('start-A');\n\n el.clearFilters();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.null;\n expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');\n expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');\n });\n\n it('filterBy title with analytics', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'beta-search-service';\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n el.selectedTitleFilter = 'A';\n await el.updateComplete;\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');\n expect(mockAnalyticsHandler.callLabel).to.equal('start-A');\n\n el.clearFilters();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.null;\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');\n expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');\n });\n\n it('selected facets with analytics - not negative facets', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const mediaTypeBucket = { count: 123, state: 'selected' } as FacetBucket;\n const mockedSelectedFacets: SelectedFacets = {\n subject: {},\n lending: {},\n mediatype: { data: mediaTypeBucket },\n language: {},\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'search-service';\n el.selectedFacets = mockedSelectedFacets;\n await el.updateComplete;\n\n el.facetClickHandler('mediatype', true, false);\n expect(mockAnalyticsHandler.callCategory).to.equal('search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetSelected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n\n el.facetClickHandler('mediatype', false, false);\n expect(el.selectedFacets).to.equal(mockedSelectedFacets);\n expect(mockAnalyticsHandler.callCategory).to.equal('search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetDeselected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n });\n\n it('selected facets with analytics - negative facets', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const mediaTypeBucket = { count: 123, state: 'selected' } as FacetBucket;\n const mockedSelectedFacets: SelectedFacets = {\n subject: {},\n lending: {},\n mediatype: { data: mediaTypeBucket },\n language: {},\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'beta-search-service';\n el.selectedFacets = mockedSelectedFacets;\n await el.updateComplete;\n\n el.facetClickHandler('mediatype', true, true);\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeSelected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n\n el.facetClickHandler('mediatype', false, true);\n expect(el.selectedFacets).to.equal(mockedSelectedFacets);\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeDeselected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n });\n\n it('should render with a sort bar, facets, and infinite scroller', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'hello';\n await el.updateComplete;\n\n const facets = el.shadowRoot?.querySelector('collection-facets');\n const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');\n const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');\n expect(facets).to.exist;\n expect(sortBar).to.exist;\n expect(infiniteScroller).to.exist;\n });\n\n it('queries the search service when given a base query', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with a metadata search', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html` <collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.METADATA}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchType).to.equal(SearchType.METADATA);\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with a fulltext search', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html` <collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.FULLTEXT}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchType).to.equal(SearchType.FULLTEXT);\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with facets selected/negated', async () => {\n const searchService = new MockSearchService();\n const selectedFacets: SelectedFacets = {\n subject: {\n foo: {\n key: 'foo',\n count: 1,\n state: 'selected',\n },\n bar: {\n key: 'bar',\n count: 2,\n state: 'hidden',\n },\n },\n lending: {},\n mediatype: {},\n language: {\n en: {\n key: 'en',\n count: 1,\n state: 'selected',\n },\n },\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n el.selectedFacets = selectedFacets;\n await el.updateComplete;\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchParams?.filters).to.deep.equal({\n subject: {\n foo: 'inc',\n bar: 'exc',\n },\n language: {\n en: 'inc',\n },\n });\n });\n\n it('fails gracefully if no search service provided', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n // This shouldn't throw an error\n expect(el.fetchPage(2)).to.exist;\n\n // Should continue showing the empty placeholder\n expect(el.shadowRoot?.querySelector('empty-placeholder')).to.exist;\n });\n\n it('restores search type from URL param', async () => {\n // Add a sin=TXT param to the URL\n const url = new URL(window.location.href);\n url.searchParams.append('sin', 'TXT');\n window.history.replaceState({}, '', url);\n\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n expect(el.searchType).to.equal(SearchType.FULLTEXT);\n });\n\n it('applies loggedin flag to tile models if needed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'loggedin';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.loginRequired).to.be.true;\n });\n\n it('applies no-preview flag to tile models if needed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'no-preview';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.contentWarning).to.be.true;\n });\n\n it('both loggedin and no-preview flags can be set simultaneously', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'loggedin-no-preview';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.loginRequired).to.be.true;\n expect(cell.model?.contentWarning).to.be.true;\n });\n\n it('joins full description array into a single string with line breaks', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n // This query receives an array description like ['line1', 'line2']\n el.baseQuery = 'multi-line-description';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n // Actual model description should be joined\n expect(cell.model?.description).to.equal('line1\\nline2');\n });\n\n it('can search on demand if only search type has changed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.METADATA}\n ></collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n el.searchType = SearchType.FULLTEXT;\n await el.updateComplete;\n\n // Haven't performed the search yet\n expect(searchService.searchType).to.equal(SearchType.METADATA);\n\n el.requestSearch();\n expect(searchService.searchType).to.equal(SearchType.FULLTEXT);\n });\n\n it('queries for collection names after a fetch', async () => {\n const searchService = new MockSearchService();\n const collectionNameCache = new MockCollectionNameCache();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .searchService=${searchService}\n .collectionNameCache=${collectionNameCache}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n expect(collectionNameCache.preloadIdentifiersRequested).to.deep.equal([\n 'foo',\n 'bar',\n 'baz',\n 'boop',\n ]);\n });\n\n it('keeps search results from fetch if no change to query or sort param', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n el.sortParam = { field: 'foo', direction: 'asc' };\n await el.updateComplete;\n\n await el.fetchPage(2);\n\n // If there is no change to the query or sort param during the fetch, the results\n // should be read.\n expect(resultsSpy.callCount).to.be.greaterThanOrEqual(1);\n });\n\n it('discards obsolete search results if sort params changed before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n el.sortParam = { field: 'foo', direction: 'asc' };\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = { field: 'foo', direction: 'desc' };\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('discards obsolete search results if sort param added before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'single-result';\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = { field: 'foo', direction: 'asc' };\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('discards obsolete search results if sort param cleared before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = null;\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('sets sort properties when user changes sort', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n expect(el.selectedSort).to.equal(SortField.relevance);\n\n el.baseQuery = 'foo';\n await el.updateComplete;\n\n const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');\n const sortSelector = sortBar?.shadowRoot?.querySelector(\n '#desktop-sort-selector'\n );\n expect(sortSelector).to.exist;\n\n // Click the title sorter\n [...(sortSelector?.children as HTMLCollection & Iterable<any>)] // tsc doesn't know children is iterable\n .find(child => child.textContent?.trim() === 'Title')\n ?.querySelector('a[href]')\n ?.click();\n\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal(SortField.title);\n });\n\n it('sets sort filter properties when user selects title filter', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-title';\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n el.selectedTitleFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-title AND firstTitle:X'\n );\n });\n\n it('sets sort filter properties when user selects creator filter', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-creator';\n el.selectedSort = 'creator' as SortField;\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-creator AND firstCreator:X'\n );\n });\n\n it('sets sort filter properties simultaneous with facets and date range', async () => {\n const searchService = new MockSearchService();\n const selectedFacets: SelectedFacets = {\n collection: { foo: { key: 'foo', state: 'selected', count: 1 } },\n creator: {},\n language: {},\n lending: {},\n mediatype: {},\n subject: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-creator';\n el.selectedSort = 'creator' as SortField;\n el.selectedFacets = selectedFacets;\n el.minSelectedDate = '1950';\n el.maxSelectedDate = '1970';\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-creator AND firstCreator:X'\n );\n expect(searchService.searchParams?.filters).to.deep.equal({\n collection: {\n foo: 'inc',\n },\n year: {\n '1950': 'gte',\n '1970': 'lte',\n },\n });\n });\n\n it('sets date range query when date picker selection changed', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'years'; // Includes year_histogram aggregation in response\n el.showHistogramDatePicker = true;\n await el.updateComplete;\n\n const facets = el.shadowRoot?.querySelector(\n 'collection-facets'\n ) as CollectionFacets;\n await facets?.updateComplete;\n\n // Wait for the date picker to be rendered (which may take until the next tick)\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n const histogram = facets?.shadowRoot?.querySelector(\n 'histogram-date-range'\n ) as HistogramDateRange;\n expect(histogram).to.exist;\n\n // Enter a new min date into the date picker\n const minDateInput = histogram.shadowRoot?.querySelector(\n '#date-min'\n ) as HTMLInputElement;\n\n const pressEnterEvent = new KeyboardEvent('keyup', {\n key: 'Enter',\n });\n\n minDateInput.value = '1960';\n minDateInput.dispatchEvent(pressEnterEvent);\n\n // Wait for the histogram's update delay\n await new Promise(res => {\n setTimeout(res, histogram.updateDelay + 50);\n });\n\n // Ensure that the histogram change propagated to the collection browser's\n // date query correctly.\n await el.updateComplete;\n expect(el.minSelectedDate).to.equal('1960');\n expect(el.maxSelectedDate).to.equal('2000');\n });\n\n it('scrolls to page', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n // Infinite scroller won't exist unless there's a base query.\n // First ensure that we don't throw errors when it doesn't exist.\n await el.goToPage(1);\n\n // And make sure it correctly calls scrollToCell when the\n // infinite scroller does exist.\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n const infiniteScroller = el.shadowRoot?.querySelector(\n 'infinite-scroller'\n ) as InfiniteScroller;\n expect(infiniteScroller).to.exist;\n\n const oldScrollToCell = infiniteScroller.scrollToCell;\n const spy = sinon.spy();\n infiniteScroller.scrollToCell = spy;\n\n await el.goToPage(1);\n\n expect(spy.callCount).to.equal(1);\n\n infiniteScroller.scrollToCell = oldScrollToCell;\n });\n\n it('refreshes when certain properties change - with some analytics event sampling', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const searchService = new MockSearchService();\n const collectionNameCache = new MockCollectionNameCache();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .analyticsHandler=${mockAnalyticsHandler}\n .searchService=${searchService}\n .collectionNameCache=${collectionNameCache}\n ></collection-browser>`\n );\n const infiniteScrollerRefreshSpy = sinon.spy();\n\n // Infinite scroller won't exist unless there's a base query\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');\n (infiniteScroller as InfiniteScroller).reload = infiniteScrollerRefreshSpy;\n expect(infiniteScrollerRefreshSpy.called).to.be.false;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(0);\n\n // testing: `loggedIn`\n el.loggedIn = true;\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.called).to.be.true;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(1);\n\n el.loggedIn = false;\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(2);\n\n // testing: `displayMode`\n el.displayMode = 'list-compact';\n el.searchContext = 'beta-search';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(3);\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search');\n expect(mockAnalyticsHandler.callAction).to.equal('displayMode');\n expect(mockAnalyticsHandler.callLabel).to.equal('list-compact');\n\n el.displayMode = 'list-detail';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(4);\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search');\n expect(mockAnalyticsHandler.callAction).to.equal('displayMode');\n expect(mockAnalyticsHandler.callLabel).to.equal('list-detail');\n\n // testing: `baseNavigationUrl`\n el.baseNavigationUrl = 'https://funtestsite.com';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(5);\n\n // testing: `baseImageUrl`\n el.baseImageUrl = 'https://funtestsiteforimages.com';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(6);\n });\n\n it('query the search service for single result', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'single-result';\n await el.updateComplete;\n await nextTick();\n\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Result');\n });\n\n it('`searchContext` prop helps describe where component is being used', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n expect(el.searchContext).to.equal(analyticsCategories.default);\n\n el.searchContext = 'unicorn-search';\n await el.updateComplete;\n\n expect(el.searchContext).to.equal('unicorn-search');\n\n // property is reflected as attribute\n expect(el.getAttribute('searchcontext')).to.equal('unicorn-search');\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"collection-browser.test.js","sourceRoot":"","sources":["../../test/collection-browser.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable import/no-duplicates */\nimport { expect, fixture } from '@open-wc/testing';\nimport { html } from 'lit';\nimport sinon from 'sinon';\nimport type { InfiniteScroller } from '@internetarchive/infinite-scroller';\nimport { SearchType } from '@internetarchive/search-service';\nimport type { HistogramDateRange } from '@internetarchive/histogram-date-range';\nimport type { CollectionBrowser } from '../src/collection-browser';\nimport '../src/collection-browser';\nimport {\n defaultSelectedFacets,\n FacetBucket,\n SelectedFacets,\n SortField,\n} from '../src/models';\nimport { MockSearchService } from './mocks/mock-search-service';\nimport { MockCollectionNameCache } from './mocks/mock-collection-name-cache';\nimport { MockAnalyticsHandler } from './mocks/mock-analytics-handler';\nimport { analyticsCategories } from '../src/utils/analytics-events';\nimport type { TileDispatcher } from '../src/tiles/tile-dispatcher';\nimport type { CollectionFacets } from '../src/collection-facets';\n\n/**\n * Wait for the next tick of the event loop.\n *\n * This is necessary in some of the tests because certain collection browser\n * updates take more than one tick to render (e.g., date picker & query changes).\n * These delays are non-ideal and should eventually be investigated and fixed,\n * but they are minor enough that waiting for the next tick is a reasonable\n * testing solution for now.\n */\nconst nextTick = () =>\n new Promise(resolve => {\n setTimeout(resolve, 0);\n });\n\ndescribe('Collection Browser', () => {\n beforeEach(async () => {\n // Apparently query params set by one test can bleed into other tests.\n // Since collection browser restores its state from certain query params, we need\n // to clear these before each test to ensure they run in isolation from one another.\n const url = new URL(window.location.href);\n const { searchParams } = url;\n searchParams.delete('sin');\n searchParams.delete('sort');\n searchParams.delete('query');\n searchParams.delete('page');\n searchParams.delete('and[]');\n searchParams.delete('not[]');\n window.history.replaceState({}, '', url);\n });\n\n it('clear existing filter for facets & sort-bar', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n el.selectedSort = 'title' as SortField;\n await el.updateComplete;\n el.clearFilters();\n\n expect(el.selectedFacets).to.equal(defaultSelectedFacets);\n expect(el.selectedSort).to.equal('relevance');\n expect(el.sortDirection).to.be.undefined;\n expect(el.sortParam).to.be.undefined;\n expect(el.selectedCreatorFilter).to.be.undefined;\n expect(el.selectedTitleFilter).to.be.undefined;\n });\n\n it('filterBy creator with analytics', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'betaSearchService';\n el.selectedSort = 'creator' as SortField;\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'A';\n await el.updateComplete;\n\n expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');\n expect(mockAnalyticsHandler.callLabel).to.equal('start-A');\n\n el.clearFilters();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.be.undefined;\n expect(mockAnalyticsHandler.callCategory).to.equal('betaSearchService');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByCreator');\n expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');\n });\n\n it('filterBy title with analytics', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'beta-search-service';\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n el.selectedTitleFilter = 'A';\n await el.updateComplete;\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');\n expect(mockAnalyticsHandler.callLabel).to.equal('start-A');\n\n el.clearFilters();\n await el.updateComplete;\n\n expect(el.selectedTitleFilter).to.be.undefined;\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('filterByTitle');\n expect(mockAnalyticsHandler.callLabel).to.equal('clear-A');\n });\n\n it('selected facets with analytics - not negative facets', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const mediaTypeBucket = { count: 123, state: 'selected' } as FacetBucket;\n const mockedSelectedFacets: SelectedFacets = {\n subject: {},\n lending: {},\n mediatype: { data: mediaTypeBucket },\n language: {},\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'search-service';\n el.selectedFacets = mockedSelectedFacets;\n await el.updateComplete;\n\n el.facetClickHandler('mediatype', true, false);\n expect(mockAnalyticsHandler.callCategory).to.equal('search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetSelected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n\n el.facetClickHandler('mediatype', false, false);\n expect(el.selectedFacets).to.equal(mockedSelectedFacets);\n expect(mockAnalyticsHandler.callCategory).to.equal('search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetDeselected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n });\n\n it('selected facets with analytics - negative facets', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const mediaTypeBucket = { count: 123, state: 'selected' } as FacetBucket;\n const mockedSelectedFacets: SelectedFacets = {\n subject: {},\n lending: {},\n mediatype: { data: mediaTypeBucket },\n language: {},\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .analyticsHandler=${mockAnalyticsHandler}>\n </collection-browser>`\n );\n\n el.searchContext = 'beta-search-service';\n el.selectedFacets = mockedSelectedFacets;\n await el.updateComplete;\n\n el.facetClickHandler('mediatype', true, true);\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeSelected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n\n el.facetClickHandler('mediatype', false, true);\n expect(el.selectedFacets).to.equal(mockedSelectedFacets);\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search-service');\n expect(mockAnalyticsHandler.callAction).to.equal('facetNegativeDeselected');\n expect(mockAnalyticsHandler.callLabel).to.equal('mediatype');\n });\n\n it('should render with a sort bar, facets, and infinite scroller', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'hello';\n await el.updateComplete;\n\n const facets = el.shadowRoot?.querySelector('collection-facets');\n const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');\n const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');\n expect(facets).to.exist;\n expect(sortBar).to.exist;\n expect(infiniteScroller).to.exist;\n });\n\n it('queries the search service when given a base query', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with a metadata search', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html` <collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.METADATA}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchType).to.equal(SearchType.METADATA);\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with a fulltext search', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html` <collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.FULLTEXT}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n await nextTick();\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchType).to.equal(SearchType.FULLTEXT);\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Results');\n });\n\n it('queries the search service with facets selected/negated', async () => {\n const searchService = new MockSearchService();\n const selectedFacets: SelectedFacets = {\n subject: {\n foo: {\n key: 'foo',\n count: 1,\n state: 'selected',\n },\n bar: {\n key: 'bar',\n count: 2,\n state: 'hidden',\n },\n },\n lending: {},\n mediatype: {},\n language: {\n en: {\n key: 'en',\n count: 1,\n state: 'selected',\n },\n },\n creator: {},\n collection: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n el.selectedFacets = selectedFacets;\n await el.updateComplete;\n\n expect(searchService.searchParams?.query).to.equal('collection:foo');\n expect(searchService.searchParams?.filters).to.deep.equal({\n subject: {\n foo: 'inc',\n bar: 'exc',\n },\n language: {\n en: 'inc',\n },\n });\n });\n\n it('fails gracefully if no search service provided', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n // This shouldn't throw an error\n expect(el.fetchPage(2)).to.exist;\n\n // Should continue showing the empty placeholder\n expect(el.shadowRoot?.querySelector('empty-placeholder')).to.exist;\n });\n\n it('restores search type from URL param', async () => {\n // Add a sin=TXT param to the URL\n const url = new URL(window.location.href);\n url.searchParams.append('sin', 'TXT');\n window.history.replaceState({}, '', url);\n\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n expect(el.searchType).to.equal(SearchType.FULLTEXT);\n });\n\n it('applies loggedin flag to tile models if needed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'loggedin';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.loginRequired).to.be.true;\n });\n\n it('applies no-preview flag to tile models if needed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'no-preview';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.contentWarning).to.be.true;\n });\n\n it('both loggedin and no-preview flags can be set simultaneously', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'loggedin-no-preview';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n expect(cell.model?.loginRequired).to.be.true;\n expect(cell.model?.contentWarning).to.be.true;\n });\n\n it('joins full description array into a single string with line breaks', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n // This query receives an array description like ['line1', 'line2']\n el.baseQuery = 'multi-line-description';\n await el.updateComplete;\n\n const cellTemplate = el.cellForIndex(0);\n expect(cellTemplate).to.exist;\n\n const cell = await fixture<TileDispatcher>(cellTemplate!);\n expect(cell).to.exist;\n\n // Actual model description should be joined\n expect(cell.model?.description).to.equal('line1\\nline2');\n });\n\n it('can search on demand if only search type has changed', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .searchService=${searchService}\n .searchType=${SearchType.METADATA}\n ></collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n el.searchType = SearchType.FULLTEXT;\n await el.updateComplete;\n\n // Haven't performed the search yet\n expect(searchService.searchType).to.equal(SearchType.METADATA);\n\n el.requestSearch();\n expect(searchService.searchType).to.equal(SearchType.FULLTEXT);\n });\n\n it('queries for collection names after a fetch', async () => {\n const searchService = new MockSearchService();\n const collectionNameCache = new MockCollectionNameCache();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .searchService=${searchService}\n .collectionNameCache=${collectionNameCache}\n >\n </collection-browser>`\n );\n\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n expect(collectionNameCache.preloadIdentifiersRequested).to.deep.equal([\n 'foo',\n 'bar',\n 'baz',\n 'boop',\n ]);\n });\n\n it('keeps search results from fetch if no change to query or sort param', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n el.sortParam = { field: 'foo', direction: 'asc' };\n await el.updateComplete;\n\n await el.fetchPage(2);\n\n // If there is no change to the query or sort param during the fetch, the results\n // should be read.\n expect(resultsSpy.callCount).to.be.greaterThanOrEqual(1);\n });\n\n it('discards obsolete search results if sort params changed before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n el.sortParam = { field: 'foo', direction: 'asc' };\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = { field: 'foo', direction: 'desc' };\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('discards obsolete search results if sort param added before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'single-result';\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = { field: 'foo', direction: 'asc' };\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('discards obsolete search results if sort param cleared before arrival', async () => {\n const resultsSpy = sinon.spy();\n const searchService = new MockSearchService({\n asyncResponse: true,\n resultsSpy,\n });\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'with-sort';\n await el.updateComplete;\n\n const fetchPromise = el.fetchPage(2);\n el.sortParam = undefined;\n await fetchPromise;\n\n // If the different sort param causes the results to be discarded,\n // the results array should never be read.\n expect(resultsSpy.callCount).to.equal(0);\n });\n\n it('sets sort properties when user changes sort', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n expect(el.selectedSort).to.equal(SortField.relevance);\n\n el.baseQuery = 'foo';\n await el.updateComplete;\n\n const sortBar = el.shadowRoot?.querySelector('sort-filter-bar');\n const sortSelector = sortBar?.shadowRoot?.querySelector(\n '#desktop-sort-selector'\n );\n expect(sortSelector).to.exist;\n\n // Click the title sorter\n [...(sortSelector?.children as HTMLCollection & Iterable<any>)] // tsc doesn't know children is iterable\n .find(child => child.textContent?.trim() === 'Title')\n ?.querySelector('a[href]')\n ?.click();\n\n await el.updateComplete;\n\n expect(el.selectedSort).to.equal(SortField.title);\n });\n\n it('sets sort filter properties when user selects title filter', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-title';\n el.selectedSort = 'title' as SortField;\n el.sortDirection = 'asc';\n el.selectedTitleFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-title AND firstTitle:X'\n );\n });\n\n it('sets sort filter properties when user selects creator filter', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-creator';\n el.selectedSort = 'creator' as SortField;\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-creator AND firstCreator:X'\n );\n });\n\n it('sets sort filter properties simultaneous with facets and date range', async () => {\n const searchService = new MockSearchService();\n const selectedFacets: SelectedFacets = {\n collection: { foo: { key: 'foo', state: 'selected', count: 1 } },\n creator: {},\n language: {},\n lending: {},\n mediatype: {},\n subject: {},\n year: {},\n };\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'first-creator';\n el.selectedSort = 'creator' as SortField;\n el.selectedFacets = selectedFacets;\n el.minSelectedDate = '1950';\n el.maxSelectedDate = '1970';\n el.sortDirection = 'asc';\n el.selectedCreatorFilter = 'X';\n await el.updateComplete;\n\n // Wait an extra tick\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n expect(searchService.searchParams?.query).to.equal(\n 'first-creator AND firstCreator:X'\n );\n expect(searchService.searchParams?.filters).to.deep.equal({\n collection: {\n foo: 'inc',\n },\n year: {\n '1950': 'gte',\n '1970': 'lte',\n },\n });\n });\n\n it('sets date range query when date picker selection changed', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'years'; // Includes year_histogram aggregation in response\n el.showHistogramDatePicker = true;\n await el.updateComplete;\n\n const facets = el.shadowRoot?.querySelector(\n 'collection-facets'\n ) as CollectionFacets;\n await facets?.updateComplete;\n\n // Wait for the date picker to be rendered (which may take until the next tick)\n await new Promise(res => {\n setTimeout(res, 0);\n });\n\n const histogram = facets?.shadowRoot?.querySelector(\n 'histogram-date-range'\n ) as HistogramDateRange;\n expect(histogram).to.exist;\n\n // Enter a new min date into the date picker\n const minDateInput = histogram.shadowRoot?.querySelector(\n '#date-min'\n ) as HTMLInputElement;\n\n const pressEnterEvent = new KeyboardEvent('keyup', {\n key: 'Enter',\n });\n\n minDateInput.value = '1960';\n minDateInput.dispatchEvent(pressEnterEvent);\n\n // Wait for the histogram's update delay\n await new Promise(res => {\n setTimeout(res, histogram.updateDelay + 50);\n });\n\n // Ensure that the histogram change propagated to the collection browser's\n // date query correctly.\n await el.updateComplete;\n expect(el.minSelectedDate).to.equal('1960');\n expect(el.maxSelectedDate).to.equal('2000');\n });\n\n it('scrolls to page', async () => {\n const searchService = new MockSearchService();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n // Infinite scroller won't exist unless there's a base query.\n // First ensure that we don't throw errors when it doesn't exist.\n await el.goToPage(1);\n\n // And make sure it correctly calls scrollToCell when the\n // infinite scroller does exist.\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n const infiniteScroller = el.shadowRoot?.querySelector(\n 'infinite-scroller'\n ) as InfiniteScroller;\n expect(infiniteScroller).to.exist;\n\n const oldScrollToCell = infiniteScroller.scrollToCell;\n const spy = sinon.spy();\n infiniteScroller.scrollToCell = spy;\n\n await el.goToPage(1);\n\n expect(spy.callCount).to.equal(1);\n\n infiniteScroller.scrollToCell = oldScrollToCell;\n });\n\n it('refreshes when certain properties change - with some analytics event sampling', async () => {\n const mockAnalyticsHandler = new MockAnalyticsHandler();\n const searchService = new MockSearchService();\n const collectionNameCache = new MockCollectionNameCache();\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser\n .analyticsHandler=${mockAnalyticsHandler}\n .searchService=${searchService}\n .collectionNameCache=${collectionNameCache}\n ></collection-browser>`\n );\n const infiniteScrollerRefreshSpy = sinon.spy();\n\n // Infinite scroller won't exist unless there's a base query\n el.baseQuery = 'collection:foo';\n await el.updateComplete;\n\n const infiniteScroller = el.shadowRoot?.querySelector('infinite-scroller');\n (infiniteScroller as InfiniteScroller).reload = infiniteScrollerRefreshSpy;\n expect(infiniteScrollerRefreshSpy.called).to.be.false;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(0);\n\n // testing: `loggedIn`\n el.loggedIn = true;\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.called).to.be.true;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(1);\n\n el.loggedIn = false;\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(2);\n\n // testing: `displayMode`\n el.displayMode = 'list-compact';\n el.searchContext = 'beta-search';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(3);\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search');\n expect(mockAnalyticsHandler.callAction).to.equal('displayMode');\n expect(mockAnalyticsHandler.callLabel).to.equal('list-compact');\n\n el.displayMode = 'list-detail';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(4);\n\n expect(mockAnalyticsHandler.callCategory).to.equal('beta-search');\n expect(mockAnalyticsHandler.callAction).to.equal('displayMode');\n expect(mockAnalyticsHandler.callLabel).to.equal('list-detail');\n\n // testing: `baseNavigationUrl`\n el.baseNavigationUrl = 'https://funtestsite.com';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(5);\n\n // testing: `baseImageUrl`\n el.baseImageUrl = 'https://funtestsiteforimages.com';\n await el.updateComplete;\n expect(infiniteScrollerRefreshSpy.callCount).to.equal(6);\n });\n\n it('query the search service for single result', async () => {\n const searchService = new MockSearchService();\n\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser .searchService=${searchService}>\n </collection-browser>`\n );\n\n el.baseQuery = 'single-result';\n await el.updateComplete;\n await nextTick();\n\n expect(\n el.shadowRoot?.querySelector('#big-results-label')?.textContent\n ).to.contains('Result');\n });\n\n it('`searchContext` prop helps describe where component is being used', async () => {\n const el = await fixture<CollectionBrowser>(\n html`<collection-browser></collection-browser>`\n );\n\n expect(el.searchContext).to.equal(analyticsCategories.default);\n\n el.searchContext = 'unicorn-search';\n await el.updateComplete;\n\n expect(el.searchContext).to.equal('unicorn-search');\n\n // property is reflected as attribute\n expect(el.getAttribute('searchcontext')).to.equal('unicorn-search');\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { expect } from '@open-wc/testing';
|
|
2
|
+
import { arrayEquals } from '../../src/utils/array-equals';
|
|
3
|
+
describe('arrayEquals', () => {
|
|
4
|
+
it('returns true for empty args', () => {
|
|
5
|
+
expect(arrayEquals([], [])).to.be.true;
|
|
6
|
+
});
|
|
7
|
+
it('returns true for identical array objects', () => {
|
|
8
|
+
const arr = ['foo', 'bar'];
|
|
9
|
+
expect(arrayEquals(arr, arr)).to.be.true;
|
|
10
|
+
});
|
|
11
|
+
it('returns true for arrays with identical contents', () => {
|
|
12
|
+
const arr1 = ['foo', 'bar'];
|
|
13
|
+
const arr2 = ['foo', 'bar'];
|
|
14
|
+
expect(arrayEquals(arr1, arr2)).to.be.true;
|
|
15
|
+
});
|
|
16
|
+
it('returns false for arrays of unequal length', () => {
|
|
17
|
+
const arr1 = [1, 2, 3];
|
|
18
|
+
const arr2 = [1, 2, 3, 4];
|
|
19
|
+
expect(arrayEquals(arr1, arr2)).to.be.false;
|
|
20
|
+
});
|
|
21
|
+
it('returns false for unequal arrays of same length', () => {
|
|
22
|
+
const arr1 = ['foo', 'bar'];
|
|
23
|
+
const arr2 = ['foo', 'qux'];
|
|
24
|
+
expect(arrayEquals(arr1, arr2)).to.be.false;
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=array-equals.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-equals.test.js","sourceRoot":"","sources":["../../../test/utils/array-equals.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE3D,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACvB,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { arrayEquals } from '../../src/utils/array-equals';\n\ndescribe('arrayEquals', () => {\n it('returns true for empty args', () => {\n expect(arrayEquals([], [])).to.be.true;\n });\n\n it('returns true for identical array objects', () => {\n const arr = ['foo', 'bar'];\n expect(arrayEquals(arr, arr)).to.be.true;\n });\n\n it('returns true for arrays with identical contents', () => {\n const arr1 = ['foo', 'bar'];\n const arr2 = ['foo', 'bar'];\n expect(arrayEquals(arr1, arr2)).to.be.true;\n });\n\n it('returns false for arrays of unequal length', () => {\n const arr1 = [1, 2, 3];\n const arr2 = [1, 2, 3, 4];\n expect(arrayEquals(arr1, arr2)).to.be.false;\n });\n\n it('returns false for unequal arrays of same length', () => {\n const arr1 = ['foo', 'bar'];\n const arr2 = ['foo', 'qux'];\n expect(arrayEquals(arr1, arr2)).to.be.false;\n });\n});\n"]}
|
package/package.json
CHANGED