From c40f31279f820a80570cd82ef01ab53d065628b1 Mon Sep 17 00:00:00 2001 From: Corrado Lombardi Date: Tue, 17 Nov 2020 09:29:01 +0100 Subject: [PATCH] [CSTPER-66] moved refreshCache function to common ComColDataService, tests have been moved accordingly. Used HalEndpointService to discover communities search top endpoint --- src/app/core/data/comcol-data.service.spec.ts | 89 ++++++++++++++++++- src/app/core/data/comcol-data.service.ts | 21 +++++ .../create-comcol-page.component.spec.ts | 82 ++--------------- .../create-comcol-page.component.ts | 21 +---- .../delete-comcol-page.component.spec.ts | 79 ++-------------- .../delete-comcol-page.component.ts | 24 +---- 6 files changed, 125 insertions(+), 191 deletions(-) diff --git a/src/app/core/data/comcol-data.service.spec.ts b/src/app/core/data/comcol-data.service.spec.ts index 1ba19df18c..f48022e6f1 100644 --- a/src/app/core/data/comcol-data.service.spec.ts +++ b/src/app/core/data/comcol-data.service.spec.ts @@ -17,6 +17,7 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { FindByIDRequest, FindListOptions } from './request.models'; import { RequestEntry } from './request.reducer'; import { RequestService } from './request.service'; +import {createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$} from '../../shared/remote-data.utils'; const LINK_NAME = 'test'; @@ -51,7 +52,9 @@ describe('ComColDataService', () => { let objectCache: ObjectCacheService; let halService: any = {}; - const rdbService = {} as RemoteDataBuildService; + const rdbService = { + buildSingle : () => null + } as any; const store = {} as Store; const notificationsService = {} as NotificationsService; const http = {} as HttpClient; @@ -178,6 +181,90 @@ describe('ComColDataService', () => { }); }); + describe('cache refresh', () => { + let communityWithoutParentHref; + let data; + + beforeEach(() => { + scheduler = getTestScheduler(); + halService = { + getEndpoint: (linkPath) => 'https://rest.api/core/' + linkPath + }; + service = initTestService(); + + }) + describe('cache refreshed top level community', () => { + beforeEach(() => { + spyOn(rdbService, 'buildSingle').and.returnValue(createNoContentRemoteDataObject$()); + data = { + dso: Object.assign(new Community(), { + metadata: [{ + key: 'dc.title', + value: 'top level community' + }] + }), + _links: { + parentCommunity: { + href: 'topLevel/parentCommunity' + } + } + }; + communityWithoutParentHref = { + dso: Object.assign(new Community(), { + metadata: [{ + key: 'dc.title', + value: 'top level community' + }] + }), + _links: {} + }; + }); + it('top level community cache refreshed', () => { + scheduler.schedule(() => (service as any).refreshCache(data)); + scheduler.flush(); + expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith('https://rest.api/core/communities/search/top'); + }); + it('top level community without parent link, cache not refreshed', () => { + scheduler.schedule(() => (service as any).refreshCache(communityWithoutParentHref)); + scheduler.flush(); + expect(requestService.removeByHrefSubstring).not.toHaveBeenCalled(); + }); + }); + + describe('cache refreshed child community', () => { + beforeEach(() => { + const parentCommunity = Object.assign(new Community(), { + uuid: 'a20da287-e174-466a-9926-f66as300d399', + id: 'a20da287-e174-466a-9926-f66as300d399', + metadata: [{ + key: 'dc.title', + value: 'parent community' + }], + _links: {} + }); + spyOn(rdbService, 'buildSingle').and.returnValue(createSuccessfulRemoteDataObject$(parentCommunity)); + data = { + dso: Object.assign(new Community(), { + metadata: [{ + key: 'dc.title', + value: 'child community' + }] + }), + _links: { + parentCommunity: { + href: 'child/parentCommunity' + } + } + }; + }); + it('child level community cache refreshed', () => { + scheduler.schedule(() => (service as any).refreshCache(data)); + scheduler.flush(); + expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith('a20da287-e174-466a-9926-f66as300d399'); + }); + }); + }); + }); }); diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index d83518a3b0..86731b9696 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -21,12 +21,14 @@ import { configureRequest, getRemoteDataPayload, getResponseFromEntry, + getSucceededOrNoContentResponse, getSucceededRemoteData } from '../shared/operators'; import { CacheableObject } from '../cache/object-cache.reducer'; import { RestResponse } from '../cache/response.models'; import { Bitstream } from '../shared/bitstream.model'; import { DSpaceObject } from '../shared/dspace-object.model'; +import {Collection} from '../shared/collection.model'; export abstract class ComColDataService extends DataService { protected abstract cds: CommunityDataService; @@ -119,4 +121,23 @@ export abstract class ComColDataService extends DataS ); } } + + public refreshCache(dso: T) { + const parentCommunityUrl = this.parentCommunityUrl(dso as any); + if (!hasValue(parentCommunityUrl)) { + return; + } + this.findByHref(parentCommunityUrl).pipe( + getSucceededOrNoContentResponse(), + take(1), + ).subscribe((rd: RemoteData) => { + const href = rd.hasSucceeded && !isEmpty(rd.payload.id) ? rd.payload.id : this.halService.getEndpoint('communities/search/top'); + this.requestService.removeByHrefSubstring(href) + }); + } + + private parentCommunityUrl(dso: Collection | Community) { + const parentCommunity = dso._links.parentCommunity; + return isNotEmpty(parentCommunity) ? parentCommunity.href : null; + } } diff --git a/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.spec.ts b/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.spec.ts index a7496fbf7a..d7827957a1 100644 --- a/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.spec.ts +++ b/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.spec.ts @@ -79,7 +79,8 @@ describe('CreateComColPageComponent', () => { })), create: (com, uuid?) => createSuccessfulRemoteDataObject$(newCommunity), getLogoEndpoint: () => observableOf(logoEndpoint), - findByHref: () => null + findByHref: () => null, + refreshCache: () => {return} }; routeServiceStub = { @@ -150,21 +151,21 @@ describe('CreateComColPageComponent', () => { it('should navigate and refresh cache when successful', () => { spyOn(router, 'navigate'); - spyOn((comp as any), 'refreshCache') + spyOn((dsoDataService as any), 'refreshCache') scheduler.schedule(() => comp.onSubmit(data)); scheduler.flush(); expect(router.navigate).toHaveBeenCalled(); - expect((comp as any).refreshCache).toHaveBeenCalled(); + expect((dsoDataService as any).refreshCache).toHaveBeenCalled(); }); it('should neither navigate nor refresh cache on failure', () => { spyOn(router, 'navigate'); spyOn(dsoDataService, 'create').and.returnValue(createFailedRemoteDataObject$(newCommunity)); - spyOn((comp as any), 'refreshCache') + spyOn(dsoDataService, 'refreshCache') scheduler.schedule(() => comp.onSubmit(data)); scheduler.flush(); expect(router.navigate).not.toHaveBeenCalled(); - expect((comp as any).refreshCache).not.toHaveBeenCalled(); + expect((dsoDataService as any).refreshCache).not.toHaveBeenCalled(); }); }); @@ -212,76 +213,5 @@ describe('CreateComColPageComponent', () => { expect(data.uploader.uploadAll).toHaveBeenCalled(); }); }); - - describe('cache refresh', () => { - let communityWithoutParentHref; - - beforeEach(() => { - scheduler = getTestScheduler(); - - }) - describe('cache refreshed top level community', () => { - beforeEach(() => { - spyOn(dsoDataService, 'findByHref').and.returnValue(createNoContentRemoteDataObject$()); - data = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'top level community' - }] - }), - _links: { - parentCommunity: { - href: 'topLevel/parentCommunity' - } - } - }; - communityWithoutParentHref = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'top level community' - }] - }), - _links: {} - }; - }); - it('top level community cache refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(data)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).toHaveBeenCalledWith('communities/search/top'); - }); - it('top level community without parent link, cache not refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(communityWithoutParentHref)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).not.toHaveBeenCalled(); - }); - }); - - describe('cache refreshed child community', () => { - beforeEach(() => { - spyOn(dsoDataService, 'findByHref').and.returnValue(createSuccessfulRemoteDataObject$(parentCommunity)); - data = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'child community' - }] - }), - _links: { - parentCommunity: { - href: 'child/parentCommunity' - } - } - }; - }); - it('child level community cache refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(data)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).toHaveBeenCalledWith('a20da287-e174-466a-9926-f66as300d399'); - }); - }); - }); - }); }); diff --git a/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.ts b/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.ts index 336998aab3..cb1f41dd23 100644 --- a/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.ts +++ b/src/app/shared/comcol-forms/create-comcol-page/create-comcol-page.component.ts @@ -101,7 +101,7 @@ export class CreateComColPageComponent implements } else { this.navigateToNewPage(); } - this.refreshCache(dsoRD); + this.dsoDataService.refreshCache(dsoRD); } this.notificationsService.success(null, this.translate.get(this.type.value + '.create.notifications.success')); }); @@ -115,23 +115,4 @@ export class CreateComColPageComponent implements this.router.navigate([this.frontendURL + this.newUUID]); } } - - private refreshCache(dso: TDomain) { - const parentCommunityUrl = this.parentCommunityUrl(dso as any); - if (!hasValue(parentCommunityUrl)) { - return; - } - this.dsoDataService.findByHref(parentCommunityUrl).pipe( - getSucceededOrNoContentResponse(), - take(1), - ).subscribe((rd: RemoteData) => { - const href = rd.hasSucceeded && !isEmpty(rd.payload.id) ? rd.payload.id : 'communities/search/top'; - this.requestService.removeByHrefSubstring(href) - }); - } - - private parentCommunityUrl(dso: Collection | Community) { - const parentCommunity = dso._links.parentCommunity; - return isNotEmpty(parentCommunity) ? parentCommunity.href : null; - } } diff --git a/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.spec.ts b/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.spec.ts index b5a3ccea5d..6669f4c395 100644 --- a/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.spec.ts +++ b/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.spec.ts @@ -16,6 +16,7 @@ import { NotificationsServiceStub } from '../../testing/notifications-service.st import {RequestService} from '../../../core/data/request.service'; import {getTestScheduler} from 'jasmine-marbles'; import {createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$} from '../../remote-data.utils'; +import {ComColDataService} from '../../../core/data/comcol-data.service'; describe('DeleteComColPageComponent', () => { let comp: DeleteComColPageComponent; @@ -67,7 +68,8 @@ describe('DeleteComColPageComponent', () => { 'dsoDataService', { delete: observableOf({ isSuccessful: true }), - findByHref: jasmine.createSpy('findByHref') + findByHref: jasmine.createSpy('findByHref'), + refreshCache: jasmine.createSpy('refreshCache') }); routerStub = { @@ -93,7 +95,7 @@ describe('DeleteComColPageComponent', () => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), SharedModule, CommonModule, RouterTestingModule], providers: [ - { provide: DataService, useValue: dsoDataService }, + { provide: ComColDataService, useValue: dsoDataService }, { provide: Router, useValue: routerStub }, { provide: ActivatedRoute, useValue: routeStub }, { provide: NotificationsService, useValue: new NotificationsServiceStub() }, @@ -153,23 +155,21 @@ describe('DeleteComColPageComponent', () => { it('should show an error notification on failure', () => { (dsoDataService.delete as any).and.returnValue(observableOf({ isSuccessful: false })); spyOn(router, 'navigate'); - spyOn((comp as any), 'refreshCache'); scheduler.schedule(() => comp.onConfirm(data2)); scheduler.flush(); fixture.detectChanges(); expect(notificationsService.error).toHaveBeenCalled(); - expect((comp as any).refreshCache).not.toHaveBeenCalled(); + expect(dsoDataService.refreshCache).not.toHaveBeenCalled(); expect(router.navigate).toHaveBeenCalled(); }); it('should show a success notification on success and navigate', () => { spyOn(router, 'navigate'); - spyOn((comp as any), 'refreshCache'); scheduler.schedule(() => comp.onConfirm(data1)); scheduler.flush(); fixture.detectChanges(); expect(notificationsService.success).toHaveBeenCalled(); - expect((comp as any).refreshCache).toHaveBeenCalled(); + expect(dsoDataService.refreshCache).toHaveBeenCalled(); expect(router.navigate).toHaveBeenCalled(); }); @@ -178,73 +178,6 @@ describe('DeleteComColPageComponent', () => { fixture.detectChanges(); expect(dsoDataService.delete).toHaveBeenCalledWith(data1.id); }); - - describe('cache refresh', () => { - let communityWithoutParentHref; - let deletedCommunity; - - describe('cache refreshed top level community', () => { - beforeEach(() => { - (dsoDataService.findByHref as any).and.returnValue(createNoContentRemoteDataObject$()); - deletedCommunity = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'top level community' - }] - }), - _links: { - parentCommunity: { - href: 'topLevel/parentCommunity' - } - } - }; - communityWithoutParentHref = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'top level community' - }] - }), - _links: {} - }; - }); - it('top level community cache refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(deletedCommunity)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).toHaveBeenCalledWith('communities/search/top'); - }); - it('top level community without parent link, cache not refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(communityWithoutParentHref)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).not.toHaveBeenCalled(); - }); - }); - - describe('cache refreshed child community', () => { - beforeEach(() => { - (dsoDataService.findByHref as any).and.returnValue(createSuccessfulRemoteDataObject$(parentCommunity)); - deletedCommunity = { - dso: Object.assign(new Community(), { - metadata: [{ - key: 'dc.title', - value: 'child community' - }] - }), - _links: { - parentCommunity: { - href: 'child/parentCommunity' - } - } - }; - }); - it('child level community cache refreshed', () => { - scheduler.schedule(() => (comp as any).refreshCache(deletedCommunity)); - scheduler.flush(); - expect(requestServiceStub.removeByHrefSubstring).toHaveBeenCalledWith('a20da287-e174-466a-9926-f66as300d399'); - }); - }); - }); }); describe('onCancel', () => { diff --git a/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.ts b/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.ts index 835d302de3..d71660b297 100644 --- a/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.ts +++ b/src/app/shared/comcol-forms/delete-comcol-page/delete-comcol-page.component.ts @@ -15,6 +15,7 @@ import { } from '../../../core/shared/operators'; import {Community} from '../../../core/shared/community.model'; import {Collection} from '../../../core/shared/collection.model'; +import {ComColDataService} from '../../../core/data/comcol-data.service'; /** * Component representing the delete page for communities and collections @@ -34,7 +35,7 @@ export class DeleteComColPageComponent implements public dsoRD$: Observable>; public constructor( - protected dsoDataService: DataService, + protected dsoDataService: ComColDataService, protected router: Router, protected route: ActivatedRoute, protected notifications: NotificationsService, @@ -58,7 +59,7 @@ export class DeleteComColPageComponent implements if (response.isSuccessful) { const successMessage = this.translate.instant((dso as any).type + '.delete.notification.success'); this.notifications.success(successMessage) - this.refreshCache(dso); + this.dsoDataService.refreshCache(dso); } else { const errorMessage = this.translate.instant((dso as any).type + '.delete.notification.fail'); this.notifications.error(errorMessage) @@ -74,23 +75,4 @@ export class DeleteComColPageComponent implements onCancel(dso: TDomain) { this.router.navigate([this.frontendURL + '/' + dso.uuid + '/edit']); } - - private refreshCache(dso: TDomain) { - const parentCommunityUrl = this.parentCommunityUrl(dso as any); - if (!hasValue(parentCommunityUrl)) { - return; - } - this.dsoDataService.findByHref(parentCommunityUrl).pipe( - getSucceededOrNoContentResponse(), - take(1), - ).subscribe((rd: RemoteData) => { - const href = rd.hasSucceeded && !isEmpty(rd.payload.id) ? rd.payload.id : 'communities/search/top'; - this.requestService.removeByHrefSubstring(href) - }); - } - - private parentCommunityUrl(dso: Collection | Community): string { - const parentCommunity = dso._links.parentCommunity; - return isNotEmpty(parentCommunity) ? parentCommunity.href : null; - } }