69432: refactor patch to return response

This commit is contained in:
Kristof De Langhe
2020-03-12 17:59:12 +01:00
parent d9e6d25da0
commit 33e395a7f6
4 changed files with 56 additions and 23 deletions

View File

@@ -16,8 +16,10 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { FindListOptions } from './request.models'; import { FindListOptions, PatchRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service-stub';
const endpoint = 'https://rest.api/core'; const endpoint = 'https://rest.api/core';
@@ -53,8 +55,8 @@ class DummyChangeAnalyzer implements ChangeAnalyzer<Item> {
describe('DataService', () => { describe('DataService', () => {
let service: TestService; let service: TestService;
let options: FindListOptions; let options: FindListOptions;
const requestService = { generateRequestId: () => uuidv4() } as RequestService; const requestService = getMockRequestService();
const halService = {} as HALEndpointService; const halService = new HALEndpointServiceStub('url') as any;
const rdbService = {} as RemoteDataBuildService; const rdbService = {} as RemoteDataBuildService;
const notificationsService = {} as NotificationsService; const notificationsService = {} as NotificationsService;
const http = {} as HttpClient; const http = {} as HttpClient;
@@ -285,18 +287,23 @@ describe('DataService', () => {
}); });
describe('patch', () => { describe('patch', () => {
let operations; const dso = {
let selfLink; uuid: 'dso-uuid'
};
const operations = [
Object.assign({
op: 'move',
from: '/1',
path: '/5'
}) as Operation
];
beforeEach(() => { beforeEach(() => {
operations = [{ op: 'replace', path: '/metadata/dc.title', value: 'random string' } as Operation]; service.patch(dso, operations);
selfLink = 'https://rest.api/endpoint/1698f1d3-be98-4c51-9fd8-6bfedcbd59b7';
spyOn(objectCache, 'addPatch');
}); });
it('should call addPatch on the object cache with the right parameters', () => { it('should configure a PatchRequest', () => {
service.patch(selfLink, operations); expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PatchRequest));
expect(objectCache.addPatch).toHaveBeenCalledWith(selfLink, operations);
}); });
}); });

View File

@@ -44,7 +44,7 @@ import {
FindByIDRequest, FindByIDRequest,
FindListOptions, FindListOptions,
FindListRequest, FindListRequest,
GetRequest GetRequest, PatchRequest
} from './request.models'; } from './request.models';
import { RequestEntry } from './request.reducer'; import { RequestEntry } from './request.reducer';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
@@ -329,12 +329,28 @@ export abstract class DataService<T extends CacheableObject> {
} }
/** /**
* Add a new patch to the object cache to a specified object * Send a patch request for a specified object
* @param {string} href The selflink of the object that will be patched * @param {T} dso The object to send a patch request for
* @param {Operation[]} operations The patch operations to be performed * @param {Operation[]} operations The patch operations to be performed
*/ */
patch(href: string, operations: Operation[]) { patch(dso: T, operations: Operation[]): Observable<RestResponse> {
this.objectCache.addPatch(href, operations); const requestId = this.requestService.generateRequestId();
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, dso.uuid)));
hrefObs.pipe(
find((href: string) => hasValue(href)),
map((href: string) => {
const request = new PatchRequest(requestId, href, operations);
this.requestService.configure(request);
})
).subscribe();
return this.requestService.getByUUID(requestId).pipe(
find((request: RequestEntry) => request.completed),
map((request: RequestEntry) => request.response)
);
} }
/** /**

View File

@@ -8,6 +8,8 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FormBuilderService } from '../../shared/form/builder/form-builder.service'; import { FormBuilderService } from '../../shared/form/builder/form-builder.service';
import { ProfilePageSecurityFormComponent } from './profile-page-security-form.component'; import { ProfilePageSecurityFormComponent } from './profile-page-security-form.component';
import { of as observableOf } from 'rxjs';
import { RestResponse } from '../../core/cache/response.models';
describe('ProfilePageSecurityFormComponent', () => { describe('ProfilePageSecurityFormComponent', () => {
let component: ProfilePageSecurityFormComponent; let component: ProfilePageSecurityFormComponent;
@@ -20,7 +22,7 @@ describe('ProfilePageSecurityFormComponent', () => {
}); });
const epersonService = jasmine.createSpyObj('epersonService', { const epersonService = jasmine.createSpyObj('epersonService', {
patch: {} patch: observableOf(new RestResponse(true, 200, 'OK'))
}); });
const notificationsService = jasmine.createSpyObj('notificationsService', { const notificationsService = jasmine.createSpyObj('notificationsService', {
success: {}, success: {},
@@ -94,7 +96,7 @@ describe('ProfilePageSecurityFormComponent', () => {
}); });
it('should return call epersonService.patch', () => { it('should return call epersonService.patch', () => {
expect(epersonService.patch).toHaveBeenCalledWith(user.self, operations); expect(epersonService.patch).toHaveBeenCalledWith(user, operations);
}); });
}); });
}); });

View File

@@ -116,11 +116,19 @@ export class ProfilePageSecurityFormComponent implements OnInit {
} }
if (passEntered) { if (passEntered) {
const operation = Object.assign({ op: 'replace', path: '/password', value: pass }); const operation = Object.assign({ op: 'replace', path: '/password', value: pass });
this.epersonService.patch(this.user.self, [operation]); this.epersonService.patch(this.user, [operation]).subscribe((response: RestResponse) => {
if (response.isSuccessful) {
this.notificationsService.success( this.notificationsService.success(
this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.title'), this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.title'),
this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.content') this.translate.instant(this.NOTIFICATIONS_PREFIX + 'success.content')
); );
} else {
this.notificationsService.error(
this.translate.instant(this.NOTIFICATIONS_PREFIX + 'error.title'), (response as ErrorResponse).errorMessage
);
}
});
} }
return passEntered; return passEntered;