[CSTPER-66] moved refreshCache function to common ComColDataService, tests have been moved accordingly.

Used HalEndpointService to discover communities search top endpoint
This commit is contained in:
Corrado Lombardi
2020-11-17 09:29:01 +01:00
parent 9658da4fc0
commit c40f31279f
6 changed files with 125 additions and 191 deletions

View File

@@ -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<CoreState>;
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');
});
});
});
});
});

View File

@@ -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<T extends CacheableObject> extends DataService<T> {
protected abstract cds: CommunityDataService;
@@ -119,4 +121,23 @@ export abstract class ComColDataService<T extends CacheableObject> 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<any>) => {
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;
}
}

View File

@@ -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');
});
});
});
});
});

View File

@@ -101,7 +101,7 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject> 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<TDomain extends DSpaceObject> 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<TDomain>) => {
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;
}
}

View File

@@ -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<DSpaceObject>;
@@ -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', () => {

View File

@@ -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<TDomain extends DSpaceObject> implements
public dsoRD$: Observable<RemoteData<TDomain>>;
public constructor(
protected dsoDataService: DataService<TDomain>,
protected dsoDataService: ComColDataService<TDomain>,
protected router: Router,
protected route: ActivatedRoute,
protected notifications: NotificationsService,
@@ -58,7 +59,7 @@ export class DeleteComColPageComponent<TDomain extends DSpaceObject> 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<TDomain extends DSpaceObject> 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<TDomain>) => {
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;
}
}