From d295fa422fced92c53ab828bc4e6286ed1f3dec9 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Thu, 9 Jul 2020 12:25:40 +0200 Subject: [PATCH] 71712: Item export no longer redirects & test async fixes --- .../dso-selector/dso-selector.component.html | 3 +- .../dso-selector/dso-selector.component.ts | 6 +++ ...export-metadata-selector.component.spec.ts | 42 ++++++++++++---- .../export-metadata-selector.component.ts | 50 +++++++++++-------- 4 files changed, 68 insertions(+), 33 deletions(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html index e2eda4dcfd..8a30399391 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html @@ -15,6 +15,7 @@ class="list-group-item list-group-item-action border-0 list-entry" title="{{ listEntry.indexableObject.name }}" (click)="onSelect.emit(listEntry.indexableObject)" #listEntryElement> - + diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index c27c5e6d13..04cfd32e3b 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -13,6 +13,7 @@ import { FormControl } from '@angular/forms'; import { Observable } from 'rxjs'; import { debounceTime, startWith, switchMap } from 'rxjs/operators'; import { SearchService } from '../../../core/shared/search/search.service'; +import { CollectionElementLinkType } from '../../object-collection/collection-element-link.type'; import { PaginatedSearchOptions } from '../../search/paginated-search-options.model'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { RemoteData } from '../../../core/data/remote-data'; @@ -76,6 +77,11 @@ export class DSOSelectorComponent implements OnInit { */ debounceTime = 500; + /** + * The available link types + */ + linkTypes = CollectionElementLinkType; + constructor(private searchService: SearchService) { } diff --git a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.spec.ts b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.spec.ts index 16dcee38d8..550c28f556 100644 --- a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.spec.ts +++ b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.spec.ts @@ -30,7 +30,7 @@ describe('ExportMetadataSelectorComponent', () => { lastModified: '2018' }); - const mockCollection1: Collection = Object.assign(new Collection(), { + const mockCollection: Collection = Object.assign(new Collection(), { id: 'test-collection-1-1', name: 'test-collection-1', handle: 'fake/test-collection-1', @@ -100,26 +100,36 @@ describe('ExportMetadataSelectorComponent', () => { }); describe('if item is selected', () => { - beforeEach(() => { - component.navigate(mockItem); + let scriptRequestSucceeded; + beforeEach((done) => { + component.navigate(mockItem).subscribe((succeeded: boolean) => { + scriptRequestSucceeded = succeeded; + done() + }); }); it('should show error notification', () => { expect(notificationService.error).toHaveBeenCalled(); + expect(scriptRequestSucceeded).toBeFalse(); }); }); describe('if collection is selected', () => { - beforeEach(() => { - component.navigate(mockCollection1); + let scriptRequestSucceeded; + beforeEach((done) => { + component.navigate(mockCollection).subscribe((succeeded: boolean) => { + scriptRequestSucceeded = succeeded; + done() + }); }); it('metadata-export script is invoked with its -i handle and -f uuid.csv', () => { const parameterValues: ProcessParameter[] = [ - Object.assign(new ProcessParameter(), { name: '-i', value: mockCollection1.handle }), - Object.assign(new ProcessParameter(), { name: '-f', value: mockCollection1.uuid + '.csv' }), + Object.assign(new ProcessParameter(), { name: '-i', value: mockCollection.handle }), + Object.assign(new ProcessParameter(), { name: '-f', value: mockCollection.uuid + '.csv' }), ]; expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []); }); it('success notification is shown', () => { + expect(scriptRequestSucceeded).toBeTrue(); expect(notificationService.success).toHaveBeenCalled(); }); it('redirected to process page', () => { @@ -128,8 +138,12 @@ describe('ExportMetadataSelectorComponent', () => { }); describe('if community is selected', () => { - beforeEach(() => { - component.navigate(mockCommunity); + let scriptRequestSucceeded; + beforeEach((done) => { + component.navigate(mockCommunity).subscribe((succeeded: boolean) => { + scriptRequestSucceeded = succeeded; + done() + }); }); it('metadata-export script is invoked with its -i handle and -f uuid.csv', () => { const parameterValues: ProcessParameter[] = [ @@ -139,6 +153,7 @@ describe('ExportMetadataSelectorComponent', () => { expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []); }); it('success notification is shown', () => { + expect(scriptRequestSucceeded).toBeTrue(); expect(notificationService.success).toHaveBeenCalled(); }); it('redirected to process page', () => { @@ -147,7 +162,8 @@ describe('ExportMetadataSelectorComponent', () => { }); describe('if community/collection is selected; but script invoke fails', () => { - beforeEach(() => { + let scriptRequestSucceeded; + beforeEach((done) => { jasmine.getEnv().allowRespy(true); spyOn(scriptService, 'invoke').and.returnValue(observableOf({ response: @@ -155,9 +171,13 @@ describe('ExportMetadataSelectorComponent', () => { isSuccessful: false, } })); - component.navigate(mockCommunity); + component.navigate(mockCommunity).subscribe((succeeded: boolean) => { + scriptRequestSucceeded = succeeded; + done() + }); }); it('error notification is shown', () => { + expect(scriptRequestSucceeded).toBeFalse(); expect(notificationService.error).toHaveBeenCalled(); }); }); diff --git a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts index e5c4befcd8..88f01404e8 100644 --- a/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component.ts @@ -1,7 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; -import { take } from 'rxjs/operators'; +import { Observable } from 'rxjs/internal/Observable'; +import { take, map } from 'rxjs/operators'; +import { of as observableOf } from 'rxjs'; import { ScriptDataService } from '../../../../core/data/processes/script-data.service'; import { RequestEntry } from '../../../../core/data/request.reducer'; import { Collection } from '../../../../core/shared/collection.model'; @@ -39,11 +41,14 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp * If the dso is a collection or community: start export-metadata script & navigate to process if successful * Otherwise show error message */ - navigate(dso: DSpaceObject) { + navigate(dso: DSpaceObject): Observable { if (dso instanceof Collection || dso instanceof Community) { - this.startScriptNotifyAndRedirect(dso, dso.handle); + const startScriptSucceeded = this.startScriptNotifyAndRedirect(dso, dso.handle); + startScriptSucceeded.pipe(take(1)).subscribe(); + return startScriptSucceeded; } else { this.notificationsService.error(this.translationService.get('dso-selector.export-metadata.notValidDSO')); + return observableOf(false); } } @@ -52,28 +57,31 @@ export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComp * Otherwise show error message * @param dso Dso to export */ - private startScriptNotifyAndRedirect(dso: DSpaceObject, handle: string) { + private startScriptNotifyAndRedirect(dso: DSpaceObject, handle: string): Observable { const parameterValues: ProcessParameter[] = [ Object.assign(new ProcessParameter(), { name: '-i', value: handle }), Object.assign(new ProcessParameter(), { name: '-f', value: dso.uuid + '.csv' }), ]; - this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []) - .pipe(take(1)) - .subscribe((requestEntry: RequestEntry) => { - if (requestEntry.response.isSuccessful) { - const title = this.translationService.get('process.new.notification.success.title'); - const content = this.translationService.get('process.new.notification.success.content'); - this.notificationsService.success(title, content); - const response: any = requestEntry.response; - if (isNotEmpty(response.resourceSelfLinks)) { - const processNumber = response.resourceSelfLinks[0].split('/').pop(); - this.router.navigateByUrl('/processes/' + processNumber); + return this.scriptDataService.invoke(METADATA_EXPORT_SCRIPT_NAME, parameterValues, []) + .pipe( + take(1), + map((requestEntry: RequestEntry) => { + if (requestEntry.response.isSuccessful) { + const title = this.translationService.get('process.new.notification.success.title'); + const content = this.translationService.get('process.new.notification.success.content'); + this.notificationsService.success(title, content); + const response: any = requestEntry.response; + if (isNotEmpty(response.resourceSelfLinks)) { + const processNumber = response.resourceSelfLinks[0].split('/').pop(); + this.router.navigateByUrl('/processes/' + processNumber); + } + return true; + } else { + const title = this.translationService.get('process.new.notification.error.title'); + const content = this.translationService.get('process.new.notification.error.content'); + this.notificationsService.error(title, content); + return false; } - } else { - const title = this.translationService.get('process.new.notification.error.title'); - const content = this.translationService.get('process.new.notification.error.content'); - this.notificationsService.error(title, content); - } - }); + })); } }