diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4e105ce6d5..d08eaf48708 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,17 +102,17 @@ jobs: - name: Install Yarn dependencies run: yarn install --frozen-lockfile -# - name: Run lint -# run: yarn run lint --quiet + - name: Run lint + run: yarn run lint --quiet -# - name: Check for circular dependencies -# run: yarn run check-circ-deps + - name: Check for circular dependencies + run: yarn run check-circ-deps - name: Run build run: yarn run build:prod -# - name: Run specs (unit tests) -# run: yarn run test:headless + - name: Run specs (unit tests) + run: yarn run test:headless # Upload code coverage report to artifact (for one version of Node only), # so that it can be shared with the 'codecov' job (see below) diff --git a/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.spec.ts b/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.spec.ts index 38be4dbb389..7acb8a6c7fa 100644 --- a/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.spec.ts +++ b/src/app/bitstream-page/legacy-bitstream-url-redirect.guard.spec.ts @@ -1,6 +1,9 @@ +import { TestBed } from '@angular/core/testing'; +import { Router } from '@angular/router'; import { cold } from 'jasmine-marbles'; import { EMPTY } from 'rxjs'; +import { APP_CONFIG } from '../../config/app-config.interface'; import { PAGE_NOT_FOUND_PATH } from '../app-routing-paths'; import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { RemoteData } from '../core/data/remote-data'; @@ -44,6 +47,15 @@ describe('legacyBitstreamURLRedirectGuard', () => { findByItemHandle: () => undefined } as any; resolver = legacyBitstreamURLRedirectGuard; + + TestBed.configureTestingModule({ + providers: [ + { provide: BitstreamDataService, useValue: bitstreamDataService }, + { provide: HardRedirectService, useValue: hardRedirectService }, + { provide: Router, useValue: router }, + { provide: APP_CONFIG, useValue: { ui: { nameSpace: '/' } } } + ] + }); }); describe(`resolve`, () => { @@ -60,12 +72,14 @@ describe('legacyBitstreamURLRedirectGuard', () => { }); }); it(`should call findByItemHandle with the handle, sequence id, and filename from the route`, () => { - resolver(route, state, bitstreamDataService, hardRedirectService, router); - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( - `${route.params.prefix}/${route.params.suffix}`, - route.params.sequence_id, - route.params.filename - ); + TestBed.runInInjectionContext(() => { + resolver(route, state); + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( + `${route.params.prefix}/${route.params.suffix}`, + route.params.sequence_id, + route.params.filename + ); + }); }); }); @@ -85,12 +99,14 @@ describe('legacyBitstreamURLRedirectGuard', () => { }); }); it(`should call findByItemHandle with the handle and filename from the route, and the sequence ID from the queryParams`, () => { - resolver(route, state, bitstreamDataService, hardRedirectService, router); - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( - `${route.params.prefix}/${route.params.suffix}`, - route.queryParams.sequenceId, - route.params.filename - ); + TestBed.runInInjectionContext(() => { + resolver(route, state); + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( + `${route.params.prefix}/${route.params.suffix}`, + route.queryParams.sequenceId, + route.params.filename + ); + }); }); }); describe(`when there's no sequenceId query parameter`, () => { @@ -105,12 +121,14 @@ describe('legacyBitstreamURLRedirectGuard', () => { }); }); it(`should call findByItemHandle with the handle, and filename from the route`, () => { - resolver(route, state, bitstreamDataService, hardRedirectService, router); - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( - `${route.params.prefix}/${route.params.suffix}`, - undefined, - route.params.filename - ); + TestBed.runInInjectionContext(() => { + resolver(route, state); + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalledWith( + `${route.params.prefix}/${route.params.suffix}`, + undefined, + route.params.filename + ); + }); }); }); }); @@ -122,9 +140,11 @@ describe('legacyBitstreamURLRedirectGuard', () => { b: remoteDataMocks.ResponsePending, c: remoteDataMocks.Error, })); - resolver(route, state, bitstreamDataService, hardRedirectService, router).subscribe(() => { - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); - expect(router.createUrlTree).toHaveBeenCalledWith([PAGE_NOT_FOUND_PATH]); + TestBed.runInInjectionContext(() => { + resolver(route, state).subscribe(() => { + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); + expect(router.createUrlTree).toHaveBeenCalledWith([PAGE_NOT_FOUND_PATH]); + }); }); }); @@ -135,9 +155,11 @@ describe('legacyBitstreamURLRedirectGuard', () => { b: remoteDataMocks.ResponsePending, c: remoteDataMocks.NoContent, })); - resolver(route, state, bitstreamDataService, hardRedirectService, router).subscribe(() => { - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); - expect(router.createUrlTree).toHaveBeenCalledWith([PAGE_NOT_FOUND_PATH]); + TestBed.runInInjectionContext(() => { + resolver(route, state).subscribe(() => { + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); + expect(router.createUrlTree).toHaveBeenCalledWith([PAGE_NOT_FOUND_PATH]); + }); }); }); @@ -148,9 +170,11 @@ describe('legacyBitstreamURLRedirectGuard', () => { b: remoteDataMocks.ResponsePending, c: remoteDataMocks.Success, })); - resolver(route, state, bitstreamDataService, hardRedirectService, router).subscribe(() => { - expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); - expect(hardRedirectService.redirect).toHaveBeenCalledWith(new URL(`/bitstreams/${bitstream.uuid}/download`, window.location.origin).href, 301); + TestBed.runInInjectionContext(() => { + resolver(route, state).subscribe(() => { + expect(bitstreamDataService.findByItemHandle).toHaveBeenCalled(); + expect(hardRedirectService.redirect).toHaveBeenCalledWith(new URL(`/bitstreams/${bitstream.uuid}/download`, window.location.origin).href, 301); + }); }); }); }); diff --git a/src/app/core/metadata/metadata.service.spec.ts b/src/app/core/metadata/metadata.service.spec.ts index fac3937643e..76258ca839a 100644 --- a/src/app/core/metadata/metadata.service.spec.ts +++ b/src/app/core/metadata/metadata.service.spec.ts @@ -181,7 +181,7 @@ describe('MetadataService', () => { })); it('route titles should overwrite dso titles', fakeAsync(() => { - (translateService.get as jasmine.Spy).and.returnValues(of('DSpace :: '), of('Translated Route Title')); + (translateService.get as jasmine.Spy).and.returnValues(of('DSpace ::'), of('Translated Route Title')); (metadataService as any).processRouteChange({ data: { value: { @@ -197,7 +197,7 @@ describe('MetadataService', () => { })); it('other navigation should add title and description', fakeAsync(() => { - (translateService.get as jasmine.Spy).and.returnValues(of('DSpace :: '), of('Dummy Title'), of('This is a dummy item component for testing!')); + (translateService.get as jasmine.Spy).and.returnValues(of('DSpace ::'), of('Dummy Title'), of('This is a dummy item component for testing!')); (metadataService as any).processRouteChange({ data: { value: { diff --git a/src/app/item-page/versions/item-versions.component.spec.ts b/src/app/item-page/versions/item-versions.component.spec.ts index 4f6237def53..819321c562d 100644 --- a/src/app/item-page/versions/item-versions.component.spec.ts +++ b/src/app/item-page/versions/item-versions.component.spec.ts @@ -182,10 +182,11 @@ describe('ItemVersionsComponent', () => { versions.forEach((version: Version, index: number) => { const versionItem = items[index]; - it(`should display version ${version.version} in the correct column for version ${version.id}`, () => { - const id = fixture.debugElement.query(By.css(`#version-row-${version.id} .version-row-element-version`)); - expect(id.nativeElement.textContent).toContain(version.version.toString()); - }); + // NOTE: CLARIN update removed version number display from the version column, so do not test it + // it(`should display version ${version.version} in the correct column for version ${version.id}`, () => { + // const id = fixture.debugElement.query(By.css(`#version-row-${version.id} .version-row-element-version`)); + // expect(id.nativeElement.textContent).toContain(version.version.toString()); + // }); // Check if the current version contains an asterisk if (item1.uuid === versionItem.uuid) { @@ -218,10 +219,14 @@ describe('ItemVersionsComponent', () => { }); describe('when the user can only delete a version', () => { - beforeAll(waitForAsync(() => { + beforeEach(() => { const canDelete = (featureID: FeatureID, url: string ) => of(featureID === FeatureID.CanDeleteVersion); authorizationServiceSpy.isAuthorized.and.callFake(canDelete); - })); + fixture.detectChanges(); + }); + afterEach(() => { + authorizationServiceSpy.isAuthorized.and.returnValue(of(true)); + }); it('should not disable the delete button', () => { const deleteButtons = fixture.debugElement.queryAll(By.css(`.version-row-element-delete`)); deleteButtons.forEach((btn) => { @@ -309,12 +314,16 @@ describe('ItemVersionsComponent', () => { fixture.detectChanges(); - // delete the last version in the table (version2 → item2) - deleteButton = fixture.debugElement.queryAll(By.css('.version-row-element-delete'))[1].nativeElement; + // delete version2 (displayed first in the table because versions are reversed) + deleteButton = fixture.debugElement.queryAll(By.css('.version-row-element-delete'))[0].nativeElement; itemDataServiceSpy.delete.calls.reset(); }); + afterEach(() => { + authorizationServiceSpy.isAuthorized.and.returnValue(of(true)); + }); + describe('if confirmed via modal', () => { beforeEach(waitForAsync(() => { deleteButton.click();