@internetarchive/collection-browser 2.17.1-alpha-webdev7667.0 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { getMockSuccessSingleResult, getMockSuccessMultipleResults, getMockSuccessSingleResultWithSort, getMockSuccessLoggedInResult, getMockSuccessNoPreviewResult, getMockSuccessLoggedInAndNoPreviewResult, getMockSuccessWithYearHistogramAggs, getMockSuccessWithDateHistogramAggs, getMockSuccessMultiLineDescription, getMockSuccessFirstTitleResult, getMockSuccessFirstCreatorResult, getMockErrorResult, getMockMalformedResult, getMockSuccessWithCollectionTitles, getMockSuccessWithChannelAliases, getMockSuccessWithCollectionAggregations, getMockSuccessExtraQuotedHref, getMockSuccessWithDefaultSort, getMockSuccessWithConciseDefaultSort, getMockSuccessWithDefaultFavSort, getMockSuccessWithParentCollections, getMockSuccessForTvCollection, getMockSuccessManyFields, getMockSuccessNoResults, getMockSuccessWithWebArchiveHits, getMockSuccessWithManyAggregations, getMockSuccessTvFields, } from './mock-search-responses';
1
+ import { getMockSuccessSingleResult, getMockSuccessMultipleResults, getMockSuccessSingleResultWithSort, getMockSuccessLoggedInResult, getMockSuccessNoPreviewResult, getMockSuccessLoggedInAndNoPreviewResult, getMockSuccessWithYearHistogramAggs, getMockSuccessWithDateHistogramAggs, getMockSuccessMultiLineDescription, getMockSuccessFirstTitleResult, getMockSuccessFirstCreatorResult, getMockErrorResult, getMockMalformedResult, getMockSuccessWithCollectionTitles, getMockSuccessWithChannelAliases, getMockSuccessWithCollectionAggregations, getMockSuccessExtraQuotedHref, getMockSuccessWithDefaultSort, getMockSuccessWithConciseDefaultSort, getMockSuccessWithDefaultFavSort, getMockSuccessWithParentCollections, getMockSuccessForTvCollection, getMockSuccessManyFields, getMockSuccessNoResults, getMockSuccessWithWebArchiveHits, getMockSuccessWithManyAggregations, getMockSuccessTvFields, getMockSuccessArchiveOrgUserResult, getMockSuccessArchiveOrgUserNoBlurResult, } from './mock-search-responses';
2
2
  const responses = {
3
3
  'single-result': getMockSuccessSingleResult,
4
4
  years: getMockSuccessWithYearHistogramAggs,
@@ -7,6 +7,8 @@ const responses = {
7
7
  loggedin: getMockSuccessLoggedInResult,
8
8
  'no-preview': getMockSuccessNoPreviewResult,
9
9
  'loggedin-no-preview': getMockSuccessLoggedInAndNoPreviewResult,
10
+ 'archive-org-user-loggedin': getMockSuccessArchiveOrgUserResult,
11
+ 'archive-org-user-loggedin-noblur': getMockSuccessArchiveOrgUserNoBlurResult,
10
12
  'first-title': getMockSuccessFirstTitleResult,
11
13
  'first-creator': getMockSuccessFirstCreatorResult,
12
14
  'collection-titles': getMockSuccessWithCollectionTitles,
@@ -55,5 +57,9 @@ export class MockSearchService {
55
57
  }
56
58
  return result;
57
59
  }
60
+ async itemDetails(_) {
61
+ // We don't currently use the itemDetails method in collection-browser
62
+ throw new Error('not implemented');
63
+ }
58
64
  }
