From 7bbce89b40f46b268203d7a30335328f66f1f89c Mon Sep 17 00:00:00 2001 From: Michael Spalti Date: Thu, 28 Apr 2022 14:26:35 -0700 Subject: [PATCH] Fixes search passthrough to Mirador and adds tests. --- .../publication/publication.component.spec.ts | 121 ++++++++++++------ .../item-types/shared/item-iiif-utils.ts | 9 +- .../item-types/shared/item.component.spec.ts | 34 ++--- .../untyped-item.component.spec.ts | 86 +++++++++---- 4 files changed, 168 insertions(+), 82 deletions(-) diff --git a/src/app/item-page/simple/item-types/publication/publication.component.spec.ts b/src/app/item-page/simple/item-types/publication/publication.component.spec.ts index 761849f232..7c63fabb47 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.spec.ts +++ b/src/app/item-page/simple/item-types/publication/publication.component.spec.ts @@ -1,6 +1,6 @@ import { HttpClient } from '@angular/common/http'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store } from '@ngrx/store'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; @@ -17,7 +17,7 @@ import { RemoteData } from '../../../../core/data/remote-data'; import { Bitstream } from '../../../../core/shared/bitstream.model'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; import { Item } from '../../../../core/shared/item.model'; -import { MetadataMap } from '../../../../core/shared/metadata.models'; +import { MetadataMap, MetadataValue } from '../../../../core/shared/metadata.models'; import { UUIDService } from '../../../../core/shared/uuid.service'; import { TranslateLoaderMock } from '../../../../shared/mocks/translate-loader.mock'; import { NotificationsService } from '../../../../shared/notifications/notifications.service'; @@ -26,22 +26,12 @@ import { TruncatableService } from '../../../../shared/truncatable/truncatable.s import { TruncatePipe } from '../../../../shared/utils/truncate.pipe'; import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component'; import { - createRelationshipsObservable, - iiifEnabled, - iiifSearchEnabled, mockRouteService + createRelationshipsObservable, getIIIFEnabled, getIIIFSearchEnabled, mockRouteService } from '../shared/item.component.spec'; import { PublicationComponent } from './publication.component'; import { createPaginatedList } from '../../../../shared/testing/utils.test'; import { RouteService } from '../../../../core/services/route.service'; - -const iiifEnabledMap: MetadataMap = { - 'dspace.iiif.enabled': [iiifEnabled], -}; - -const iiifEnabledWithSearchMap: MetadataMap = { - 'dspace.iiif.enabled': [iiifEnabled], - 'iiif.search.enabled': [iiifSearchEnabled], -}; +import { UntypedItemComponent } from '../untyped-item/untyped-item.component'; const noMetadata = new MetadataMap(); @@ -72,31 +62,32 @@ describe('PublicationComponent', () => { })], declarations: [PublicationComponent, GenericItemPageFieldComponent, TruncatePipe], providers: [ - { provide: ItemDataService, useValue: {} }, - { provide: TruncatableService, useValue: {} }, - { provide: RelationshipService, useValue: {} }, - { provide: ObjectCacheService, useValue: {} }, - { provide: UUIDService, useValue: {} }, - { provide: Store, useValue: {} }, - { provide: RemoteDataBuildService, useValue: {} }, - { provide: CommunityDataService, useValue: {} }, - { provide: HALEndpointService, useValue: {} }, - { provide: NotificationsService, useValue: {} }, - { provide: HttpClient, useValue: {} }, - { provide: DSOChangeAnalyzer, useValue: {} }, - { provide: DefaultChangeAnalyzer, useValue: {} }, - { provide: BitstreamDataService, useValue: mockBitstreamDataService }, - { provide: RouteService, useValue: mockRouteService } + {provide: ItemDataService, useValue: {}}, + {provide: TruncatableService, useValue: {}}, + {provide: RelationshipService, useValue: {}}, + {provide: ObjectCacheService, useValue: {}}, + {provide: UUIDService, useValue: {}}, + {provide: Store, useValue: {}}, + {provide: RemoteDataBuildService, useValue: {}}, + {provide: CommunityDataService, useValue: {}}, + {provide: HALEndpointService, useValue: {}}, + {provide: NotificationsService, useValue: {}}, + {provide: HttpClient, useValue: {}}, + {provide: DSOChangeAnalyzer, useValue: {}}, + {provide: DefaultChangeAnalyzer, useValue: {}}, + {provide: BitstreamDataService, useValue: mockBitstreamDataService}, + {provide: RouteService, useValue: mockRouteService} ], schemas: [NO_ERRORS_SCHEMA] }).overrideComponent(PublicationComponent, { - set: { changeDetection: ChangeDetectionStrategy.Default } - }).compileComponents(); + set: {changeDetection: ChangeDetectionStrategy.Default} + }); })); describe('default view', () => { beforeEach(waitForAsync(() => { + TestBed.compileComponents(); fixture = TestBed.createComponent(PublicationComponent); comp = fixture.componentInstance; comp.object = getItem(noMetadata); @@ -137,6 +128,42 @@ describe('PublicationComponent', () => { describe('with IIIF viewer', () => { beforeEach(waitForAsync(() => { + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(false)], + }; + TestBed.compileComponents(); + fixture = TestBed.createComponent(PublicationComponent); + comp = fixture.componentInstance; + comp.object = getItem(iiifEnabledMap); + fixture.detectChanges(); + })); + + it('should contain an iiif viewer component', () => { + const fields = fixture.debugElement.queryAll(By.css('ds-mirador-viewer')); + expect(fields.length).toBeGreaterThanOrEqual(1); + }); + it('should not retrieve the query term for previous route', fakeAsync((): void => { + //tick(10) + expect(comp.iiifQuery$).toBeFalsy(); + })); + + }); + + describe('with IIIF viewer and search', () => { + + beforeEach(waitForAsync(() => { + const localMockRouteService = { + getPreviousUrl(): Observable { + return of('/search?query=test') + } + }; + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(true)], + }; + TestBed.overrideProvider(RouteService, {useValue: localMockRouteService}); + TestBed.compileComponents(); fixture = TestBed.createComponent(PublicationComponent); comp = fixture.componentInstance; comp.object = getItem(iiifEnabledMap); @@ -148,15 +175,30 @@ describe('PublicationComponent', () => { expect(fields.length).toBeGreaterThanOrEqual(1); }); + it('should retrieve the query term for previous route', fakeAsync((): void => { + //tick(10) + expect(comp.iiifQuery$.subscribe(result => expect(result).toEqual('test'))); + })) + }); - describe('with IIIF viewer and search', () => { + describe('with IIIF viewer and search but no previous search query', () => { beforeEach(waitForAsync(() => { - mockRouteService.getPreviousUrl.and.returnValue(of(['/search?q=bird&motivation=painting','/item'])); + const localMockRouteService = { + getPreviousUrl(): Observable { + return of('/item') + } + }; + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(true)], + }; + TestBed.overrideProvider(RouteService, {useValue: localMockRouteService}); + TestBed.compileComponents(); fixture = TestBed.createComponent(PublicationComponent); comp = fixture.componentInstance; - comp.object = getItem(iiifEnabledWithSearchMap); + comp.object = getItem(iiifEnabledMap); fixture.detectChanges(); })); @@ -165,11 +207,12 @@ describe('PublicationComponent', () => { expect(fields.length).toBeGreaterThanOrEqual(1); }); - it('should call the RouteService getHistory method', () => { - expect(mockRouteService.getPreviousUrl).toHaveBeenCalled(); - }); + it('should not retrieve the query term for previous route', fakeAsync( () => { + let emitted; + comp.iiifQuery$.subscribe(result => emitted = result); + tick(10) + expect(emitted).toBeUndefined(); + })); }); - }); - diff --git a/src/app/item-page/simple/item-types/shared/item-iiif-utils.ts b/src/app/item-page/simple/item-types/shared/item-iiif-utils.ts index eb7b30eb56..45bba1e569 100644 --- a/src/app/item-page/simple/item-types/shared/item-iiif-utils.ts +++ b/src/app/item-page/simple/item-types/shared/item-iiif-utils.ts @@ -1,6 +1,6 @@ import { Item } from '../../../../core/shared/item.model'; import { Observable } from 'rxjs'; -import { filter, map } from 'rxjs/operators'; +import { filter, map, take } from 'rxjs/operators'; import { RouteService } from '../../../../core/services/route.service'; export const isIiifEnabled = (item: Item) => { @@ -26,10 +26,9 @@ export const getDSpaceQuery = (item: Item, routeService: RouteService): Observab return r.includes('/search'); }), map(r => { - const arr = r.split('&'); - const q = arr[1]; - const v = q.split('='); + const v = r.split('query='); return v[1]; - }) + }), + take(1) ); }; diff --git a/src/app/item-page/simple/item-types/shared/item.component.spec.ts b/src/app/item-page/simple/item-types/shared/item.component.spec.ts index fc07f60b28..96c5bd5106 100644 --- a/src/app/item-page/simple/item-types/shared/item.component.spec.ts +++ b/src/app/item-page/simple/item-types/shared/item.component.spec.ts @@ -4,7 +4,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store } from '@ngrx/store'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../../../../core/cache/object-cache.service'; import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; @@ -33,21 +33,25 @@ import { createPaginatedList } from '../../../../shared/testing/utils.test'; import { RouteService } from '../../../../core/services/route.service'; import { MetadataValue } from '../../../../core/shared/metadata.models'; -export const iiifEnabled = Object.assign(new MetadataValue(),{ - 'value': 'true', - 'language': null, - 'authority': null, - 'confidence': -1, - 'place': 0 -}); +export function getIIIFSearchEnabled(enabled: boolean): MetadataValue { + return Object.assign(new MetadataValue(), { + 'value': enabled, + 'language': null, + 'authority': null, + 'confidence': -1, + 'place': 0 + }); +} -export const iiifSearchEnabled = Object.assign(new MetadataValue(), { - 'value': 'true', - 'language': null, - 'authority': null, - 'confidence': -1, - 'place': 0 -}); +export function getIIIFEnabled(enabled: boolean): MetadataValue { + return Object.assign(new MetadataValue(), { + 'value': enabled, + 'language': null, + 'authority': null, + 'confidence': -1, + 'place': 0 + }); +} export const mockRouteService = jasmine.createSpyObj('RouteService', ['getPreviousUrl']); diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts index efbb4672a5..b5ac779086 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts @@ -1,10 +1,10 @@ import { HttpClient } from '@angular/common/http'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store } from '@ngrx/store'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../../../../core/cache/object-cache.service'; import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; @@ -26,13 +26,10 @@ import { TruncatableService } from '../../../../shared/truncatable/truncatable.s import { TruncatePipe } from '../../../../shared/utils/truncate.pipe'; import { GenericItemPageFieldComponent } from '../../field-components/specific-field/generic/generic-item-page-field.component'; import { - createRelationshipsObservable, - iiifEnabled, - iiifSearchEnabled, mockRouteService + createRelationshipsObservable, getIIIFEnabled, getIIIFSearchEnabled, mockRouteService } from '../shared/item.component.spec'; import { UntypedItemComponent } from './untyped-item.component'; import { RouteService } from '../../../../core/services/route.service'; -import { of } from 'rxjs'; import { createPaginatedList } from '../../../../shared/testing/utils.test'; import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service'; import { VersionDataService } from '../../../../core/data/version-data.service'; @@ -41,16 +38,6 @@ import { WorkspaceitemDataService } from '../../../../core/submission/workspacei import { SearchService } from '../../../../core/shared/search/search.service'; import { ItemVersionsSharedService } from '../../../../shared/item/item-versions/item-versions-shared.service'; - -const iiifEnabledMap: MetadataMap = { - 'dspace.iiif.enabled': [iiifEnabled], -}; - -const iiifEnabledWithSearchMap: MetadataMap = { - 'dspace.iiif.enabled': [iiifEnabled], - 'iiif.search.enabled': [iiifSearchEnabled], -}; - const noMetadata = new MetadataMap(); function getItem(metadata: MetadataMap) { @@ -108,11 +95,12 @@ describe('UntypedItemComponent', () => { schemas: [NO_ERRORS_SCHEMA] }).overrideComponent(UntypedItemComponent, { set: {changeDetection: ChangeDetectionStrategy.Default} - }).compileComponents(); + }); })); describe('default view', () => { beforeEach(waitForAsync(() => { + TestBed.compileComponents(); fixture = TestBed.createComponent(UntypedItemComponent); comp = fixture.componentInstance; comp.object = getItem(noMetadata); @@ -159,6 +147,41 @@ describe('UntypedItemComponent', () => { describe('with IIIF viewer', () => { beforeEach(waitForAsync(() => { + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(false)], + }; + TestBed.compileComponents(); + fixture = TestBed.createComponent(UntypedItemComponent); + comp = fixture.componentInstance; + comp.object = getItem(iiifEnabledMap); + fixture.detectChanges(); + })); + + it('should contain an iiif viewer component', () => { + const fields = fixture.debugElement.queryAll(By.css('ds-mirador-viewer')); + expect(fields.length).toBeGreaterThanOrEqual(1); + }); + it('should not retrieve the query term for previous route', (): void => { + expect(comp.iiifQuery$).toBeFalsy(); + }); + + }); + + describe('with IIIF viewer and search', () => { + + beforeEach(waitForAsync(() => { + const localMockRouteService = { + getPreviousUrl(): Observable { + return of('/search?query=test') + } + }; + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(true)], + }; + TestBed.overrideProvider(RouteService, {useValue: localMockRouteService}); + TestBed.compileComponents(); fixture = TestBed.createComponent(UntypedItemComponent); comp = fixture.componentInstance; comp.object = getItem(iiifEnabledMap); @@ -170,15 +193,29 @@ describe('UntypedItemComponent', () => { expect(fields.length).toBeGreaterThanOrEqual(1); }); + it('should retrieve the query term for previous route', (): void => { + expect(comp.iiifQuery$.subscribe(result => expect(result).toEqual('test'))); + }); + }); - describe('with IIIF viewer and search', () => { + describe('with IIIF viewer and search but no previous search query', () => { beforeEach(waitForAsync(() => { - mockRouteService.getPreviousUrl.and.returnValue(of(['/search?q=bird&motivation=painting','/item'])); + const localMockRouteService = { + getPreviousUrl(): Observable { + return of('/item') + } + }; + const iiifEnabledMap: MetadataMap = { + 'dspace.iiif.enabled': [getIIIFEnabled(true)], + 'iiif.search.enabled': [getIIIFSearchEnabled(true)], + }; + TestBed.overrideProvider(RouteService, {useValue: localMockRouteService}); + TestBed.compileComponents(); fixture = TestBed.createComponent(UntypedItemComponent); comp = fixture.componentInstance; - comp.object = getItem(iiifEnabledWithSearchMap); + comp.object = getItem(iiifEnabledMap); fixture.detectChanges(); })); @@ -187,9 +224,12 @@ describe('UntypedItemComponent', () => { expect(fields.length).toBeGreaterThanOrEqual(1); }); - it('should call the RouteService getHistory method', () => { - expect(mockRouteService.getPreviousUrl).toHaveBeenCalled(); - }); + it('should not retrieve the query term for previous route', fakeAsync( () => { + let emitted; + comp.iiifQuery$.subscribe(result => emitted = result); + tick(10) + expect(emitted).toBeUndefined() + })); });