Merge pull request #916 from 4Science/CSTPER-66

Communities and collections not shown right after creation
This commit is contained in:
Tim Donohue
2020-11-19 14:52:46 -06:00
committed by GitHub
17 changed files with 328 additions and 82 deletions

View File

@@ -12,6 +12,7 @@ import { CommunityDataService } from '../../core/data/community-data.service';
import { CreateCollectionPageComponent } from './create-collection-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import {RequestService} from '../../core/data/request.service';
describe('CreateCollectionPageComponent', () => {
let comp: CreateCollectionPageComponent;
@@ -29,7 +30,8 @@ describe('CreateCollectionPageComponent', () => {
},
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
{ provide: Router, useValue: {} },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: RequestService, useValue: {}}
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();

View File

@@ -7,6 +7,7 @@ import { Collection } from '../../core/shared/collection.model';
import { CollectionDataService } from '../../core/data/collection-data.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
import {RequestService} from '../../core/data/request.service';
/**
* Component that represents the page where a user can create a new Collection
@@ -26,8 +27,9 @@ export class CreateCollectionPageComponent extends CreateComColPageComponent<Col
protected routeService: RouteService,
protected router: Router,
protected notificationsService: NotificationsService,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
super(collectionDataService, communityDataService, routeService, router, notificationsService, translate);
super(collectionDataService, communityDataService, routeService, router, notificationsService, translate, requestService);
}
}

View File

@@ -9,6 +9,7 @@ import { of as observableOf } from 'rxjs';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { DeleteCollectionPageComponent } from './delete-collection-page.component';
import { CollectionDataService } from '../../core/data/collection-data.service';
import {RequestService} from '../../core/data/request.service';
describe('DeleteCollectionPageComponent', () => {
let comp: DeleteCollectionPageComponent;
@@ -22,6 +23,7 @@ describe('DeleteCollectionPageComponent', () => {
{ provide: CollectionDataService, useValue: {} },
{ provide: ActivatedRoute, useValue: { data: observableOf({ dso: { payload: {} } }) } },
{ provide: NotificationsService, useValue: {} },
{ provide: RequestService, useValue: {} }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();

View File

@@ -5,6 +5,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { CollectionDataService } from '../../core/data/collection-data.service';
import { Collection } from '../../core/shared/collection.model';
import { TranslateService } from '@ngx-translate/core';
import {RequestService} from '../../core/data/request.service';
/**
* Component that represents the page where a user can delete an existing Collection
@@ -22,8 +23,9 @@ export class DeleteCollectionPageComponent extends DeleteComColPageComponent<Col
protected router: Router,
protected route: ActivatedRoute,
protected notifications: NotificationsService,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
super(dsoDataService, router, route, notifications, translate);
super(dsoDataService, router, route, notifications, translate, requestService);
}
}

View File

@@ -12,6 +12,7 @@ import { CommunityDataService } from '../../core/data/community-data.service';
import { CreateCommunityPageComponent } from './create-community-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import {RequestService} from '../../core/data/request.service';
describe('CreateCommunityPageComponent', () => {
let comp: CreateCommunityPageComponent;
@@ -25,7 +26,8 @@ describe('CreateCommunityPageComponent', () => {
{ provide: CommunityDataService, useValue: { findById: () => observableOf({}) } },
{ provide: RouteService, useValue: { getQueryParameterValue: () => observableOf('1234') } },
{ provide: Router, useValue: {} },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: RequestService, useValue: {} }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();

View File

@@ -6,6 +6,7 @@ import { Router } from '@angular/router';
import { CreateComColPageComponent } from '../../shared/comcol-forms/create-comcol-page/create-comcol-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
import {RequestService} from '../../core/data/request.service';
/**
* Component that represents the page where a user can create a new Community
@@ -24,8 +25,9 @@ export class CreateCommunityPageComponent extends CreateComColPageComponent<Comm
protected routeService: RouteService,
protected router: Router,
protected notificationsService: NotificationsService,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
super(communityDataService, communityDataService, routeService, router, notificationsService, translate);
super(communityDataService, communityDataService, routeService, router, notificationsService, translate, requestService);
}
}

View File

@@ -9,6 +9,7 @@ import { CommunityDataService } from '../../core/data/community-data.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { SharedModule } from '../../shared/shared.module';
import { DeleteCommunityPageComponent } from './delete-community-page.component';
import {RequestService} from '../../core/data/request.service';
describe('DeleteCommunityPageComponent', () => {
let comp: DeleteCommunityPageComponent;
@@ -22,6 +23,7 @@ describe('DeleteCommunityPageComponent', () => {
{ provide: CommunityDataService, useValue: {} },
{ provide: ActivatedRoute, useValue: { data: observableOf({ dso: { payload: {} } }) } },
{ provide: NotificationsService, useValue: {} },
{ provide: RequestService, useValue: {}}
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();

View File

@@ -5,6 +5,7 @@ import { ActivatedRoute, Router } from '@angular/router';
import { DeleteComColPageComponent } from '../../shared/comcol-forms/delete-comcol-page/delete-comcol-page.component';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
import {RequestService} from '../../core/data/request.service';
/**
* Component that represents the page where a user can delete an existing Community
@@ -22,8 +23,10 @@ export class DeleteCommunityPageComponent extends DeleteComColPageComponent<Comm
protected router: Router,
protected route: ActivatedRoute,
protected notifications: NotificationsService,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
super(dsoDataService, router, route, notifications, translate);
super(dsoDataService, router, route, notifications, translate, requestService);
}
}

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.parentCommunityUrlLookup(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 parentCommunityUrlLookup(dso: Collection | Community) {
const parentCommunity = dso._links.parentCommunity;
return isNotEmpty(parentCommunity) ? parentCommunity.href : null;
}
}

View File

@@ -55,4 +55,8 @@ export class RemoteData<T> {
return this.state === RemoteDataState.Success;
}
get hasNoContent(): boolean {
return this.statusCode === 204;
}
}

View File

@@ -75,6 +75,10 @@ export const getSucceededRemoteWithNotEmptyData = () =>
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded && isNotEmpty(rd.payload)));
export const getSucceededOrNoContentResponse = () =>
<T>(source: Observable<RemoteData<T>>): Observable<RemoteData<T>> =>
source.pipe(find((rd: RemoteData<T>) => rd.hasSucceeded || rd.hasNoContent));
/**
* Get the first successful remotely retrieved object
*

View File

@@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { RouteService } from '../../../core/services/route.service';
import { Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Community } from '../../../core/shared/community.model';
import { SharedModule } from '../../shared.module';
@@ -12,12 +12,14 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { CreateComColPageComponent } from './create-comcol-page.component';
import {
createFailedRemoteDataObject$,
createFailedRemoteDataObject$, createNoContentRemoteDataObject$,
createSuccessfulRemoteDataObject$
} from '../../remote-data.utils';
import { ComColDataService } from '../../../core/data/comcol-data.service';
import { NotificationsService } from '../../notifications/notifications.service';
import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
import { RequestService } from '../../../core/data/request.service';
import {getTestScheduler} from 'jasmine-marbles';
describe('CreateComColPageComponent', () => {
let comp: CreateComColPageComponent<DSpaceObject>;
@@ -29,9 +31,12 @@ describe('CreateComColPageComponent', () => {
let community;
let newCommunity;
let parentCommunity;
let communityDataServiceStub;
let routeServiceStub;
let routerStub;
let requestServiceStub;
let scheduler;
const logoEndpoint = 'rest/api/logo/endpoint';
@@ -41,7 +46,18 @@ describe('CreateComColPageComponent', () => {
metadata: [{
key: 'dc.title',
value: 'test community'
}]
}],
_links: {}
});
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: {}
});
newCommunity = Object.assign(new Community(), {
@@ -49,7 +65,8 @@ describe('CreateComColPageComponent', () => {
metadata: [{
key: 'dc.title',
value: 'new community'
}]
}],
_links: {}
});
communityDataServiceStub = {
@@ -61,7 +78,9 @@ describe('CreateComColPageComponent', () => {
}]
})),
create: (com, uuid?) => createSuccessfulRemoteDataObject$(newCommunity),
getLogoEndpoint: () => observableOf(logoEndpoint)
getLogoEndpoint: () => observableOf(logoEndpoint),
findByHref: () => null,
refreshCache: () => {return}
};
routeServiceStub = {
@@ -71,6 +90,10 @@ describe('CreateComColPageComponent', () => {
navigate: (commands) => commands
};
requestServiceStub = jasmine.createSpyObj('RequestService', {
removeByHrefSubstring: jasmine.createSpy('removeByHrefSubstring'),
});
}
beforeEach(async(() => {
@@ -82,7 +105,8 @@ describe('CreateComColPageComponent', () => {
{ provide: CommunityDataService, useValue: communityDataServiceStub },
{ provide: RouteService, useValue: routeServiceStub },
{ provide: Router, useValue: routerStub },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: RequestService, useValue: requestServiceStub}
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
@@ -97,6 +121,7 @@ describe('CreateComColPageComponent', () => {
communityDataService = (comp as any).communityDataService;
routeService = (comp as any).routeService;
router = (comp as any).router;
scheduler = getTestScheduler();
});
describe('onSubmit', () => {
@@ -111,6 +136,7 @@ describe('CreateComColPageComponent', () => {
value: 'test'
}]
}),
_links: {},
uploader: {
options: {
url: ''
@@ -123,19 +149,23 @@ describe('CreateComColPageComponent', () => {
};
});
it('should navigate when successful', () => {
it('should navigate and refresh cache when successful', () => {
spyOn(router, 'navigate');
comp.onSubmit(data);
fixture.detectChanges();
spyOn((dsoDataService as any), 'refreshCache')
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(router.navigate).toHaveBeenCalled();
expect((dsoDataService as any).refreshCache).toHaveBeenCalled();
});
it('should not navigate on failure', () => {
it('should neither navigate nor refresh cache on failure', () => {
spyOn(router, 'navigate');
spyOn(dsoDataService, 'create').and.returnValue(createFailedRemoteDataObject$(newCommunity));
comp.onSubmit(data);
fixture.detectChanges();
spyOn(dsoDataService, 'refreshCache')
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(router.navigate).not.toHaveBeenCalled();
expect((dsoDataService as any).refreshCache).not.toHaveBeenCalled();
});
});
@@ -148,6 +178,7 @@ describe('CreateComColPageComponent', () => {
value: 'test'
}]
}),
_links: {},
uploader: {
options: {
url: ''
@@ -164,21 +195,21 @@ describe('CreateComColPageComponent', () => {
it('should not navigate', () => {
spyOn(router, 'navigate');
comp.onSubmit(data);
fixture.detectChanges();
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(router.navigate).not.toHaveBeenCalled();
});
it('should set the uploader\'s url to the logo\'s endpoint', () => {
comp.onSubmit(data);
fixture.detectChanges();
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(data.uploader.options.url).toEqual(logoEndpoint);
});
it('should call the uploader\'s uploadAll', () => {
spyOn(data.uploader, 'uploadAll');
comp.onSubmit(data);
fixture.detectChanges();
scheduler.schedule(() => comp.onSubmit(data));
scheduler.flush();
expect(data.uploader.uploadAll).toHaveBeenCalled();
});
});

View File

@@ -2,18 +2,21 @@ import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
import {flatMap, take} from 'rxjs/operators';
import { ComColDataService } from '../../../core/data/comcol-data.service';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { RemoteData } from '../../../core/data/remote-data';
import { RouteService } from '../../../core/services/route.service';
import { Community } from '../../../core/shared/community.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { getSucceededRemoteData } from '../../../core/shared/operators';
import {
getFirstSucceededRemoteDataPayload,
} from '../../../core/shared/operators';
import { ResourceType } from '../../../core/shared/resource-type';
import { hasValue, isNotEmpty, isNotUndefined } from '../../empty.util';
import {hasValue, isNotEmpty, isNotUndefined} from '../../empty.util';
import { NotificationsService } from '../../notifications/notifications.service';
import { RequestParam } from '../../../core/cache/models/request-param.model';
import {RequestService} from '../../../core/data/request.service';
/**
* Component representing the create page for communities and collections
@@ -54,7 +57,8 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject> implements
protected routeService: RouteService,
protected router: Router,
protected notificationsService: NotificationsService,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
}
@@ -76,25 +80,29 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject> implements
const dso = event.dso;
const uploader = event.uploader;
this.parentUUID$.pipe(take(1)).subscribe((uuid: string) => {
this.parentUUID$.pipe(
take(1),
flatMap((uuid: string) => {
const params = uuid ? [new RequestParam('parent', uuid)] : [];
this.dsoDataService.create(dso, ...params)
.pipe(getSucceededRemoteData())
.subscribe((dsoRD: RemoteData<TDomain>) => {
if (isNotUndefined(dsoRD)) {
this.newUUID = dsoRD.payload.uuid;
if (uploader.queue.length > 0) {
this.dsoDataService.getLogoEndpoint(this.newUUID).pipe(take(1)).subscribe((href: string) => {
uploader.options.url = href;
uploader.uploadAll();
});
} else {
this.navigateToNewPage();
}
this.notificationsService.success(null, this.translate.get(this.type.value + '.create.notifications.success'));
return this.dsoDataService.create(dso, ...params)
.pipe(getFirstSucceededRemoteDataPayload()
)
}))
.subscribe((dsoRD: TDomain) => {
if (isNotUndefined(dsoRD)) {
this.newUUID = dsoRD.uuid;
if (uploader.queue.length > 0) {
this.dsoDataService.getLogoEndpoint(this.newUUID).pipe(take(1)).subscribe((href: string) => {
uploader.options.url = href;
uploader.uploadAll();
});
} else {
this.navigateToNewPage();
}
});
});
this.dsoDataService.refreshCache(dsoRD);
}
this.notificationsService.success(null, this.translate.get(this.type.value + '.create.notifications.success'));
});
}
/**
@@ -105,5 +113,4 @@ export class CreateComColPageComponent<TDomain extends DSpaceObject> implements
this.router.navigate([this.frontendURL + this.newUUID]);
}
}
}

View File

@@ -1,7 +1,7 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import {TranslateModule, TranslateService} from '@ngx-translate/core';
import { of as observableOf } from 'rxjs';
import { Community } from '../../../core/shared/community.model';
import { SharedModule } from '../../shared.module';
@@ -13,6 +13,10 @@ import { DataService } from '../../../core/data/data.service';
import { DeleteComColPageComponent } from './delete-comcol-page.component';
import { NotificationsService } from '../../notifications/notifications.service';
import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
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>;
@@ -22,9 +26,15 @@ describe('DeleteComColPageComponent', () => {
let community;
let newCommunity;
let parentCommunity;
let routerStub;
let routeStub;
let notificationsService;
let translateServiceStub;
let requestServiceStub;
let scheduler;
const validUUID = 'valid-uuid';
const invalidUUID = 'invalid-uuid';
const frontendURL = '/testType';
@@ -45,10 +55,21 @@ describe('DeleteComColPageComponent', () => {
}]
});
parentCommunity = Object.assign(new Community(), {
uuid: 'a20da287-e174-466a-9926-f66as300d399',
id: 'a20da287-e174-466a-9926-f66as300d399',
metadata: [{
key: 'dc.title',
value: 'parent community'
}]
});
dsoDataService = jasmine.createSpyObj(
'dsoDataService',
{
delete: observableOf({ isSuccessful: true })
delete: observableOf({ isSuccessful: true }),
findByHref: jasmine.createSpy('findByHref'),
refreshCache: jasmine.createSpy('refreshCache')
});
routerStub = {
@@ -59,6 +80,14 @@ describe('DeleteComColPageComponent', () => {
data: observableOf(community)
};
requestServiceStub = jasmine.createSpyObj('RequestService', {
removeByHrefSubstring: jasmine.createSpy('removeByHrefSubstring')
});
translateServiceStub = jasmine.createSpyObj('TranslateService', {
instant: jasmine.createSpy('instant')
});
}
beforeEach(async(() => {
@@ -66,10 +95,12 @@ 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() },
{ provide: TranslateService, useValue: translateServiceStub},
{ provide: RequestService, useValue: requestServiceStub}
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
@@ -82,43 +113,63 @@ describe('DeleteComColPageComponent', () => {
notificationsService = (comp as any).notifications;
(comp as any).frontendURL = frontendURL;
router = (comp as any).router;
scheduler = getTestScheduler();
});
describe('onConfirm', () => {
let data1;
let data2;
beforeEach(() => {
data1 = Object.assign(new Community(), {
uuid: validUUID,
metadata: [{
key: 'dc.title',
value: 'test'
}]
});
data1 = {
dso: Object.assign(new Community(), {
uuid: validUUID,
metadata: [{
key: 'dc.title',
value: 'test'
}]
}),
_links: {}
};
data2 = Object.assign(new Community(), {
uuid: invalidUUID,
metadata: [{
key: 'dc.title',
value: 'test'
}]
});
data2 = {
dso: Object.assign(new Community(), {
uuid: invalidUUID,
metadata: [{
key: 'dc.title',
value: 'test'
}]
}),
_links: {},
uploader: {
options: {
url: ''
},
queue: [],
/* tslint:disable:no-empty */
uploadAll: () => {}
/* tslint:enable:no-empty */
}
};
});
it('should show an error notification on failure', () => {
(dsoDataService.delete as any).and.returnValue(observableOf({ isSuccessful: false }));
spyOn(router, 'navigate');
comp.onConfirm(data2);
scheduler.schedule(() => comp.onConfirm(data2));
scheduler.flush();
fixture.detectChanges();
expect(notificationsService.error).toHaveBeenCalled();
expect(dsoDataService.refreshCache).not.toHaveBeenCalled();
expect(router.navigate).toHaveBeenCalled();
});
it('should show a success notification on success and navigate', () => {
spyOn(router, 'navigate');
comp.onConfirm(data1);
scheduler.schedule(() => comp.onConfirm(data1));
scheduler.flush();
fixture.detectChanges();
expect(notificationsService.success).toHaveBeenCalled();
expect(dsoDataService.refreshCache).toHaveBeenCalled();
expect(router.navigate).toHaveBeenCalled();
});