59
65
  //# sourceMappingURL=mock-search-service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock-search-service.js","sourceRoot":"","sources":["../../../test/mocks/mock-search-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Result } from '@internetarchive/result-type';\nimport type {\n SearchParams,\n SearchResponse,\n SearchServiceInterface,\n SearchServiceError,\n SearchType,\n} from '@internetarchive/search-service';\nimport {\n getMockSuccessSingleResult,\n getMockSuccessMultipleResults,\n getMockSuccessSingleResultWithSort,\n getMockSuccessLoggedInResult,\n getMockSuccessNoPreviewResult,\n getMockSuccessLoggedInAndNoPreviewResult,\n getMockSuccessWithYearHistogramAggs,\n getMockSuccessWithDateHistogramAggs,\n getMockSuccessMultiLineDescription,\n getMockSuccessFirstTitleResult,\n getMockSuccessFirstCreatorResult,\n getMockErrorResult,\n getMockMalformedResult,\n getMockSuccessWithCollectionTitles,\n getMockSuccessWithChannelAliases,\n getMockSuccessWithCollectionAggregations,\n getMockSuccessExtraQuotedHref,\n getMockSuccessWithDefaultSort,\n getMockSuccessWithConciseDefaultSort,\n getMockSuccessWithDefaultFavSort,\n getMockSuccessWithParentCollections,\n getMockSuccessForTvCollection,\n getMockSuccessManyFields,\n getMockSuccessNoResults,\n getMockSuccessWithWebArchiveHits,\n getMockSuccessWithManyAggregations,\n getMockSuccessTvFields,\n} from './mock-search-responses';\n\nconst responses: Record<\n string,\n () => Result<SearchResponse, SearchServiceError>\n> = {\n 'single-result': getMockSuccessSingleResult,\n years: getMockSuccessWithYearHistogramAggs,\n months: getMockSuccessWithDateHistogramAggs,\n 'multi-line-description': getMockSuccessMultiLineDescription,\n loggedin: getMockSuccessLoggedInResult,\n 'no-preview': getMockSuccessNoPreviewResult,\n 'loggedin-no-preview': getMockSuccessLoggedInAndNoPreviewResult,\n 'first-title': getMockSuccessFirstTitleResult,\n 'first-creator': getMockSuccessFirstCreatorResult,\n 'collection-titles': getMockSuccessWithCollectionTitles,\n 'channel-aliases': getMockSuccessWithChannelAliases,\n 'collection-aggregations': getMockSuccessWithCollectionAggregations,\n 'extra-quoted-href': getMockSuccessExtraQuotedHref,\n 'default-sort': getMockSuccessWithDefaultSort,\n 'default-sort-concise': getMockSuccessWithConciseDefaultSort,\n 'fav-sort': getMockSuccessWithDefaultFavSort,\n 'parent-collections': getMockSuccessWithParentCollections,\n 'tv-collection': getMockSuccessForTvCollection,\n 'web-archive': getMockSuccessWithWebArchiveHits,\n 'more-facets': getMockSuccessWithManyAggregations,\n 'many-fields': getMockSuccessManyFields,\n 'tv-fields': getMockSuccessTvFields,\n 'no-results': getMockSuccessNoResults,\n error: getMockErrorResult,\n malformed: getMockMalformedResult,\n};\n\nexport class MockSearchService implements SearchServiceInterface {\n searchParams?: SearchParams;\n\n searchType?: SearchType;\n\n asyncResponse: boolean;\n\n asyncResponseDelay: number;\n\n resultsSpy: Function;\n\n constructor({\n asyncResponse = false,\n asyncResponseDelay = 0,\n resultsSpy = () => {},\n } = {}) {\n this.asyncResponse = asyncResponse;\n this.asyncResponseDelay = asyncResponseDelay;\n this.resultsSpy = resultsSpy;\n }\n\n async search(\n params: SearchParams,\n searchType: SearchType,\n ): Promise<Result<SearchResponse, SearchServiceError>> {\n this.searchParams = params;\n this.searchType = searchType;\n\n if (this.asyncResponse) {\n // Add an artificial 1-tick delay\n await new Promise(res => {\n setTimeout(res, this.asyncResponseDelay);\n });\n }\n\n const responseKey =\n (this.searchParams.query || this.searchParams.pageTarget) ?? '';\n const resultFn: () => Result<SearchResponse, SearchServiceError> =\n responses[responseKey] ?? getMockSuccessMultipleResults;\n let result = resultFn();\n\n // with-sort query has special handling\n if (this.searchParams.query === 'with-sort') {\n result = getMockSuccessSingleResultWithSort(this.resultsSpy);\n }\n\n // Apply any uid param from the request\n if (result.success) {\n (result.success.request.clientParameters as any).uid = params.uid;\n }\n\n return result;\n }\n}\n"]}
