mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 11:33:04 +00:00
85262: Allow empty patch requests
This commit is contained in:
@@ -40,13 +40,15 @@ export abstract class JsonPatchOperationsService<ResponseDefinitionDomain, Patch
|
|||||||
* The resource type value
|
* The resource type value
|
||||||
* @param resourceId
|
* @param resourceId
|
||||||
* The resource id value
|
* The resource id value
|
||||||
|
* @param allowEmptyRequest
|
||||||
|
* Allow an empty list of operations in the request's body
|
||||||
* @return Observable<ResponseDefinitionDomain>
|
* @return Observable<ResponseDefinitionDomain>
|
||||||
* observable of response
|
* observable of response
|
||||||
*/
|
*/
|
||||||
protected submitJsonPatchOperations(hrefObs: Observable<string>, resourceType: string, resourceId?: string): Observable<ResponseDefinitionDomain> {
|
protected submitJsonPatchOperations(hrefObs: Observable<string>, resourceType: string, resourceId?: string, allowEmptyRequest = false): Observable<ResponseDefinitionDomain> {
|
||||||
const requestId = this.requestService.generateRequestId();
|
const requestId = this.requestService.generateRequestId();
|
||||||
let startTransactionTime = null;
|
let startTransactionTime = null;
|
||||||
const [patchRequest$, emptyRequest$] = partition((request: PatchRequestDefinition) => isNotEmpty(request.body))(hrefObs.pipe(
|
const [patchRequest$, emptyRequest$] = partition((request: PatchRequestDefinition) => allowEmptyRequest || isNotEmpty(request.body))(hrefObs.pipe(
|
||||||
mergeMap((endpointURL: string) => {
|
mergeMap((endpointURL: string) => {
|
||||||
return this.store.select(jsonPatchOperationsByResourceType(resourceType)).pipe(
|
return this.store.select(jsonPatchOperationsByResourceType(resourceType)).pipe(
|
||||||
take(1),
|
take(1),
|
||||||
@@ -79,11 +81,11 @@ export abstract class JsonPatchOperationsService<ResponseDefinitionDomain, Patch
|
|||||||
|
|
||||||
return observableMerge(
|
return observableMerge(
|
||||||
emptyRequest$.pipe(
|
emptyRequest$.pipe(
|
||||||
filter((request: PatchRequestDefinition) => isEmpty(request.body)),
|
filter((request: PatchRequestDefinition) => !allowEmptyRequest && isEmpty(request.body)),
|
||||||
tap(() => startTransactionTime = null),
|
tap(() => startTransactionTime = null),
|
||||||
map(() => null)),
|
map(() => null)),
|
||||||
patchRequest$.pipe(
|
patchRequest$.pipe(
|
||||||
filter((request: PatchRequestDefinition) => isNotEmpty(request.body)),
|
filter((request: PatchRequestDefinition) => allowEmptyRequest || isNotEmpty(request.body)),
|
||||||
tap(() => this.store.dispatch(new StartTransactionPatchOperationsAction(resourceType, resourceId, startTransactionTime))),
|
tap(() => this.store.dispatch(new StartTransactionPatchOperationsAction(resourceType, resourceId, startTransactionTime))),
|
||||||
tap((request: PatchRequestDefinition) => this.requestService.send(request)),
|
tap((request: PatchRequestDefinition) => this.requestService.send(request)),
|
||||||
mergeMap(() => {
|
mergeMap(() => {
|
||||||
@@ -141,16 +143,18 @@ export abstract class JsonPatchOperationsService<ResponseDefinitionDomain, Patch
|
|||||||
* The scope id
|
* The scope id
|
||||||
* @param resourceType
|
* @param resourceType
|
||||||
* The resource type value
|
* The resource type value
|
||||||
|
* @param allowEmptyRequest
|
||||||
|
* Allow an empty list of operations in the request's body
|
||||||
* @return Observable<ResponseDefinitionDomain>
|
* @return Observable<ResponseDefinitionDomain>
|
||||||
* observable of response
|
* observable of response
|
||||||
*/
|
*/
|
||||||
public jsonPatchByResourceType(linkPath: string, scopeId: string, resourceType: string): Observable<ResponseDefinitionDomain> {
|
public jsonPatchByResourceType(linkPath: string, scopeId: string, resourceType: string, allowEmptyRequest = false): Observable<ResponseDefinitionDomain> {
|
||||||
const href$ = this.halService.getEndpoint(linkPath).pipe(
|
const href$ = this.halService.getEndpoint(linkPath).pipe(
|
||||||
filter((href: string) => isNotEmpty(href)),
|
filter((href: string) => isNotEmpty(href)),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)));
|
map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)));
|
||||||
|
|
||||||
return this.submitJsonPatchOperations(href$, resourceType);
|
return this.submitJsonPatchOperations(href$, resourceType, undefined, allowEmptyRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -201,6 +201,15 @@ describe('SubmissionFormFooterComponent Component', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not have deposit button disabled when submission is not valid', () => {
|
||||||
|
comp.showDepositAndDiscard = observableOf(true);
|
||||||
|
compAsAny.submissionIsInvalid = observableOf(true);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const depositBtn: any = fixture.debugElement.query(By.css('.btn-success'));
|
||||||
|
|
||||||
|
expect(depositBtn.nativeElement.disabled).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
it('should not have deposit button disabled when submission is valid', () => {
|
it('should not have deposit button disabled when submission is valid', () => {
|
||||||
comp.showDepositAndDiscard = observableOf(true);
|
comp.showDepositAndDiscard = observableOf(true);
|
||||||
compAsAny.submissionIsInvalid = observableOf(false);
|
compAsAny.submissionIsInvalid = observableOf(false);
|
||||||
|
@@ -879,6 +879,36 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return a SAVE_SUBMISSION_FORM_SUCCESS action when there are errors', () => {
|
||||||
|
store.nextState({
|
||||||
|
submission: {
|
||||||
|
objects: submissionState
|
||||||
|
}
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
actions = hot('--a-', {
|
||||||
|
a: {
|
||||||
|
type: SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION,
|
||||||
|
payload: {
|
||||||
|
submissionId: submissionId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = [Object.assign({}, mockSubmissionRestResponse[0], {
|
||||||
|
sections: mockSectionsData,
|
||||||
|
errors: mockSectionsErrors
|
||||||
|
})];
|
||||||
|
|
||||||
|
submissionJsonPatchOperationsServiceStub.jsonPatchByResourceType.and.returnValue(observableOf(response));
|
||||||
|
|
||||||
|
const expected = cold('--b-', {
|
||||||
|
b: new SaveSubmissionFormSuccessAction(submissionId, response as any[])
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
|
||||||
it('should catch errors and return a SAVE_SUBMISSION_FORM_ERROR', () => {
|
it('should catch errors and return a SAVE_SUBMISSION_FORM_ERROR', () => {
|
||||||
actions = hot('--a-', {
|
actions = hot('--a-', {
|
||||||
a: {
|
a: {
|
||||||
|
@@ -201,7 +201,8 @@ export class SubmissionObjectEffects {
|
|||||||
return this.operationsService.jsonPatchByResourceType(
|
return this.operationsService.jsonPatchByResourceType(
|
||||||
this.submissionService.getSubmissionObjectLinkName(),
|
this.submissionService.getSubmissionObjectLinkName(),
|
||||||
action.payload.submissionId,
|
action.payload.submissionId,
|
||||||
'sections').pipe(
|
'sections',
|
||||||
|
true).pipe(
|
||||||
map((response: SubmissionObject[]) => {
|
map((response: SubmissionObject[]) => {
|
||||||
if (this.canDeposit(response)) {
|
if (this.canDeposit(response)) {
|
||||||
return new DepositSubmissionAction(action.payload.submissionId);
|
return new DepositSubmissionAction(action.payload.submissionId);
|
||||||
|
Reference in New Issue
Block a user