View File

@@ -1,13 +1,14 @@
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { ActivatedRoute, Router } from '@angular/router';
import { RemoteData } from '../../../core/data/remote-data';
import { first, map } from 'rxjs/operators';
import { DataService } from '../../../core/data/data.service';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
import { NotificationsService } from '../../notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
import { RestResponse } from '../../../core/cache/response.models';
import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs';
import {ActivatedRoute, Router} from '@angular/router';
import {RemoteData} from '../../../core/data/remote-data';
import {first, map} from 'rxjs/operators';
import {DSpaceObject} from '../../../core/shared/dspace-object.model';
import {NotificationsService} from '../../notifications/notifications.service';
import {TranslateService} from '@ngx-translate/core';
import {RestResponse} from '../../../core/cache/response.models';
import {RequestService} from '../../../core/data/request.service';
import {ComColDataService} from '../../../core/data/comcol-data.service';
/**
* Component representing the delete page for communities and collections
@@ -27,11 +28,12 @@ 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,
protected translate: TranslateService
protected translate: TranslateService,
protected requestService: RequestService
) {
}
@@ -50,6 +52,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.dsoDataService.refreshCache(dso);
} else {
const errorMessage = this.translate.instant((dso as any).type + '.delete.notification.fail');
this.notifications.error(errorMessage)

View File

@@ -69,3 +69,24 @@ export function createPendingRemoteDataObject<T>(object?: T): RemoteData<T> {
export function createPendingRemoteDataObject$<T>(object?: T): Observable<RemoteData<T>> {
return observableOf(createPendingRemoteDataObject(object));
}
/**
* Method to create a remote data object with no content
*/
export function createNoContentRemoteDataObject<T>(): RemoteData<T> {
return new RemoteData(
true,
true,
true,
null,
null,
204
);
}
/**
* Method to create a remote data object that has succeeded with no content, wrapped in an observable
*/
export function createNoContentRemoteDataObject$<T>(): Observable<RemoteData<T>> {
return observableOf(createNoContentRemoteDataObject());
}