mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 07:23:03 +00:00
74179: Edit group functionality added + test (fixes)
This commit is contained in:
@@ -42,6 +42,7 @@ describe('GroupFormComponent', () => {
|
|||||||
let ePersonDataServiceStub: any;
|
let ePersonDataServiceStub: any;
|
||||||
let groupsDataServiceStub: any;
|
let groupsDataServiceStub: any;
|
||||||
let authorizationService: AuthorizationDataService;
|
let authorizationService: AuthorizationDataService;
|
||||||
|
let notificationService: NotificationsServiceStub;
|
||||||
let router;
|
let router;
|
||||||
|
|
||||||
let groups;
|
let groups;
|
||||||
@@ -76,6 +77,9 @@ describe('GroupFormComponent', () => {
|
|||||||
editGroup(group: Group) {
|
editGroup(group: Group) {
|
||||||
this.activeGroup = group
|
this.activeGroup = group
|
||||||
},
|
},
|
||||||
|
updateGroup(group: Group) {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
cancelEditGroup(): void {
|
cancelEditGroup(): void {
|
||||||
this.activeGroup = null;
|
this.activeGroup = null;
|
||||||
},
|
},
|
||||||
@@ -96,6 +100,7 @@ describe('GroupFormComponent', () => {
|
|||||||
builderService = getMockFormBuilderService();
|
builderService = getMockFormBuilderService();
|
||||||
translateService = getMockTranslateService();
|
translateService = getMockTranslateService();
|
||||||
router = new RouterMock();
|
router = new RouterMock();
|
||||||
|
notificationService = new NotificationsServiceStub();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
|
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
@@ -109,7 +114,7 @@ describe('GroupFormComponent', () => {
|
|||||||
providers: [GroupFormComponent,
|
providers: [GroupFormComponent,
|
||||||
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
|
{ provide: EPersonDataService, useValue: ePersonDataServiceStub },
|
||||||
{ provide: GroupDataService, useValue: groupsDataServiceStub },
|
{ provide: GroupDataService, useValue: groupsDataServiceStub },
|
||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
|
{ provide: NotificationsService, useValue: notificationService },
|
||||||
{ provide: FormBuilderService, useValue: builderService },
|
{ provide: FormBuilderService, useValue: builderService },
|
||||||
{ provide: DSOChangeAnalyzer, useValue: {} },
|
{ provide: DSOChangeAnalyzer, useValue: {} },
|
||||||
{ provide: HttpClient, useValue: {} },
|
{ provide: HttpClient, useValue: {} },
|
||||||
@@ -154,6 +159,34 @@ describe('GroupFormComponent', () => {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
describe('with active Group', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(groupsDataServiceStub, 'getActiveGroup').and.returnValue(observableOf(expected));
|
||||||
|
spyOn(groupsDataServiceStub, 'updateGroup').and.returnValue(observableOf(new RestResponse(true, 200, 'OK')));
|
||||||
|
component.groupName.value = 'newGroupName';
|
||||||
|
component.onSubmit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit the existing group using the correct new values', async(() => {
|
||||||
|
const expected2 = Object.assign(new Group(), {
|
||||||
|
name: 'newGroupName',
|
||||||
|
metadata: {
|
||||||
|
'dc.description': [
|
||||||
|
{
|
||||||
|
value: groupDescription
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(component.submitForm.emit).toHaveBeenCalledWith(expected2);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
it('should emit success notification', () => {
|
||||||
|
expect(notificationService.success).toHaveBeenCalled();
|
||||||
|
})
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -193,7 +193,7 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
|||||||
if (group === null) {
|
if (group === null) {
|
||||||
this.createNewGroup(values);
|
this.createNewGroup(values);
|
||||||
} else {
|
} else {
|
||||||
this.editGroup(group, values);
|
this.editGroup(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -246,14 +246,37 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO
|
* Edit existing Group based on given values from form and old Group
|
||||||
* @param group
|
* @param group Group to edit and old values contained within
|
||||||
* @param values
|
|
||||||
*/
|
*/
|
||||||
editGroup(group: Group, values) {
|
editGroup(group: Group) {
|
||||||
// TODO (backend)
|
const editedGroup = Object.assign(new Group(), {
|
||||||
console.log('TODO implement editGroup', values);
|
id: group.id,
|
||||||
this.notificationsService.error('TODO implement editGroup (not yet implemented in backend) ');
|
metadata: {
|
||||||
|
'dc.description': [
|
||||||
|
{
|
||||||
|
value: (hasValue(this.groupDescription.value) ? this.groupDescription.value : group.firstMetadataValue('dc.description'))
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
name: (hasValue(this.groupName.value) ? this.groupName.value : group.name),
|
||||||
|
_links: group._links,
|
||||||
|
});
|
||||||
|
const response = this.groupDataService.updateGroup(editedGroup);
|
||||||
|
response.pipe(take(1)).subscribe((restResponse: RestResponse) => {
|
||||||
|
console.log('resp', restResponse)
|
||||||
|
if (restResponse.isSuccessful) {
|
||||||
|
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.edited.success', { name: editedGroup.name }));
|
||||||
|
this.submitForm.emit(editedGroup);
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.notification.edited.failure', { name: editedGroup.name }));
|
||||||
|
this.cancelForm.emit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.groupName.value != null && this.groupName.value !== group.name) {
|
||||||
|
this.showNotificationIfNameInUse(editedGroup, 'edited');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2,6 +2,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { createSelector, select, Store } from '@ngrx/store';
|
import { createSelector, select, Store } from '@ngrx/store';
|
||||||
|
import { Operation } from 'fast-json-patch/lib/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { filter, map, take, tap } from 'rxjs/operators';
|
import { filter, map, take, tap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
@@ -21,12 +22,19 @@ import { DataService } from '../data/data.service';
|
|||||||
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
|
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
|
||||||
import { PaginatedList } from '../data/paginated-list';
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { CreateRequest, DeleteRequest, FindListOptions, FindListRequest, PostRequest } from '../data/request.models';
|
import {
|
||||||
|
CreateRequest,
|
||||||
|
DeleteRequest,
|
||||||
|
FindListOptions,
|
||||||
|
FindListRequest,
|
||||||
|
PatchRequest,
|
||||||
|
PostRequest
|
||||||
|
} from '../data/request.models';
|
||||||
|
|
||||||
import { RequestService } from '../data/request.service';
|
import { RequestService } from '../data/request.service';
|
||||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { getResponseFromEntry } from '../shared/operators';
|
import { getRemoteDataPayload, getResponseFromEntry, getSucceededRemoteData } from '../shared/operators';
|
||||||
import { EPerson } from './models/eperson.model';
|
import { EPerson } from './models/eperson.model';
|
||||||
import { Group } from './models/group.model';
|
import { Group } from './models/group.model';
|
||||||
import { dataService } from '../cache/builders/build-decorators';
|
import { dataService } from '../cache/builders/build-decorators';
|
||||||
@@ -135,26 +143,41 @@ export class GroupDataService extends DataService<Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or Update a group
|
* Add a new patch to the object cache
|
||||||
* If the group contains an id, it is assumed the eperson already exists and is updated instead
|
* The patch is derived from the differences between the given object and its version in the object cache
|
||||||
* @param group The group to create or update
|
* @param group The group with changes
|
||||||
*/
|
*/
|
||||||
public createOrUpdateGroup(group: Group): Observable<RemoteData<Group>> {
|
updateGroup(group: Group): Observable<RestResponse> {
|
||||||
const isUpdate = hasValue(group.id);
|
const requestId = this.requestService.generateRequestId();
|
||||||
if (isUpdate) {
|
const oldVersion$ = this.findByHref(group._links.self.href);
|
||||||
return this.updateGroup(group);
|
oldVersion$.pipe(
|
||||||
} else {
|
getSucceededRemoteData(),
|
||||||
return this.create(group, null);
|
getRemoteDataPayload(),
|
||||||
}
|
map((oldGroup: Group) => {
|
||||||
|
const operations = this.generateOperations(oldGroup, group);
|
||||||
|
const patchRequest = new PatchRequest(requestId, group._links.self.href, operations);
|
||||||
|
return this.requestService.configure(patchRequest);
|
||||||
|
}),
|
||||||
|
take(1)
|
||||||
|
).subscribe();
|
||||||
|
|
||||||
|
return this.fetchResponse(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* // TODO
|
* Metadata operations are generated by the difference between old and new Group
|
||||||
* @param {DSpaceObject} ePerson The given object
|
* Custom replace operation for the other group Name value
|
||||||
|
* @param oldGroup
|
||||||
|
* @param newGroup
|
||||||
*/
|
*/
|
||||||
updateGroup(group: Group): Observable<RemoteData<Group>> {
|
private generateOperations(oldGroup: Group, newGroup: Group): Operation[] {
|
||||||
// TODO
|
let operations = this.comparator.diff(oldGroup, newGroup).filter((operation: Operation) => operation.op === 'replace');
|
||||||
return null;
|
if (hasValue(oldGroup.name) && oldGroup.name !== newGroup.name) {
|
||||||
|
operations = [...operations, {
|
||||||
|
op: 'replace', path: '/name', value: newGroup.name
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -327,6 +327,12 @@
|
|||||||
|
|
||||||
"admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.",
|
"admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.",
|
||||||
|
|
||||||
|
"admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"",
|
||||||
|
|
||||||
|
"admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!",
|
||||||
|
|
||||||
|
"admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"",
|
||||||
|
|
||||||
"admin.access-control.groups.form.actions.delete": "Delete Group",
|
"admin.access-control.groups.form.actions.delete": "Delete Group",
|
||||||
|
|
||||||
"admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"",
|
"admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"",
|
||||||
|
Reference in New Issue
Block a user