1
+ {"version":3,"file":"mock-search-service.js","sourceRoot":"","sources":["../../../test/mocks/mock-search-service.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Result } from '@internetarchive/result-type';\nimport type {\n SearchParams,\n SearchResponse,\n SearchServiceInterface,\n SearchServiceError,\n SearchType,\n} from '@internetarchive/search-service';\nimport {\n getMockSuccessSingleResult,\n getMockSuccessMultipleResults,\n getMockSuccessSingleResultWithSort,\n getMockSuccessLoggedInResult,\n getMockSuccessNoPreviewResult,\n getMockSuccessLoggedInAndNoPreviewResult,\n getMockSuccessWithYearHistogramAggs,\n getMockSuccessWithDateHistogramAggs,\n getMockSuccessMultiLineDescription,\n getMockSuccessFirstTitleResult,\n getMockSuccessFirstCreatorResult,\n getMockErrorResult,\n getMockMalformedResult,\n getMockSuccessWithCollectionTitles,\n getMockSuccessWithChannelAliases,\n getMockSuccessWithCollectionAggregations,\n getMockSuccessExtraQuotedHref,\n getMockSuccessWithDefaultSort,\n getMockSuccessWithConciseDefaultSort,\n getMockSuccessWithDefaultFavSort,\n getMockSuccessWithParentCollections,\n getMockSuccessForTvCollection,\n getMockSuccessManyFields,\n getMockSuccessNoResults,\n getMockSuccessWithWebArchiveHits,\n getMockSuccessWithManyAggregations,\n getMockSuccessTvFields,\n getMockSuccessArchiveOrgUserResult,\n getMockSuccessArchiveOrgUserNoBlurResult,\n} from './mock-search-responses';\n\nconst responses: Record<\n string,\n () => Result<SearchResponse, SearchServiceError>\n> = {\n 'single-result': getMockSuccessSingleResult,\n years: getMockSuccessWithYearHistogramAggs,\n months: getMockSuccessWithDateHistogramAggs,\n 'multi-line-description': getMockSuccessMultiLineDescription,\n loggedin: getMockSuccessLoggedInResult,\n 'no-preview': getMockSuccessNoPreviewResult,\n 'loggedin-no-preview': getMockSuccessLoggedInAndNoPreviewResult,\n 'archive-org-user-loggedin': getMockSuccessArchiveOrgUserResult,\n 'archive-org-user-loggedin-noblur': getMockSuccessArchiveOrgUserNoBlurResult,\n 'first-title': getMockSuccessFirstTitleResult,\n 'first-creator': getMockSuccessFirstCreatorResult,\n 'collection-titles': getMockSuccessWithCollectionTitles,\n 'channel-aliases': getMockSuccessWithChannelAliases,\n 'collection-aggregations': getMockSuccessWithCollectionAggregations,\n 'extra-quoted-href': getMockSuccessExtraQuotedHref,\n 'default-sort': getMockSuccessWithDefaultSort,\n 'default-sort-concise': getMockSuccessWithConciseDefaultSort,\n 'fav-sort': getMockSuccessWithDefaultFavSort,\n 'parent-collections': getMockSuccessWithParentCollections,\n 'tv-collection': getMockSuccessForTvCollection,\n 'web-archive': getMockSuccessWithWebArchiveHits,\n 'more-facets': getMockSuccessWithManyAggregations,\n 'many-fields': getMockSuccessManyFields,\n 'tv-fields': getMockSuccessTvFields,\n 'no-results': getMockSuccessNoResults,\n error: getMockErrorResult,\n malformed: getMockMalformedResult,\n};\n\nexport class MockSearchService implements SearchServiceInterface {\n searchParams?: SearchParams;\n\n searchType?: SearchType;\n\n asyncResponse: boolean;\n\n asyncResponseDelay: number;\n\n resultsSpy: Function;\n\n constructor({\n asyncResponse = false,\n asyncResponseDelay = 0,\n resultsSpy = () => {},\n } = {}) {\n this.asyncResponse = asyncResponse;\n this.asyncResponseDelay = asyncResponseDelay;\n this.resultsSpy = resultsSpy;\n }\n\n async search(\n params: SearchParams,\n searchType: SearchType,\n ): Promise<Result<SearchResponse, SearchServiceError>> {\n this.searchParams = params;\n this.searchType = searchType;\n\n if (this.asyncResponse) {\n // Add an artificial 1-tick delay\n await new Promise(res => {\n setTimeout(res, this.asyncResponseDelay);\n });\n }\n\n const responseKey =\n (this.searchParams.query || this.searchParams.pageTarget) ?? '';\n const resultFn: () => Result<SearchResponse, SearchServiceError> =\n responses[responseKey] ?? getMockSuccessMultipleResults;\n let result = resultFn();\n\n // with-sort query has special handling\n if (this.searchParams.query === 'with-sort') {\n result = getMockSuccessSingleResultWithSort(this.resultsSpy);\n }\n\n // Apply any uid param from the request\n if (result.success) {\n (result.success.request.clientParameters as any).uid = params.uid;\n }\n\n return result;\n }\n\n async itemDetails(\n _: string,\n ): Promise<Result<SearchResponse, SearchServiceError>> {\n // We don't currently use the itemDetails method in collection-browser\n throw new Error('not implemented');\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "The Internet Archive Collection Browser.",
4
4
  "license": "AGPL-3.0-only",
5
5
  "author": "Internet Archive",
6
- "version": "2.17.1-alpha-webdev7667.0",
6
+ "version": "2.18.0",
7
7
  "main": "dist/index.js",
8
8
  "module": "dist/index.js",
9
9
  "scripts": {
@@ -26,13 +26,13 @@
26
26
  "@internetarchive/analytics-manager": "^0.1.4",
27
27
  "@internetarchive/feature-feedback": "^1.0.0",
28
28
  "@internetarchive/field-parsers": "^1.0.0",
29
- "@internetarchive/histogram-date-range": "^1.3.1",
29
+ "@internetarchive/histogram-date-range": "^1.3.2",
30
30
  "@internetarchive/ia-activity-indicator": "^0.0.6",
31
31
  "@internetarchive/ia-dropdown": "^1.3.10",
32
32
  "@internetarchive/iaux-item-metadata": "^1.0.5",
33
33
  "@internetarchive/infinite-scroller": "^1.0.1",
34
34
  "@internetarchive/modal-manager": "^2.0.1",
35
- "@internetarchive/search-service": "2.4.1-alpha-webdev7667.0",
35
+ "@internetarchive/search-service": "^2.5.0",
36
36
  "@internetarchive/shared-resize-observer": "^0.2.0",
37
37
  "@lit/localize": "^0.12.2",
38
38
  "dompurify": "^3.2.4",
package/src/app-root.ts CHANGED
@@ -379,22 +379,6 @@ export class AppRoot extends LitElement {
379
379
 
380
380
  <fieldset class="cb-visual-appearance">
381
381
  <legend>CB Visual Appearance</legend>
382
- <div class="checkbox-control">
383
- <input
384
- type="checkbox"
385
- id="show-dummy-snippets"
386
- @click=${this.snippetsChanged}
387
- />
388
- <label for="show-dummy-snippets">Show dummy snippets</label>
389
- </div>
390
- <div class="checkbox-control">
391
- <input
392
- type="checkbox"
393
- id="show-dummy-reviews"
394
- @click=${this.reviewsChanged}
395
- />
396
- <label for="show-dummy-reviews">Show dummy reviews</label>
397
- </div>
398
382
  <div class="checkbox-control">
399
383
  <input
400
384
  type="checkbox"
@@ -637,87 +621,6 @@ export class AppRoot extends LitElement {
637
621
  }
638
622
  }
639
623
 
640
- private async snippetsChanged(e: Event) {
641
- const target = e.target as HTMLInputElement;
642
- if (target.checked) {
643
- // Decorate the default search service with a wrapper that adds
644
- // dummy snippets to any successful searches
645
- this.searchService = {
646
- async search(params, searchType) {
647
- const searchResponse = await SearchService.default.search(
648
- params,
649
- searchType,
650
- );
651
- searchResponse.success?.response.results.forEach(result => {
652
- Object.defineProperty(result, 'highlight', {
653
- value: new StringField([
654
- 'this is a text {{{snippet}}} block with potentially',
655
- 'multiple {{{snippets}}} and such',
656
- 'but the {{{snippet}}} block may be quite long perhaps',
657
- 'depending on how many {{{snippet}}} matches there are',
658
- 'there may be multiple lines of {{{snippets}}} to show',
659
- 'but each {{{snippet}}} should be relatively short',
660
- 'and {{{snippets}}} are each a {{{snippet}}} of text',
661
- 'but every {{{snippet}}} might have multiple matches',
662
- 'the {{{snippets}}} should be separated and surrounded by ellipses',
663
- ]),
664
- });
665
- });
666
- return searchResponse;
667
- },
668
- };
669
- } else {
670
- // Restore the default seach service
671
- this.searchService = SearchService.default;
672
- }
673
-
674
- // Re-perform the current search to show/hide the snippets immediately
675
- this.reperformCurrentSearch();
676
- }
677
-
678
- private async reviewsChanged(e: Event) {
679
- const target = e.target as HTMLInputElement;
680
- if (target.checked) {
681
- // Decorate the default search service with a wrapper that adds
682
- // dummy reviews to any successful searches
683
- this.searchService = {
684
- async search(params, searchType) {
685
- const searchResponse = await SearchService.default.search(
686
- params,
687
- searchType,
688
- );
689
- searchResponse.success?.response.results.forEach((result, i) => {
690
- Object.defineProperty(result, 'review', {
691
- value: {
692
- title: 'My Great Review',
693
- body: "This item is really great and that's why I'm leaving this review on it and giving it so many star...",
694
- stars: (i + 3) % 6,
695
- },
696
- });
697
- });
698
- return searchResponse;
699
- },
700
- };
701
- } else {
702
- // Restore the default seach service
703
- this.searchService = SearchService.default;
704
- }
705
-
706
- // Re-perform the current search to show/hide the reviews immediately
707
- this.reperformCurrentSearch();
708
- }
709
-
710
- private async reperformCurrentSearch(): Promise<void> {
711
- const oldQuery = this.searchQuery;
712
- this.searchQuery = '-'; // Should just reset to the placeholder
713
- await this.updateComplete;
714
- // For unclear reasons, Safari refuses to re-apply the old query until the next tick, hence:
715
- await new Promise(res => {
716
- setTimeout(res, 0);
717
- });
718
- this.searchQuery = oldQuery; // Re-apply the original query
719
- }
720
-
721
624
  private datePickerChanged(e: Event) {
722
625
  const target = e.target as HTMLInputElement;
723
626
  this.collectionBrowser.showHistogramDatePicker = target.checked;
@@ -895,8 +895,7 @@ describe('Collection Browser', () => {
895
895
  expect(sortSelector, 'sort bar').to.exist;
896
896
 
897
897
  // Click the title sorter
898
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
899
- [...(sortSelector?.children as HTMLCollection & Iterable<any>)] // tsc doesn't know children is iterable
898
+ Array.from(sortSelector!.children)
900
899
  .find(child => child.textContent?.trim() === 'Title')
901
900
  ?.querySelector('button')
902
901
  ?.click();
@@ -904,6 +903,16 @@ describe('Collection Browser', () => {
904
903
  await el.updateComplete;
905
904
 
906
905
  expect(el.selectedSort).to.equal(SortField.title);
906
+
907
+ // Click the creator sorter
908
+ Array.from(sortSelector!.children)
909
+ .find(child => child.textContent?.trim() === 'Creator')
910
+ ?.querySelector('button')
911
+ ?.click();
912
+
913
+ await el.updateComplete;
914
+
915
+ expect(el.selectedSort).to.equal(SortField.creator);
907
916
  });
908
917
 
909
918
  it('sets sort filter properties when user selects title filter', async () => {
@@ -1072,9 +1081,11 @@ describe('Collection Browser', () => {
1072
1081
 
1073
1082
  it('sets date range query when date picker selection changed', async () => {
1074
1083
  const searchService = new MockSearchService();
1084
+ const mockAnalyticsHandler = new MockAnalyticsHandler();
1075
1085
  const el = await fixture<CollectionBrowser>(
1076
1086
  html`<collection-browser
1077
1087
  .searchService=${searchService}
1088
+ .analyticsHandler=${mockAnalyticsHandler}
1078
1089
  .suppressPlaceholders=${true}
1079
1090
  >
1080
1091
  </collection-browser>`,
@@ -2145,6 +2156,79 @@ describe('Collection Browser', () => {
2145
2156
  .exist;
2146
2157
  });
2147
2158
 
2159
+ it('shows Blurring checkbox for admin users', async () => {
2160
+ const searchService = new MockSearchService();
2161
+ const el = await fixture<CollectionBrowser>(
2162
+ html`<collection-browser
2163
+ .baseNavigationUrl=${''}
2164
+ .searchService=${searchService}
2165
+ >
2166
+ </collection-browser>`,
2167
+ );
2168
+
2169
+ el.baseQuery = 'archive-org-user-loggedin';
2170
+ await el.updateComplete;
2171
+ await el.initialSearchComplete;
2172
+
2173
+ const blurringCheck = el.shadowRoot?.querySelector(
2174
+ '#tile-blur-check',
2175
+ ) as HTMLInputElement;
2176
+ expect(blurringCheck).to.exist;
2177
+ expect(blurringCheck.checked).to.be.true;
2178
+ });
2179
+
2180
+ it('unchecks Blurring checkbox for admin users with blurring preference off', async () => {
2181
+ const searchService = new MockSearchService();
2182
+ const el = await fixture<CollectionBrowser>(
2183
+ html`<collection-browser
2184
+ .baseNavigationUrl=${''}
2185
+ .searchService=${searchService}
2186
+ >
2187
+ </collection-browser>`,
2188
+ );
2189
+
2190
+ el.baseQuery = 'archive-org-user-loggedin-noblur';
2191
+ await el.updateComplete;
2192
+ await el.initialSearchComplete;
2193
+
2194
+ const blurringCheck = el.shadowRoot?.querySelector(
2195
+ '#tile-blur-check',
2196
+ ) as HTMLInputElement;
2197
+ expect(blurringCheck).to.exist;
2198
+ expect(blurringCheck.checked).to.be.false;
2199
+ });
2200
+
2201
+ it('toggles blur state when Blurring checkbox is toggled', async () => {
2202
+ const searchService = new MockSearchService();
2203
+ const el = await fixture<CollectionBrowser>(
2204
+ html`<collection-browser
2205
+ .baseNavigationUrl=${''}
2206
+ .searchService=${searchService}
2207
+ >
2208
+ </collection-browser>`,
2209
+ );
2210
+
2211
+ el.baseQuery = 'archive-org-user-loggedin';
2212
+ await el.updateComplete;
2213
+ await el.initialSearchComplete;
2214
+
2215
+ const blurringCheck = el.shadowRoot?.querySelector(
2216
+ '#tile-blur-check',
2217
+ ) as HTMLInputElement;
2218
+ expect(blurringCheck).to.exist;
2219
+
2220
+ blurringCheck.dispatchEvent(new PointerEvent('click'));
2221
+ await el.updateComplete;
2222
+
2223
+ const infiniteScroller = el.shadowRoot?.querySelector(
2224
+ 'infinite-scroller',
2225
+ ) as InfiniteScroller;
2226
+ const firstTile = infiniteScroller?.shadowRoot?.querySelector(
2227
+ 'tile-dispatcher',
2228
+ ) as TileDispatcher;
2229
+ expect(firstTile.suppressBlurring).to.be.true;
2230
+ });
2231
+
2148
2232
  it('applies loans tab properties to sort bar', async () => {
2149
2233
  const searchService = new MockSearchService();
2150
2234
  const el = await fixture<CollectionBrowser>(
@@ -220,4 +220,28 @@ describe('Image block component', () => {
220
220
  ) as TextOverlay;
221
221
  expect(textOverlay).not.to.exist;
222
222
  });
223
+
224
+ it('should render no overlay if blurring is suppressed', async () => {
225
+ const el = await fixture<ImageBlock>(html`
226
+ <image-block
227
+ .model=${{
228
+ loginRequired: true,
229
+ contentWarning: true,
230
+ identifier: 'goody',
231
+ }}
232
+ .baseImageUrl=${'https://archive.org'}
233
+ .isCompactTile=${false}
234
+ .isListTile=${false}
235
+ .viewSize=${'desktop'}
236
+ .loggedIn=${true}
237
+ suppressBlurring
238
+ >
239
+ </image-block>
240
+ `);
241
+
242
+ const textOverlay = el.shadowRoot?.querySelector(
243
+ 'text-overlay',
244
+ ) as TextOverlay;
245
+ expect(textOverlay).not.to.exist;
246
+ });
223
247
  });
@@ -5,6 +5,7 @@ import { TileModel } from '../src/models';
5
5
  import type { ItemImage } from '../src/tiles/item-image';
6
6
 
7
7
  import '../src/tiles/item-image';
8
+ import { MediaType } from '@internetarchive/field-parsers';
8
9
 
9
10
  const baseImageUrl = 'https://archive.org';
10
11
  const testBookModel: TileModel = new TileModel({});
@@ -131,4 +132,89 @@ describe('ItemImage component', () => {
131
132
  expect(img).to.exist;
132
133
  expect(img?.getAttribute('src')).not.to.exist;
133
134
  });
135
+
136
+ it('should blur image if login required flag set', async () => {
137
+ const model = new TileModel({ identifier: 'foo' });
138
+ model.loginRequired = true;
139
+
140
+ const el = await fixture<ItemImage>(html`
141
+ <item-image
142
+ .isListTile=${false}
143
+ .isCompactTile=${false}
144
+ .model=${model}
145
+ .baseImageUrl=${baseImageUrl}
146
+ >
147
+ </item-image>
148
+ `);
149
+
150
+ const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
151
+ expect(dropShadow).to.exist;
152
+
153
+ const imgClasses = dropShadow?.querySelector('img')?.classList;
154
+ expect(imgClasses?.contains('blur')).to.be.true;
155
+ });
156
+
157
+ it('should blur image if content warning flag set', async () => {
158
+ const model = new TileModel({ identifier: 'foo' });
159
+ model.contentWarning = true;
160
+
161
+ const el = await fixture<ItemImage>(html`
162
+ <item-image
163
+ .isListTile=${false}
164
+ .isCompactTile=${false}
165
+ .model=${model}
166
+ .baseImageUrl=${baseImageUrl}
167
+ >
168
+ </item-image>
169
+ `);
170
+
171
+ const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
172
+ expect(dropShadow).to.exist;
173
+
174
+ const imgClasses = dropShadow?.querySelector('img')?.classList;
175
+ expect(imgClasses?.contains('blur')).to.be.true;
176
+ });
177
+
178
+ it('should not blur image if no login required nor content warning', async () => {
179
+ const model = new TileModel({ identifier: 'foo' });
180
+
181
+ const el = await fixture<ItemImage>(html`
182
+ <item-image
183
+ .isListTile=${false}
184
+ .isCompactTile=${false}
185
+ .model=${model}
186
+ .baseImageUrl=${baseImageUrl}
187
+ >
188
+ </item-image>
189
+ `);
190
+
191
+ const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
192
+ expect(dropShadow).to.exist;
193
+
194
+ const imgClasses = dropShadow?.querySelector('img')?.classList;
195
+ expect(imgClasses?.contains('blur')).to.be.false;
196
+ });
197
+
198
+ it('should not blur image if blurring is suppressed, regardless of content flags', async () => {
199
+ const model = new TileModel({ identifier: 'foo' });
200
+ model.loginRequired = true;
201
+ model.contentWarning = true;
202
+
203
+ const el = await fixture<ItemImage>(html`
204
+ <item-image
205
+ .isListTile=${false}
206
+ .isCompactTile=${false}
207
+ .model=${model}
208
+ .baseImageUrl=${baseImageUrl}
209
+ suppressBlurring
210
+ >
211
+ </item-image>
212
+ `);
213
+
214
+ const dropShadow = el.shadowRoot?.querySelector('.drop-shadow');
215
+ expect(dropShadow).to.exist;
216
+
217
+ const imgClasses = dropShadow?.querySelector('img')?.classList;
218
+ expect(imgClasses?.contains('blur')).to.be.false;
219
+ });
134
220
  });
@@ -291,6 +291,110 @@ export const getMockSuccessWithDateHistogramAggs: () => Result<
291
291
  },
292
292
  });
293
293
 
294
+ export const getMockSuccessArchiveOrgUserResult: () => Result<
295
+ SearchResponse,
296
+ SearchServiceError
297
+ > = () => ({
298
+ success: {
299
+ request: {
300
+ kind: 'hits',
301
+ clientParameters: {
302
+ user_query: 'archive-org-user-loggedin',
303
+ sort: [],
304
+ },
305
+ backendRequests: {
306
+ primary: {
307
+ kind: 'hits',
308
+ finalized_parameters: {
309
+ user_query: 'archive-org-user-loggedin',
310
+ sort: [],
311
+ },
312
+ },
313
+ },
314
+ },
315
+ rawResponse: {},
316
+ sessionContext: {
317
+ is_archive_user: true,
318
+ pps_relevant_user_preferences: {
319
+ display__blur_moderated_content: 'on',
320
+ },
321
+ },
322
+ response: {
323
+ totalResults: 2,
324
+ returnedCount: 2,
325
+ results: [
326
+ new ItemHit({
327
+ fields: {
328
+ identifier: 'foo',
329
+ collection: ['foo', 'loggedin', 'bar'],
330
+ __href__: '/foo',
331
+ },
332
+ }),
333
+ new ItemHit({
334
+ fields: {
335
+ identifier: 'bar',
336
+ collection: ['baz', 'boop'],
337
+ __href__: '/bar',
338
+ },
339
+ }),
340
+ ],
341
+ },
342
+ responseHeader: {
343
+ succeeded: true,
344
+ query_time: 0,
345
+ },
346
+ },
347
+ });
348
+
349
+ export const getMockSuccessArchiveOrgUserNoBlurResult: () => Result<
350
+ SearchResponse,
351
+ SearchServiceError
352
+ > = () => ({
353
+ success: {
354
+ request: {
355
+ kind: 'hits',
356
+ clientParameters: {
357
+ user_query: 'archive-org-user-loggedin-noblur',
358
+ sort: [],
359
+ },
360
+ backendRequests: {
361
+ primary: {
362
+ kind: 'hits',
363
+ finalized_parameters: {
364
+ user_query: 'archive-org-user-loggedin-noblur',
365
+ sort: [],
366
+ },
367
+ },
368
+ },
369
+ },
370
+ rawResponse: {},
371
+ sessionContext: {
372
+ is_archive_user: true,
373
+ pps_relevant_user_preferences: {
374
+ display__blur_moderated_content: 'off',
375
+ },
376
+ },
377
+ response: {
378
+ totalResults: 1,
379
+ returnedCount: 1,
380
+ results: [
381
+ new ItemHit({
382
+ fields: {
383
+ identifier: 'foo',
384
+ collection: ['loggedin'],
385
+ title: 'foo',
386
+ mediatype: 'texts',
387
+ },
388
+ }),
389
+ ],
390
+ },
391
+ responseHeader: {
392
+ succeeded: true,
393
+ query_time: 0,
394
+ },
395
+ },
396
+ });
397
+
294
398
  export const getMockSuccessLoggedInResult: () => Result<
295
399
  SearchResponse,
296
400
  SearchServiceError
@@ -34,6 +34,8 @@ import {
34
34
  getMockSuccessWithWebArchiveHits,
35
35
  getMockSuccessWithManyAggregations,
36
36
  getMockSuccessTvFields,
37
+ getMockSuccessArchiveOrgUserResult,
38
+ getMockSuccessArchiveOrgUserNoBlurResult,
37
39
  } from './mock-search-responses';
38
40
 
39
41
  const responses: Record<
@@ -47,6 +49,8 @@ const responses: Record<
47
49
  loggedin: getMockSuccessLoggedInResult,
48
50
  'no-preview': getMockSuccessNoPreviewResult,
49
51
  'loggedin-no-preview': getMockSuccessLoggedInAndNoPreviewResult,
52
+ 'archive-org-user-loggedin': getMockSuccessArchiveOrgUserResult,
53
+ 'archive-org-user-loggedin-noblur': getMockSuccessArchiveOrgUserNoBlurResult,
50
54
  'first-title': getMockSuccessFirstTitleResult,
51
55
  'first-creator': getMockSuccessFirstCreatorResult,
52
56
  'collection-titles': getMockSuccessWithCollectionTitles,
@@ -120,4 +124,11 @@ export class MockSearchService implements SearchServiceInterface {
120
124
 
121
125
  return result;
122
126
  }
127
+
128
+ async itemDetails(
129
+ _: string,
130
+ ): Promise<Result<SearchResponse, SearchServiceError>> {
131
+ // We don't currently use the itemDetails method in collection-browser
132
+ throw new Error('not implemented');
133
+ }
123
134
  }