mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge remote-tracking branch 'origin/main' into CST-4633-search-refactoring
This commit is contained in:
@@ -63,7 +63,7 @@ export class BrowseByDatePageComponent extends BrowseByMetadataPageComponent {
|
|||||||
this.browseId = params.id || this.defaultBrowseId;
|
this.browseId = params.id || this.defaultBrowseId;
|
||||||
this.startsWith = +params.startsWith || params.startsWith;
|
this.startsWith = +params.startsWith || params.startsWith;
|
||||||
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
|
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
|
||||||
this.updatePageWithItems(searchOptions, this.value);
|
this.updatePageWithItems(searchOptions, this.value, undefined);
|
||||||
this.updateParent(params.scope);
|
this.updateParent(params.scope);
|
||||||
this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
|
this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
|
||||||
}));
|
}));
|
||||||
|
@@ -99,6 +99,11 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
value = '';
|
value = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authority key (may be undefined) associated with {@link #value}.
|
||||||
|
*/
|
||||||
|
authority: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current startsWith option (fetched and updated from query-params)
|
* The current startsWith option (fetched and updated from query-params)
|
||||||
*/
|
*/
|
||||||
@@ -123,11 +128,12 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||||
this.browseId = params.id || this.defaultBrowseId;
|
this.browseId = params.id || this.defaultBrowseId;
|
||||||
|
this.authority = params.authority;
|
||||||
this.value = +params.value || params.value || '';
|
this.value = +params.value || params.value || '';
|
||||||
this.startsWith = +params.startsWith || params.startsWith;
|
this.startsWith = +params.startsWith || params.startsWith;
|
||||||
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
|
const searchOptions = browseParamsToOptions(params, currentPage, currentSort, this.browseId);
|
||||||
if (isNotEmpty(this.value)) {
|
if (isNotEmpty(this.value)) {
|
||||||
this.updatePageWithItems(searchOptions, this.value);
|
this.updatePageWithItems(searchOptions, this.value, this.authority);
|
||||||
} else {
|
} else {
|
||||||
this.updatePage(searchOptions);
|
this.updatePage(searchOptions);
|
||||||
}
|
}
|
||||||
@@ -166,8 +172,8 @@ export class BrowseByMetadataPageComponent implements OnInit {
|
|||||||
* scope: string }
|
* scope: string }
|
||||||
* @param value The value of the browse-entry to display items for
|
* @param value The value of the browse-entry to display items for
|
||||||
*/
|
*/
|
||||||
updatePageWithItems(searchOptions: BrowseEntrySearchOptions, value: string) {
|
updatePageWithItems(searchOptions: BrowseEntrySearchOptions, value: string, authority: string) {
|
||||||
this.items$ = this.browseService.getBrowseItemsFor(value, searchOptions);
|
this.items$ = this.browseService.getBrowseItemsFor(value, authority, searchOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -46,7 +46,7 @@ export class BrowseByTitlePageComponent extends BrowseByMetadataPageComponent {
|
|||||||
})
|
})
|
||||||
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
).subscribe(([params, currentPage, currentSort]: [Params, PaginationComponentOptions, SortOptions]) => {
|
||||||
this.browseId = params.id || this.defaultBrowseId;
|
this.browseId = params.id || this.defaultBrowseId;
|
||||||
this.updatePageWithItems(browseParamsToOptions(params, currentPage, currentSort, this.browseId), undefined);
|
this.updatePageWithItems(browseParamsToOptions(params, currentPage, currentSort, this.browseId), undefined, undefined);
|
||||||
this.updateParent(params.scope);
|
this.updateParent(params.scope);
|
||||||
}));
|
}));
|
||||||
this.updateStartsWithTextOptions();
|
this.updateStartsWithTextOptions();
|
||||||
|
@@ -129,6 +129,7 @@ describe('BrowseService', () => {
|
|||||||
describe('getBrowseEntriesFor and findList', () => {
|
describe('getBrowseEntriesFor and findList', () => {
|
||||||
// should contain special characters such that url encoding can be tested as well
|
// should contain special characters such that url encoding can be tested as well
|
||||||
const mockAuthorName = 'Donald Smith & Sons';
|
const mockAuthorName = 'Donald Smith & Sons';
|
||||||
|
const mockAuthorityKey = 'some authority key ?=;';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
requestService = getMockRequestService(getRequestEntry$(true));
|
requestService = getMockRequestService(getRequestEntry$(true));
|
||||||
@@ -155,7 +156,7 @@ describe('BrowseService', () => {
|
|||||||
it('should call hrefOnlyDataService.findAllByHref with the expected href', () => {
|
it('should call hrefOnlyDataService.findAllByHref with the expected href', () => {
|
||||||
const expected = browseDefinitions[1]._links.items.href + '?filterValue=' + encodeURIComponent(mockAuthorName);
|
const expected = browseDefinitions[1]._links.items.href + '?filterValue=' + encodeURIComponent(mockAuthorName);
|
||||||
|
|
||||||
scheduler.schedule(() => service.getBrowseItemsFor(mockAuthorName, new BrowseEntrySearchOptions(browseDefinitions[1].id)).subscribe());
|
scheduler.schedule(() => service.getBrowseItemsFor(mockAuthorName, undefined, new BrowseEntrySearchOptions(browseDefinitions[1].id)).subscribe());
|
||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
|
|
||||||
expect(getFirstUsedArgumentOfSpyMethod(hrefOnlyDataService.findAllByHref)).toBeObservable(cold('(a|)', {
|
expect(getFirstUsedArgumentOfSpyMethod(hrefOnlyDataService.findAllByHref)).toBeObservable(cold('(a|)', {
|
||||||
@@ -164,6 +165,20 @@ describe('BrowseService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
describe('when getBrowseItemsFor is called with a valid filter value and authority key', () => {
|
||||||
|
it('should call hrefOnlyDataService.findAllByHref with the expected href', () => {
|
||||||
|
const expected = browseDefinitions[1]._links.items.href +
|
||||||
|
'?filterValue=' + encodeURIComponent(mockAuthorName) +
|
||||||
|
'&filterAuthority=' + encodeURIComponent(mockAuthorityKey);
|
||||||
|
|
||||||
|
scheduler.schedule(() => service.getBrowseItemsFor(mockAuthorName, mockAuthorityKey, new BrowseEntrySearchOptions(browseDefinitions[1].id)).subscribe());
|
||||||
|
scheduler.flush();
|
||||||
|
|
||||||
|
expect(getFirstUsedArgumentOfSpyMethod(hrefOnlyDataService.findAllByHref)).toBeObservable(cold('(a|)', {
|
||||||
|
a: expected
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getBrowseURLFor', () => {
|
describe('getBrowseURLFor', () => {
|
||||||
|
@@ -105,7 +105,7 @@ export class BrowseService {
|
|||||||
* @param options Options to narrow down your search
|
* @param options Options to narrow down your search
|
||||||
* @returns {Observable<RemoteData<PaginatedList<Item>>>}
|
* @returns {Observable<RemoteData<PaginatedList<Item>>>}
|
||||||
*/
|
*/
|
||||||
getBrowseItemsFor(filterValue: string, options: BrowseEntrySearchOptions): Observable<RemoteData<PaginatedList<Item>>> {
|
getBrowseItemsFor(filterValue: string, filterAuthority: string, options: BrowseEntrySearchOptions): Observable<RemoteData<PaginatedList<Item>>> {
|
||||||
const href$ = this.getBrowseDefinitions().pipe(
|
const href$ = this.getBrowseDefinitions().pipe(
|
||||||
getBrowseDefinitionLinks(options.metadataDefinition),
|
getBrowseDefinitionLinks(options.metadataDefinition),
|
||||||
hasValueOperator(),
|
hasValueOperator(),
|
||||||
@@ -132,6 +132,9 @@ export class BrowseService {
|
|||||||
if (isNotEmpty(filterValue)) {
|
if (isNotEmpty(filterValue)) {
|
||||||
args.push(`filterValue=${encodeURIComponent(filterValue)}`);
|
args.push(`filterValue=${encodeURIComponent(filterValue)}`);
|
||||||
}
|
}
|
||||||
|
if (isNotEmpty(filterAuthority)) {
|
||||||
|
args.push(`filterAuthority=${encodeURIComponent(filterAuthority)}`);
|
||||||
|
}
|
||||||
if (isNotEmpty(args)) {
|
if (isNotEmpty(args)) {
|
||||||
href = new URLCombiner(href, `?${args.join('&')}`).toString();
|
href = new URLCombiner(href, `?${args.join('&')}`).toString();
|
||||||
}
|
}
|
||||||
|
@@ -87,4 +87,15 @@ describe('ProcessFormComponent', () => {
|
|||||||
component.submitForm({ controls: {} } as any);
|
component.submitForm({ controls: {} } as any);
|
||||||
expect(scriptService.invoke).toHaveBeenCalled();
|
expect(scriptService.invoke).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when undefined parameters are provided', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
component.parameters = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invoke the script with an empty array of parameters', () => {
|
||||||
|
component.submitForm({ controls: {} } as any);
|
||||||
|
expect(scriptService.invoke).toHaveBeenCalledWith(script.id, [], jasmine.anything());
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -12,6 +12,7 @@ import { Router } from '@angular/router';
|
|||||||
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
import { getProcessListRoute } from '../process-page-routing.paths';
|
import { getProcessListRoute } from '../process-page-routing.paths';
|
||||||
|
import { isEmpty } from '../../shared/empty.util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to create a new script
|
* Component to create a new script
|
||||||
@@ -35,7 +36,7 @@ export class ProcessFormComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* The parameter values to use to start the process
|
* The parameter values to use to start the process
|
||||||
*/
|
*/
|
||||||
@Input() public parameters: ProcessParameter[];
|
@Input() public parameters: ProcessParameter[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional files that are used as parameter values
|
* Optional files that are used as parameter values
|
||||||
@@ -69,6 +70,9 @@ export class ProcessFormComponent implements OnInit {
|
|||||||
* @param form
|
* @param form
|
||||||
*/
|
*/
|
||||||
submitForm(form: NgForm) {
|
submitForm(form: NgForm) {
|
||||||
|
if (isEmpty(this.parameters)) {
|
||||||
|
this.parameters = [];
|
||||||
|
}
|
||||||
if (!this.validateForm(form) || this.isRequiredMissing()) {
|
if (!this.validateForm(form) || this.isRequiredMissing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="" [queryParams]="{value: object.value, startsWith: undefined}" [queryParamsHandling]="'merge'" class="lead">
|
<a *ngIf="linkType != linkTypes.None" [target]="(linkType == linkTypes.ExternalLink) ? '_blank' : '_self'" rel="noopener noreferrer" [routerLink]="" [queryParams]="getQueryParams()" [queryParamsHandling]="'merge'" class="lead">
|
||||||
{{object.value}}
|
{{object.value}}
|
||||||
</a>
|
</a>
|
||||||
<span *ngIf="linkType == linkTypes.None" class="lead">
|
<span *ngIf="linkType == linkTypes.None" class="lead">
|
||||||
|
@@ -15,4 +15,16 @@ import { listableObjectComponent } from '../../object-collection/shared/listable
|
|||||||
* This component is automatically used to create a list view for BrowseEntry objects when used in ObjectCollectionComponent
|
* This component is automatically used to create a list view for BrowseEntry objects when used in ObjectCollectionComponent
|
||||||
*/
|
*/
|
||||||
@listableObjectComponent(BrowseEntry, ViewMode.ListElement)
|
@listableObjectComponent(BrowseEntry, ViewMode.ListElement)
|
||||||
export class BrowseEntryListElementComponent extends AbstractListableElementComponent<BrowseEntry> {}
|
export class BrowseEntryListElementComponent extends AbstractListableElementComponent<BrowseEntry> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query params to access the item page of this browse entry.
|
||||||
|
*/
|
||||||
|
public getQueryParams(): {[param: string]: any} {
|
||||||
|
return {
|
||||||
|
value: this.object.value,
|
||||||
|
authority: !!this.object.authority ? this.object.authority : undefined,
|
||||||
|
startsWith: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -24,6 +24,12 @@ export class FacetValue implements HALResource {
|
|||||||
@autoserialize
|
@autoserialize
|
||||||
count: number;
|
count: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Authority Value for this facet
|
||||||
|
*/
|
||||||
|
@autoserialize
|
||||||
|
authorityKey?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link HALLink}s for this FacetValue
|
* The {@link HALLink}s for this FacetValue
|
||||||
*/
|
*/
|
||||||
|
@@ -12,6 +12,7 @@ describe('Search Utils', () => {
|
|||||||
let facetValueWithSearchHref: FacetValue;
|
let facetValueWithSearchHref: FacetValue;
|
||||||
let facetValueWithoutSearchHref: FacetValue;
|
let facetValueWithoutSearchHref: FacetValue;
|
||||||
let searchFilterConfig: SearchFilterConfig;
|
let searchFilterConfig: SearchFilterConfig;
|
||||||
|
let facetValueWithSearchHrefAuthority: FacetValue;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
facetValueWithSearchHref = Object.assign(new FacetValue(), {
|
facetValueWithSearchHref = Object.assign(new FacetValue(), {
|
||||||
@@ -22,6 +23,11 @@ describe('Search Utils', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
facetValueWithSearchHrefAuthority = Object.assign(new FacetValue(), {
|
||||||
|
value: 'Value with search href',
|
||||||
|
authorityKey: 'uuid',
|
||||||
|
}
|
||||||
|
);
|
||||||
facetValueWithoutSearchHref = Object.assign(new FacetValue(), {
|
facetValueWithoutSearchHref = Object.assign(new FacetValue(), {
|
||||||
value: 'Value without search href'
|
value: 'Value without search href'
|
||||||
});
|
});
|
||||||
@@ -34,6 +40,10 @@ describe('Search Utils', () => {
|
|||||||
expect(getFacetValueForType(facetValueWithSearchHref, searchFilterConfig)).toEqual('Value with search href,operator');
|
expect(getFacetValueForType(facetValueWithSearchHref, searchFilterConfig)).toEqual('Value with search href,operator');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should retrieve the correct value from the Facet', () => {
|
||||||
|
expect(getFacetValueForType(facetValueWithSearchHrefAuthority, searchFilterConfig)).toEqual('uuid,authority');
|
||||||
|
});
|
||||||
|
|
||||||
it('should return the facet value with an equals operator by default', () => {
|
it('should return the facet value with an equals operator by default', () => {
|
||||||
expect(getFacetValueForType(facetValueWithoutSearchHref, searchFilterConfig)).toEqual('Value without search href,equals');
|
expect(getFacetValueForType(facetValueWithoutSearchHref, searchFilterConfig)).toEqual('Value without search href,equals');
|
||||||
});
|
});
|
||||||
|
@@ -16,6 +16,10 @@ export function getFacetValueForType(facetValue: FacetValue, searchFilterConfig:
|
|||||||
return values[1];
|
return values[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (facetValue.authorityKey) {
|
||||||
|
return addOperatorToFilterValue(facetValue.authorityKey, 'authority');
|
||||||
|
}
|
||||||
|
|
||||||
return addOperatorToFilterValue(facetValue.value, 'equals');
|
return addOperatorToFilterValue(facetValue.value, 'equals');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
<button *ngIf="(showDepositAndDiscard | async)"
|
<button *ngIf="(showDepositAndDiscard | async)"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-success"
|
class="btn btn-success"
|
||||||
[disabled]="(submissionIsInvalid | async) || (processingSaveStatus | async) || (processingDepositStatus | async)"
|
[disabled]="(processingSaveStatus | async) || (processingDepositStatus | async)"
|
||||||
(click)="deposit($event)">
|
(click)="deposit($event)">
|
||||||
<span><i class="fas fa-plus"></i> {{'submission.general.deposit' | translate}}</span>
|
<span><i class="fas fa-plus"></i> {{'submission.general.deposit' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@@ -201,13 +201,13 @@ describe('SubmissionFormFooterComponent Component', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have deposit button disabled when submission is not valid', () => {
|
it('should not have deposit button disabled when submission is not valid', () => {
|
||||||
comp.showDepositAndDiscard = observableOf(true);
|
comp.showDepositAndDiscard = observableOf(true);
|
||||||
compAsAny.submissionIsInvalid = observableOf(true);
|
compAsAny.submissionIsInvalid = observableOf(true);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const depositBtn: any = fixture.debugElement.query(By.css('.btn-success'));
|
const depositBtn: any = fixture.debugElement.query(By.css('.btn-success'));
|
||||||
|
|
||||||
expect(depositBtn.nativeElement.disabled).toBeTruthy();
|
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', () => {
|
||||||
|
@@ -54,6 +54,8 @@ import { Item } from '../../core/shared/item.model';
|
|||||||
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
|
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
|
||||||
import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service';
|
import { WorkflowItemDataService } from '../../core/submission/workflowitem-data.service';
|
||||||
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
|
import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
|
||||||
|
import { SubmissionObjectDataService } from '../../core/submission/submission-object-data.service';
|
||||||
|
import { mockSubmissionObjectDataService } from '../../shared/testing/submission-oject-data-service.mock';
|
||||||
|
|
||||||
describe('SubmissionObjectEffects test suite', () => {
|
describe('SubmissionObjectEffects test suite', () => {
|
||||||
let submissionObjectEffects: SubmissionObjectEffects;
|
let submissionObjectEffects: SubmissionObjectEffects;
|
||||||
@@ -63,6 +65,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
let notificationsServiceStub;
|
let notificationsServiceStub;
|
||||||
let submissionServiceStub;
|
let submissionServiceStub;
|
||||||
let submissionJsonPatchOperationsServiceStub;
|
let submissionJsonPatchOperationsServiceStub;
|
||||||
|
let submissionObjectDataServiceStub;
|
||||||
const collectionId: string = mockSubmissionCollectionId;
|
const collectionId: string = mockSubmissionCollectionId;
|
||||||
const submissionId: string = mockSubmissionId;
|
const submissionId: string = mockSubmissionId;
|
||||||
const submissionDefinitionResponse: any = mockSubmissionDefinitionResponse;
|
const submissionDefinitionResponse: any = mockSubmissionDefinitionResponse;
|
||||||
@@ -75,6 +78,9 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
notificationsServiceStub = new NotificationsServiceStub();
|
notificationsServiceStub = new NotificationsServiceStub();
|
||||||
submissionServiceStub = new SubmissionServiceStub();
|
submissionServiceStub = new SubmissionServiceStub();
|
||||||
submissionJsonPatchOperationsServiceStub = new SubmissionJsonPatchOperationsServiceStub();
|
submissionJsonPatchOperationsServiceStub = new SubmissionJsonPatchOperationsServiceStub();
|
||||||
|
submissionObjectDataServiceStub = mockSubmissionObjectDataService;
|
||||||
|
|
||||||
|
submissionServiceStub.hasUnsavedModification.and.returnValue(observableOf(true));
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -99,6 +105,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
{ provide: WorkflowItemDataService, useValue: {} },
|
{ provide: WorkflowItemDataService, useValue: {} },
|
||||||
{ provide: WorkflowItemDataService, useValue: {} },
|
{ provide: WorkflowItemDataService, useValue: {} },
|
||||||
{ provide: HALEndpointService, useValue: {} },
|
{ provide: HALEndpointService, useValue: {} },
|
||||||
|
{ provide: SubmissionObjectDataService, useValue: submissionObjectDataServiceStub },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -879,7 +886,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow to deposit when there are errors', () => {
|
it('should return a SAVE_SUBMISSION_FORM_SUCCESS action when there are errors', () => {
|
||||||
store.nextState({
|
store.nextState({
|
||||||
submission: {
|
submission: {
|
||||||
objects: submissionState
|
objects: submissionState
|
||||||
@@ -902,31 +909,8 @@ describe('SubmissionObjectEffects test suite', () => {
|
|||||||
|
|
||||||
submissionJsonPatchOperationsServiceStub.jsonPatchByResourceType.and.returnValue(observableOf(response));
|
submissionJsonPatchOperationsServiceStub.jsonPatchByResourceType.and.returnValue(observableOf(response));
|
||||||
|
|
||||||
const errorsList = parseSectionErrors(mockSectionsErrors);
|
|
||||||
const expected = cold('--b-', {
|
const expected = cold('--b-', {
|
||||||
b: [
|
b: new SaveSubmissionFormSuccessAction(submissionId, response as any[])
|
||||||
new UpdateSectionDataAction(
|
|
||||||
submissionId,
|
|
||||||
'traditionalpageone',
|
|
||||||
mockSectionsData.traditionalpageone as any,
|
|
||||||
errorsList.traditionalpageone || [],
|
|
||||||
errorsList.traditionalpageone || []
|
|
||||||
),
|
|
||||||
new UpdateSectionDataAction(
|
|
||||||
submissionId,
|
|
||||||
'license',
|
|
||||||
mockSectionsData.license as any,
|
|
||||||
errorsList.license || [],
|
|
||||||
errorsList.license || []
|
|
||||||
),
|
|
||||||
new UpdateSectionDataAction(
|
|
||||||
submissionId,
|
|
||||||
'upload',
|
|
||||||
mockSectionsData.upload as any,
|
|
||||||
errorsList.upload || [],
|
|
||||||
errorsList.upload || []
|
|
||||||
)
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
expect(submissionObjectEffects.saveAndDeposit$).toBeObservable(expected);
|
||||||
|
@@ -196,19 +196,26 @@ export class SubmissionObjectEffects {
|
|||||||
*/
|
*/
|
||||||
@Effect() saveAndDeposit$ = this.actions$.pipe(
|
@Effect() saveAndDeposit$ = this.actions$.pipe(
|
||||||
ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
|
ofType(SubmissionObjectActionTypes.SAVE_AND_DEPOSIT_SUBMISSION),
|
||||||
withLatestFrom(this.store$),
|
withLatestFrom(this.submissionService.hasUnsavedModification()),
|
||||||
switchMap(([action, currentState]: [SaveAndDepositSubmissionAction, any]) => {
|
switchMap(([action, hasUnsavedModification]: [SaveAndDepositSubmissionAction, boolean]) => {
|
||||||
return this.operationsService.jsonPatchByResourceType(
|
let response$: Observable<SubmissionObject[]>;
|
||||||
this.submissionService.getSubmissionObjectLinkName(),
|
if (hasUnsavedModification) {
|
||||||
action.payload.submissionId,
|
response$ = this.operationsService.jsonPatchByResourceType(
|
||||||
'sections').pipe(
|
this.submissionService.getSubmissionObjectLinkName(),
|
||||||
|
action.payload.submissionId,
|
||||||
|
'sections') as Observable<SubmissionObject[]>;
|
||||||
|
} else {
|
||||||
|
response$ = this.submissionObjectService.findById(action.payload.submissionId).pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
|
map((submissionObject: SubmissionObject) => [submissionObject])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return response$.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);
|
||||||
} else {
|
} else {
|
||||||
this.notificationsService.warning(null, this.translate.get('submission.sections.general.sections_not_valid'));
|
return new SaveSubmissionFormSuccessAction(action.payload.submissionId, response);
|
||||||
return this.parseSaveResponse((currentState.submission as SubmissionState).objects[action.payload.submissionId],
|
|
||||||
response, action.payload.submissionId, currentState.forms);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
catchError(() => observableOf(new SaveSubmissionFormErrorAction(action.payload.submissionId))));
|
||||||
|
Reference in New Issue
Block a user