mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
Added tests
This commit is contained in:
@@ -6,16 +6,30 @@ import { AuthStatus } from './models/auth-status.model';
|
||||
import { AuthResponseParsingService } from './auth-response-parsing.service';
|
||||
import { AuthGetRequest, AuthPostRequest } from '../data/request.models';
|
||||
import { MockStore } from '../../shared/testing/mock-store';
|
||||
import { ObjectCacheState } from '../cache/object-cache.reducer';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
|
||||
describe('AuthResponseParsingService', () => {
|
||||
let service: AuthResponseParsingService;
|
||||
|
||||
const EnvConfig = { cache: { msToLive: 1000 } } as GlobalConfig;
|
||||
const store = new MockStore<ObjectCacheState>({});
|
||||
const objectCacheService = new ObjectCacheService(store as any);
|
||||
let store: any;
|
||||
let objectCacheService: ObjectCacheService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
StoreModule.forRoot({}),
|
||||
],
|
||||
providers: [
|
||||
{ provide: Store, useClass: MockStore }
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
store = TestBed.get(Store);
|
||||
objectCacheService = new ObjectCacheService(store as any);
|
||||
service = new AuthResponseParsingService(EnvConfig, objectCacheService);
|
||||
});
|
||||
|
||||
|
@@ -42,10 +42,12 @@ describe('IntegrationService', () => {
|
||||
const name = 'type';
|
||||
const metadata = 'dc.type';
|
||||
const query = '';
|
||||
const value = 'test';
|
||||
const uuid = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
|
||||
const integrationEndpoint = 'https://rest.api/integration';
|
||||
const serviceEndpoint = `${integrationEndpoint}/${LINK_NAME}`;
|
||||
const entriesEndpoint = `${serviceEndpoint}/${name}/entries?query=${query}&metadata=${metadata}&uuid=${uuid}`;
|
||||
const entryValueEndpoint = `${serviceEndpoint}/${name}/entryValue/${value}?metadata=${metadata}`;
|
||||
|
||||
findOptions = new IntegrationSearchOptions(uuid, name, metadata);
|
||||
|
||||
@@ -88,4 +90,20 @@ describe('IntegrationService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getEntryByValue', () => {
|
||||
|
||||
it('should configure a new IntegrationRequest', () => {
|
||||
findOptions = new IntegrationSearchOptions(
|
||||
null,
|
||||
name,
|
||||
metadata,
|
||||
value);
|
||||
|
||||
const expected = new IntegrationRequest(requestService.generateRequestId(), entryValueEndpoint);
|
||||
scheduler.schedule(() => service.getEntryByValue(findOptions).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -315,8 +315,6 @@ describe('jsonPatchOperationsReducer test suite', () => {
|
||||
const action = new FlushPatchOperationsAction(testJsonPatchResourceType, undefined);
|
||||
const newState = jsonPatchOperationsReducer(initState, action);
|
||||
|
||||
console.log(initState);
|
||||
console.log(newState);
|
||||
expect(newState[testJsonPatchResourceType].transactionStartTime).toBeNull();
|
||||
expect(newState[testJsonPatchResourceType].commitPending).toBeFalsy();
|
||||
expect(newState[testJsonPatchResourceType].children[testJsonPatchResourceId].body).toEqual([]);
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
|
||||
import { getMockRequestService } from '../../shared/mocks/mock-request.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
@@ -16,12 +17,12 @@ import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-respon
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { JsonPatchOperationsEntry, JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer';
|
||||
import { MockStore } from '../../shared/testing/mock-store';
|
||||
import {
|
||||
CommitPatchOperationsAction,
|
||||
RollbacktPatchOperationsAction,
|
||||
StartTransactionPatchOperationsAction
|
||||
} from './json-patch-operations.actions';
|
||||
import { MockStore } from '../../shared/testing/mock-store';
|
||||
|
||||
class TestService extends JsonPatchOperationsService<SubmitDataResponseDefinitionObject, SubmissionPatchRequest> {
|
||||
protected linkPath = '';
|
||||
@@ -102,8 +103,19 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
|
||||
}
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
StoreModule.forRoot({}),
|
||||
],
|
||||
providers: [
|
||||
{ provide: Store, useClass: MockStore }
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
store = new MockStore<CoreState>({} as CoreState);
|
||||
store = TestBed.get(Store);
|
||||
responseCache = initMockResponseCacheService(true);
|
||||
requestService = getMockRequestService();
|
||||
rdbService = getMockRemoteDataBuildService();
|
||||
@@ -111,8 +123,8 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
halService = new HALEndpointServiceStub(resourceEndpointURL);
|
||||
service = initTestService();
|
||||
|
||||
spyOn((service as any).store, 'select').and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
spyOn((service as any).store, 'dispatch').and.callThrough();
|
||||
spyOn(store, 'select').and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
spyOn(store, 'dispatch').and.callThrough();
|
||||
spyOn(Date.prototype, 'getTime').and.callFake(() => {
|
||||
return timestamp;
|
||||
});
|
||||
@@ -142,7 +154,7 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceType(resourceEndpoint, resourceScope, testJsonPatchResourceType).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
|
||||
describe('when request is successful', () => {
|
||||
@@ -151,13 +163,13 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceType(resourceEndpoint, resourceScope, testJsonPatchResourceType).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when request is not successful', () => {
|
||||
beforeEach(() => {
|
||||
store = new MockStore<CoreState>({} as CoreState);
|
||||
store = TestBed.get(Store);
|
||||
responseCache = initMockResponseCacheService(false);
|
||||
requestService = getMockRequestService();
|
||||
rdbService = getMockRemoteDataBuildService();
|
||||
@@ -165,8 +177,8 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
halService = new HALEndpointServiceStub(resourceEndpointURL);
|
||||
service = initTestService();
|
||||
|
||||
spyOn((service as any).store, 'select').and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
spyOn((service as any).store, 'dispatch').and.callThrough();
|
||||
store.select.and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
store.dispatch.and.callThrough();
|
||||
});
|
||||
|
||||
it('should dispatch a new RollbacktPatchOperationsAction', () => {
|
||||
@@ -175,7 +187,7 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceType(resourceEndpoint, resourceScope, testJsonPatchResourceType).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -204,7 +216,7 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceID(resourceEndpoint, resourceScope, testJsonPatchResourceType, testJsonPatchResourceId).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
|
||||
describe('when request is successful', () => {
|
||||
@@ -213,13 +225,13 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceID(resourceEndpoint, resourceScope, testJsonPatchResourceType, testJsonPatchResourceId).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when request is not successful', () => {
|
||||
beforeEach(() => {
|
||||
store = new MockStore<CoreState>({} as CoreState);
|
||||
store = TestBed.get(Store);
|
||||
responseCache = initMockResponseCacheService(false);
|
||||
requestService = getMockRequestService();
|
||||
rdbService = getMockRemoteDataBuildService();
|
||||
@@ -227,8 +239,8 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
halService = new HALEndpointServiceStub(resourceEndpointURL);
|
||||
service = initTestService();
|
||||
|
||||
spyOn((service as any).store, 'select').and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
spyOn((service as any).store, 'dispatch').and.callThrough();
|
||||
store.select.and.returnValue(observableOf(mockState['json/patch'][testJsonPatchResourceType]));
|
||||
store.dispatch.and.callThrough();
|
||||
});
|
||||
|
||||
it('should dispatch a new RollbacktPatchOperationsAction', () => {
|
||||
@@ -237,7 +249,7 @@ describe('JsonPatchOperationsService test suite', () => {
|
||||
scheduler.schedule(() => service.jsonPatchByResourceID(resourceEndpoint, resourceScope, testJsonPatchResourceType, testJsonPatchResourceId).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expectedAction);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -20,14 +20,11 @@ import { FormFieldMetadataValueObject } from '../../../models/form-field-metadat
|
||||
import { DsDynamicInputModel } from '../ds-dynamic-input.model';
|
||||
import { createTestComponent } from '../../../../../testing/utils';
|
||||
import { DynamicFormLayoutService, DynamicFormValidationService } from '@ng-dynamic-forms/core';
|
||||
import { MockStore } from '../../../../../testing/mock-store';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '../../../../../../app.reducer';
|
||||
import { AuthService } from '../../../../../../core/auth/auth.service';
|
||||
import { AuthServiceStub } from '../../../../../testing/auth-service-stub';
|
||||
import { AuthorityService } from '../../../../../../core/integration/authority.service';
|
||||
import { AuthorityServiceStub } from '../../../../../testing/authority-service-stub';
|
||||
import { MOCK_SUBMISSION_CONFIG } from '../../../../../testing/mock-submission-config';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { MockStore } from '../../../../../testing/mock-store';
|
||||
|
||||
export let FORM_GROUP_TEST_MODEL_CONFIG;
|
||||
|
||||
@@ -103,7 +100,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
|
||||
// async beforeEach
|
||||
beforeEach(async(() => {
|
||||
init();
|
||||
const store = new MockStore<AppState>(Object.create(null));
|
||||
|
||||
/* TODO make sure these files use mocks instead of real services/components https://github.com/DSpace/dspace-angular/issues/281 */
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
@@ -111,6 +108,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
NgbModule.forRoot(),
|
||||
StoreModule.forRoot({}),
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
@@ -128,7 +126,7 @@ describe('DsDynamicRelationGroupComponent test suite', () => {
|
||||
FormService,
|
||||
{ provide: AuthorityService, useValue: new AuthorityServiceStub() },
|
||||
{ provide: GLOBAL_CONFIG, useValue: config },
|
||||
{ provide: Store, useValue: store },
|
||||
{ provide: Store, useClass: MockStore }
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
});
|
||||
|
@@ -10,7 +10,7 @@ import {
|
||||
DynamicFormValidationService,
|
||||
DynamicInputModel
|
||||
} from '@ng-dynamic-forms/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
@@ -124,7 +124,6 @@ function init() {
|
||||
}
|
||||
};
|
||||
|
||||
store = new MockStore<FormState>(formState);
|
||||
}
|
||||
|
||||
describe('FormComponent test suite', () => {
|
||||
@@ -144,6 +143,7 @@ describe('FormComponent test suite', () => {
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
NgbModule.forRoot(),
|
||||
StoreModule.forRoot({}),
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
@@ -157,9 +157,7 @@ describe('FormComponent test suite', () => {
|
||||
FormComponent,
|
||||
FormService,
|
||||
{ provide: GLOBAL_CONFIG, useValue: config },
|
||||
{
|
||||
provide: Store, useValue: store
|
||||
}
|
||||
{ provide: Store, useClass: MockStore }
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
});
|
||||
@@ -177,6 +175,7 @@ describe('FormComponent test suite', () => {
|
||||
|
||||
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
||||
testComp = testFixture.componentInstance;
|
||||
|
||||
});
|
||||
afterEach(() => {
|
||||
testFixture.destroy();
|
||||
@@ -194,6 +193,7 @@ describe('FormComponent test suite', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
formFixture = TestBed.createComponent(FormComponent);
|
||||
store = TestBed.get(Store);
|
||||
formComp = formFixture.componentInstance; // FormComponent test instance
|
||||
formComp.formId = 'testForm';
|
||||
formComp.formModel = TEST_FORM_MODEL;
|
||||
@@ -384,6 +384,7 @@ describe('FormComponent test suite', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
formFixture = TestBed.createComponent(FormComponent);
|
||||
store = TestBed.get(Store);
|
||||
formComp = formFixture.componentInstance; // FormComponent test instance
|
||||
formComp.formId = 'testFormArray';
|
||||
formComp.formModel = TEST_FORM_MODEL_WITH_ARRAY;
|
||||
|
7
src/app/shared/mocks/mock-translate.service.ts
Normal file
7
src/app/shared/mocks/mock-translate.service.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
export function getMockTranslateService(): TranslateService {
|
||||
return jasmine.createSpyObj('translateService', {
|
||||
get: jasmine.createSpy('get')
|
||||
});
|
||||
}
|
@@ -1,24 +1,21 @@
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Action } from '@ngrx/store';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActionsSubject, ReducerManager, StateObservable, Store } from '@ngrx/store';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
|
||||
export class MockStore<T> extends BehaviorSubject<T> {
|
||||
@Injectable()
|
||||
export class MockStore<T> extends Store<T> {
|
||||
private stateSubject = new BehaviorSubject<T>({} as T);
|
||||
|
||||
constructor(private _initialState: T) {
|
||||
super(_initialState);
|
||||
constructor(
|
||||
state$: StateObservable,
|
||||
actionsObserver: ActionsSubject,
|
||||
reducerManager: ReducerManager
|
||||
) {
|
||||
super(state$, actionsObserver, reducerManager);
|
||||
this.source = this.stateSubject.asObservable();
|
||||
}
|
||||
|
||||
dispatch = (action: Action): void => {
|
||||
// console.info(action);
|
||||
};
|
||||
|
||||
select = <R>(pathOrMapFn: any): Observable<T> => {
|
||||
return this.asObservable().pipe(
|
||||
map((value) => pathOrMapFn.projector(value)))
|
||||
};
|
||||
|
||||
nextState(_newState: T) {
|
||||
this.next(_newState);
|
||||
nextState(nextState: T) {
|
||||
this.stateSubject.next(nextState);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { cold, hot } from 'jasmine-marbles';
|
||||
import { provideMockActions } from '@ngrx/effects/testing';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@@ -65,6 +65,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
StoreModule.forRoot({}),
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
@@ -75,7 +76,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
providers: [
|
||||
SubmissionObjectEffects,
|
||||
TranslateService,
|
||||
{provide: Store, useValue: new MockStore({})},
|
||||
{ provide: Store, useClass: MockStore },
|
||||
provideMockActions(() => actions),
|
||||
{ provide: NotificationsService, useValue: notificationsServiceStub },
|
||||
{ provide: SectionsService, useClass: SectionsServiceStub },
|
||||
@@ -85,6 +86,7 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
submissionObjectEffects = TestBed.get(SubmissionObjectEffects);
|
||||
store = TestBed.get(Store);
|
||||
});
|
||||
|
||||
describe('loadForm$', () => {
|
||||
@@ -263,7 +265,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
describe('saveSubmissionSuccess$', () => {
|
||||
|
||||
it('should return a UPLOAD_SECTION_DATA action for each updated section', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -312,7 +313,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should display a success notification', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -358,7 +358,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should display a warning notification when there are errors', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -406,7 +405,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should detect and notify a new section', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -534,7 +532,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should not allow to deposit when there are errors', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -609,7 +606,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
|
||||
describe('depositSubmission$', () => {
|
||||
it('should return a DEPOSIT_SUBMISSION_SUCCESS action on success', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -636,7 +632,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should return a DEPOSIT_SUBMISSION_ERROR action on error', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -721,7 +716,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
|
||||
describe('discardSubmission$', () => {
|
||||
it('should return a DISCARD_SUBMISSION_SUCCESS action on success', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
@@ -748,7 +742,6 @@ describe('SubmissionObjectEffects test suite', () => {
|
||||
});
|
||||
|
||||
it('should return a DISCARD_SUBMISSION_ERROR action on error', () => {
|
||||
store = TestBed.get(Store);
|
||||
store.nextState({
|
||||
submission: {
|
||||
objects: mockSubmissionState
|
||||
|
@@ -69,7 +69,7 @@ export class SectionsDirective implements OnDestroy, OnInit {
|
||||
this.changeDetectorRef.detectChanges();
|
||||
// If section is no longer active dispatch save action
|
||||
if (!this.active && isNotNull(activeSectionId)) {
|
||||
this.submissionService.dispatchSaveSection(this.submissionId, this.sectionId);
|
||||
this.submissionService.dispatchSave(this.submissionId);
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -89,7 +89,7 @@ export class SectionsDirective implements OnDestroy, OnInit {
|
||||
}
|
||||
|
||||
public isOpen() {
|
||||
return (this.sectionState) ? true : false;
|
||||
return this.sectionState;
|
||||
}
|
||||
|
||||
public isMandatory() {
|
||||
|
378
src/app/submission/sections/sections.service.spec.ts
Normal file
378
src/app/submission/sections/sections.service.spec.ts
Normal file
@@ -0,0 +1,378 @@
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { submissionReducers } from '../submission.reducers';
|
||||
import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { SubmissionService } from '../submission.service';
|
||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service-stub';
|
||||
import { SubmissionServiceStub } from '../../shared/testing/submission-service-stub';
|
||||
import { getMockTranslateService } from '../../shared/mocks/mock-translate.service';
|
||||
import { SectionsService } from './sections.service';
|
||||
import { mockSectionsData, mockSectionsErrors, mockSubmissionState } from '../../shared/mocks/mock-submission';
|
||||
import {
|
||||
DisableSectionAction,
|
||||
EnableSectionAction,
|
||||
InertSectionErrorsAction,
|
||||
RemoveSectionErrorsAction,
|
||||
SectionStatusChangeAction,
|
||||
UpdateSectionDataAction
|
||||
} from '../objects/submission-objects.actions';
|
||||
import { FormAddError, FormClearErrorsAction, FormRemoveErrorAction } from '../../shared/form/form.actions';
|
||||
import parseSectionErrors from '../utils/parseSectionErrors';
|
||||
import { SubmissionScopeType } from '../../core/submission/submission-scope-type';
|
||||
import { SubmissionSectionError } from '../objects/submission-objects.reducer';
|
||||
|
||||
describe('SectionsService test suite', () => {
|
||||
let notificationsServiceStub: NotificationsServiceStub;
|
||||
let scrollToService: ScrollToService;
|
||||
let service: SectionsService;
|
||||
let submissionServiceStub: SubmissionServiceStub;
|
||||
let translateService: any;
|
||||
|
||||
const formId = 'formTest';
|
||||
const submissionId = '826';
|
||||
const sectionId = 'traditionalpageone';
|
||||
const sectionErrors: any = parseSectionErrors(mockSectionsErrors);
|
||||
const sectionData: any = mockSectionsData;
|
||||
const sectionState: any = mockSubmissionState['826'].sections[sectionId];
|
||||
|
||||
const store: any = jasmine.createSpyObj('store', {
|
||||
dispatch: jasmine.createSpy('dispatch'),
|
||||
select: jasmine.createSpy('select')
|
||||
});
|
||||
|
||||
function getMockScrollToService(): ScrollToService {
|
||||
return jasmine.createSpyObj('scrollToService', {
|
||||
scrollTo: jasmine.createSpy('scrollTo')
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
StoreModule.forRoot({submissionReducers} as any),
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: MockTranslateLoader
|
||||
}
|
||||
})
|
||||
],
|
||||
providers: [
|
||||
{ provide: NotificationsService, useClass: NotificationsServiceStub },
|
||||
{ provide: ScrollToService, useValue: getMockScrollToService() },
|
||||
{ provide: SubmissionService, useClass: SubmissionServiceStub },
|
||||
{ provide: TranslateService, useValue: getMockTranslateService() },
|
||||
{ provide: Store, useValue: store },
|
||||
SectionsService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.get(SectionsService);
|
||||
submissionServiceStub = TestBed.get(SubmissionService);
|
||||
notificationsServiceStub = TestBed.get(NotificationsService);
|
||||
scrollToService = TestBed.get(ScrollToService);
|
||||
translateService = TestBed.get(TranslateService);
|
||||
});
|
||||
|
||||
describe('checkSectionErrors', () => {
|
||||
it('should dispatch a new RemoveSectionErrorsAction and FormClearErrorsAction when there are no errors', () => {
|
||||
service.checkSectionErrors(submissionId, sectionId, formId, []);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new RemoveSectionErrorsAction(submissionId, sectionId));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormClearErrorsAction(formId));
|
||||
});
|
||||
|
||||
it('should dispatch a new FormAddError for each section\'s error', () => {
|
||||
service.checkSectionErrors(submissionId, sectionId, formId, sectionErrors[sectionId]);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormAddError(
|
||||
formId,
|
||||
'dc_contributor_author',
|
||||
0,
|
||||
'error.validation.required'));
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormAddError(
|
||||
formId,
|
||||
'dc_title',
|
||||
0,
|
||||
'error.validation.required'));
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormAddError(formId,
|
||||
'dc_date_issued',
|
||||
0,
|
||||
'error.validation.required'));
|
||||
});
|
||||
|
||||
it('should dispatch a new FormRemoveErrorAction for each section\'s error that no longer exists', () => {
|
||||
const currentErrors = Array.of(...sectionErrors[sectionId]);
|
||||
const prevErrors = Array.of(...sectionErrors[sectionId]);
|
||||
currentErrors.pop();
|
||||
|
||||
service.checkSectionErrors(submissionId, sectionId, formId, currentErrors, prevErrors);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormAddError(
|
||||
formId,
|
||||
'dc_contributor_author',
|
||||
0,
|
||||
'error.validation.required'));
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormAddError(
|
||||
formId,
|
||||
'dc_title',
|
||||
0,
|
||||
'error.validation.required'));
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new FormRemoveErrorAction(
|
||||
formId,
|
||||
'dc_date_issued',
|
||||
0));
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchRemoveSectionErrors', () => {
|
||||
it('should dispatch a new RemoveSectionErrorsAction', () => {
|
||||
service.dispatchRemoveSectionErrors(submissionId, sectionId);
|
||||
const expected = new RemoveSectionErrorsAction(submissionId, sectionId);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSectionData', () => {
|
||||
it('should return an observable with section\'s data', () => {
|
||||
store.select.and.returnValue(observableOf(sectionData[sectionId]));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: sectionData[sectionId]
|
||||
});
|
||||
|
||||
expect(service.getSectionData(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSectionErrors', () => {
|
||||
it('should return an observable with section\'s errors', () => {
|
||||
store.select.and.returnValue(observableOf(sectionErrors[sectionId]));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: sectionErrors[sectionId]
|
||||
});
|
||||
|
||||
expect(service.getSectionErrors(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSectionState', () => {
|
||||
it('should return an observable with section\'s state', () => {
|
||||
store.select.and.returnValue(observableOf(sectionState));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: sectionState
|
||||
});
|
||||
|
||||
expect(service.getSectionState(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionValid', () => {
|
||||
it('should return an observable of boolean', () => {
|
||||
store.select.and.returnValue(observableOf({isValid: false}));
|
||||
|
||||
let expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionValid(submissionId, sectionId)).toBeObservable(expected);
|
||||
|
||||
store.select.and.returnValue(observableOf({isValid: true}));
|
||||
|
||||
expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
expect(service.isSectionValid(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionActive', () => {
|
||||
it('should return an observable of boolean', () => {
|
||||
submissionServiceStub.getActiveSectionId.and.returnValue(observableOf(sectionId));
|
||||
|
||||
let expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
expect(service.isSectionActive(submissionId, sectionId)).toBeObservable(expected);
|
||||
|
||||
submissionServiceStub.getActiveSectionId.and.returnValue(observableOf('test'));
|
||||
|
||||
expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionActive(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionEnabled', () => {
|
||||
it('should return an observable of boolean', () => {
|
||||
store.select.and.returnValue(observableOf({enabled: false}));
|
||||
|
||||
let expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionEnabled(submissionId, sectionId)).toBeObservable(expected);
|
||||
|
||||
store.select.and.returnValue(observableOf({enabled: true}));
|
||||
|
||||
expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
expect(service.isSectionEnabled(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionReadOnly', () => {
|
||||
it('should return an observable of true when it\'s a readonly section and scope is not workspace', () => {
|
||||
store.select.and.returnValue(observableOf({
|
||||
visibility: {
|
||||
main: null,
|
||||
other: 'READONLY'
|
||||
}
|
||||
}));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return an observable of false when it\'s a readonly section and scope is workspace', () => {
|
||||
store.select.and.returnValue(observableOf({
|
||||
visibility: {
|
||||
main: null,
|
||||
other: 'READONLY'
|
||||
}
|
||||
}));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkspaceItem)).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return an observable of false when it\'s not a readonly section', () => {
|
||||
store.select.and.returnValue(observableOf({
|
||||
visibility: null
|
||||
}));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionReadOnly(submissionId, sectionId, SubmissionScopeType.WorkflowItem)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionAvailable', () => {
|
||||
it('should return an observable of true when section is available', () => {
|
||||
store.select.and.returnValue(observableOf(mockSubmissionState[submissionId]));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
expect(service.isSectionAvailable(submissionId, sectionId)).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return an observable of false when section is not available', () => {
|
||||
store.select.and.returnValue(observableOf(mockSubmissionState[submissionId]));
|
||||
|
||||
const expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(service.isSectionAvailable(submissionId, 'test')).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addSection', () => {
|
||||
it('should dispatch a new EnableSectionAction a move target to new section', () => {
|
||||
|
||||
service.addSection(submissionId, 'newSection');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new EnableSectionAction(submissionId, 'newSection'));
|
||||
expect(scrollToService.scrollTo).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeSection', () => {
|
||||
it('should dispatch a new DisableSectionAction', () => {
|
||||
|
||||
service.removeSection(submissionId, 'newSection');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new DisableSectionAction(submissionId, 'newSection'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSectionError', () => {
|
||||
it('should dispatch a new InertSectionErrorsAction', () => {
|
||||
|
||||
const error: SubmissionSectionError = {
|
||||
path: 'test',
|
||||
message: 'message test'
|
||||
};
|
||||
service.setSectionError(submissionId, sectionId, error);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new InertSectionErrorsAction(submissionId, sectionId, error));
|
||||
});
|
||||
});
|
||||
|
||||
describe('setSectionStatus', () => {
|
||||
it('should dispatch a new SectionStatusChangeAction', () => {
|
||||
|
||||
service.setSectionStatus(submissionId, sectionId, true);
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SectionStatusChangeAction(submissionId, sectionId, true));
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateSectionData', () => {
|
||||
|
||||
it('should dispatch a new UpdateSectionDataAction', () => {
|
||||
const scheduler = getTestScheduler();
|
||||
const data: any = {test: 'test'};
|
||||
spyOn(service, 'isSectionAvailable').and.returnValue(observableOf(true));
|
||||
spyOn(service, 'isSectionEnabled').and.returnValue(observableOf(true));
|
||||
scheduler.schedule(() => service.updateSectionData(submissionId, sectionId, data, []));
|
||||
scheduler.flush();
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new UpdateSectionDataAction(submissionId, sectionId, data, []));
|
||||
});
|
||||
|
||||
it('should dispatch a new UpdateSectionDataAction and display a new notification when section is not enabled', () => {
|
||||
const scheduler = getTestScheduler();
|
||||
const data: any = {test: 'test'};
|
||||
spyOn(service, 'isSectionAvailable').and.returnValue(observableOf(true));
|
||||
spyOn(service, 'isSectionEnabled').and.returnValue(observableOf(false));
|
||||
translateService.get.and.returnValue(observableOf('test'));
|
||||
scheduler.schedule(() => service.updateSectionData(submissionId, sectionId, data, []));
|
||||
scheduler.flush();
|
||||
|
||||
expect(notificationsServiceStub.info).toHaveBeenCalled();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new UpdateSectionDataAction(submissionId, sectionId, data, []));
|
||||
});
|
||||
});
|
||||
});
|
@@ -133,7 +133,9 @@ export class SectionsService {
|
||||
return this.store.select(submissionSectionFromIdSelector(submissionId, sectionId)).pipe(
|
||||
filter((sectionObj) => hasValue(sectionObj)),
|
||||
map((sectionObj: SubmissionSectionObject) => {
|
||||
return sectionObj.visibility.other === 'READONLY' && submissionScope !== SubmissionScopeType.WorkspaceItem
|
||||
return isNotEmpty(sectionObj.visibility)
|
||||
&& sectionObj.visibility.other === 'READONLY'
|
||||
&& submissionScope !== SubmissionScopeType.WorkspaceItem
|
||||
}),
|
||||
distinctUntilChanged());
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<ng-container *ngIf="readMode">
|
||||
<button class="btn btn-link" (click)="downloadBitstreamFile(); $event.stopPropagation()"><i class="fa fa-download fa-2x text-normal" aria-hidden="true"></i></button>
|
||||
<!--<a href="{{fileData.url}}" title="Download file" target="_blank"><i class="fa fa-download text-normal mr-3" aria-hidden="true"></i></a>-->
|
||||
<button class="btn btn-link" (click)="$event.preventDefault();switchMode();"><i class="fa fa-pencil-square-o fa-2x text-normal"></i></button>
|
||||
<button class="btn btn-link" (click)="$event.preventDefault();switchMode();"><i class="fa fa-edit fa-2x text-normal"></i></button>
|
||||
<button class="btn btn-link" (click)="$event.preventDefault();confirmDelete(content);"><i class="fa fa-trash fa-2x text-danger"></i></button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!readMode">
|
||||
|
102
src/app/submission/submission-rest.service.spec.ts
Normal file
102
src/app/submission/submission-rest.service.spec.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
|
||||
import { SubmissionRestService } from './submission-rest.service';
|
||||
import { ResponseCacheService } from '../core/cache/response-cache.service';
|
||||
import { RequestService } from '../core/data/request.service';
|
||||
import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service';
|
||||
import { getMockRequestService } from '../shared/mocks/mock-request.service';
|
||||
import { getMockRemoteDataBuildService } from '../shared/mocks/mock-remote-data-build.service';
|
||||
import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service-stub';
|
||||
import {
|
||||
SubmissionDeleteRequest,
|
||||
SubmissionPatchRequest,
|
||||
SubmissionPostRequest,
|
||||
SubmissionRequest
|
||||
} from '../core/data/request.models';
|
||||
import { FormFieldMetadataValueObject } from '../shared/form/builder/models/form-field-metadata-value.model';
|
||||
|
||||
describe('SubmissionRestService test suite', () => {
|
||||
let scheduler: TestScheduler;
|
||||
let service: SubmissionRestService;
|
||||
let responseCache: ResponseCacheService;
|
||||
let requestService: RequestService;
|
||||
let rdbService: RemoteDataBuildService;
|
||||
let halService: any;
|
||||
|
||||
const resourceEndpointURL = 'https://rest.api/endpoint';
|
||||
const resourceEndpoint = 'workspaceitems';
|
||||
const resourceScope = '260';
|
||||
const body = { test: new FormFieldMetadataValueObject('test')};
|
||||
const resourceHref = resourceEndpointURL + '/' + resourceEndpoint + '/' + resourceScope;
|
||||
const timestampResponse = 1545994811992;
|
||||
|
||||
function initMockResponseCacheService(isSuccessful: boolean): ResponseCacheService {
|
||||
return jasmine.createSpyObj('responseCache', {
|
||||
get: cold('c-', {
|
||||
c: {response: {isSuccessful},
|
||||
timeAdded: timestampResponse}
|
||||
}),
|
||||
remove: jasmine.createSpy('remove')
|
||||
});
|
||||
}
|
||||
|
||||
function initTestService() {
|
||||
return new SubmissionRestService(
|
||||
rdbService,
|
||||
responseCache,
|
||||
requestService,
|
||||
halService
|
||||
);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
responseCache = initMockResponseCacheService(true);
|
||||
requestService = getMockRequestService();
|
||||
rdbService = getMockRemoteDataBuildService();
|
||||
scheduler = getTestScheduler();
|
||||
halService = new HALEndpointServiceStub(resourceEndpointURL);
|
||||
service = initTestService();
|
||||
|
||||
});
|
||||
|
||||
describe('deleteById', () => {
|
||||
it('should configure a new SubmissionDeleteRequest', () => {
|
||||
const expected = new SubmissionDeleteRequest(requestService.generateRequestId(), resourceHref);
|
||||
scheduler.schedule(() => service.deleteById(resourceScope, resourceEndpoint).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDataById', () => {
|
||||
it('should configure a new SubmissionRequest', () => {
|
||||
const expected = new SubmissionRequest(requestService.generateRequestId(), resourceHref);
|
||||
scheduler.schedule(() => service.getDataById(resourceEndpoint, resourceScope).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(expected, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('postToEndpoint', () => {
|
||||
it('should configure a new SubmissionPostRequest', () => {
|
||||
const expected = new SubmissionPostRequest(requestService.generateRequestId(), resourceHref, body);
|
||||
scheduler.schedule(() => service.postToEndpoint(resourceEndpoint, body, resourceScope).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(expected, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('patchToEndpoint', () => {
|
||||
it('should configure a new SubmissionPatchRequest', () => {
|
||||
const expected = new SubmissionPatchRequest(requestService.generateRequestId(), resourceHref, body);
|
||||
scheduler.schedule(() => service.patchToEndpoint(resourceEndpoint, body, resourceScope).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(requestService.configure).toHaveBeenCalledWith(expected, true);
|
||||
});
|
||||
});
|
||||
});
|
@@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
import { merge as observableMerge, Observable, throwError as observableThrowError } from 'rxjs';
|
||||
import { distinctUntilChanged, filter, flatMap, map, mergeMap, tap } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { ResponseCacheService } from '../core/cache/response-cache.service';
|
||||
import { RequestService } from '../core/data/request.service';
|
||||
@@ -10,7 +9,6 @@ import { ResponseCacheEntry } from '../core/cache/response-cache.reducer';
|
||||
import { SubmissionSuccessResponse } from '../core/cache/response-cache.models';
|
||||
import { isNotEmpty } from '../shared/empty.util';
|
||||
import {
|
||||
ConfigRequest,
|
||||
DeleteRequest,
|
||||
PostRequest,
|
||||
RestRequest,
|
||||
@@ -20,7 +18,6 @@ import {
|
||||
SubmissionRequest
|
||||
} from '../core/data/request.models';
|
||||
import { SubmitDataResponseDefinitionObject } from '../core/shared/submit-data-response-definition.model';
|
||||
import { CoreState } from '../core/core.reducers';
|
||||
import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { HALEndpointService } from '../core/shared/hal-endpoint.service';
|
||||
import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service';
|
||||
@@ -33,7 +30,6 @@ export class SubmissionRestService {
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected responseCache: ResponseCacheService,
|
||||
protected requestService: RequestService,
|
||||
protected store: Store<CoreState>,
|
||||
protected halService: HALEndpointService) {
|
||||
}
|
||||
|
||||
@@ -104,13 +100,6 @@ export class SubmissionRestService {
|
||||
distinctUntilChanged());
|
||||
}
|
||||
|
||||
public getDataByHref(href: string, options?: HttpOptions): Observable<any> {
|
||||
const request = new ConfigRequest(this.requestService.generateRequestId(), href, options);
|
||||
this.requestService.configure(request, true);
|
||||
|
||||
return this.fetchRequest(request);
|
||||
}
|
||||
|
||||
public getDataById(linkName: string, id: string): Observable<any> {
|
||||
return this.halService.getEndpoint(linkName).pipe(
|
||||
map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, id)),
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { async, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { async, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { HttpHeaders } from '@angular/common/http';
|
||||
|
||||
import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { cold, hot, } from 'jasmine-marbles';
|
||||
|
||||
@@ -17,14 +17,27 @@ import { MockActivatedRoute } from '../shared/mocks/mock-active-router';
|
||||
import { GLOBAL_CONFIG } from '../../config';
|
||||
import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { SubmissionScopeType } from '../core/submission/submission-scope-type';
|
||||
import { submissionRestResponse } from '../shared/mocks/mock-submission';
|
||||
import { mockSubmissionDefinition, submissionRestResponse } from '../shared/mocks/mock-submission';
|
||||
import { NotificationsService } from '../shared/notifications/notifications.service';
|
||||
import { MockTranslateLoader } from '../shared/mocks/mock-translate-loader';
|
||||
import { MOCK_SUBMISSION_CONFIG } from '../shared/testing/mock-submission-config';
|
||||
import {
|
||||
CancelSubmissionFormAction,
|
||||
ChangeSubmissionCollectionAction,
|
||||
DiscardSubmissionAction,
|
||||
InitSubmissionFormAction,
|
||||
ResetSubmissionFormAction,
|
||||
SaveAndDepositSubmissionAction,
|
||||
SaveForLaterSubmissionFormAction,
|
||||
SaveSubmissionFormAction, SaveSubmissionSectionFormAction,
|
||||
SetActiveSectionAction
|
||||
} from './objects/submission-objects.actions';
|
||||
|
||||
describe('SubmissionService test suite', () => {
|
||||
const config = MOCK_SUBMISSION_CONFIG;
|
||||
|
||||
const collectionId = '43fe1f8c-09a6-4fcf-9c78-5d4fed8f2c8f';
|
||||
const submissionId = '826';
|
||||
const sectionId = 'test';
|
||||
const subState = {
|
||||
objects: {
|
||||
826: {
|
||||
@@ -317,6 +330,8 @@ describe('SubmissionService test suite', () => {
|
||||
};
|
||||
const restService = new SubmissionRestServiceStub();
|
||||
const router = new MockRouter();
|
||||
const selfUrl = 'https://rest.api/dspace-spring-rest/api/submission/workspaceitems/826';
|
||||
const submissionDefinition: any = mockSubmissionDefinition;
|
||||
|
||||
let service: SubmissionService;
|
||||
|
||||
@@ -338,7 +353,6 @@ describe('SubmissionService test suite', () => {
|
||||
{provide: ActivatedRoute, useValue: new MockActivatedRoute()},
|
||||
NotificationsService,
|
||||
RouteService,
|
||||
ScrollToService,
|
||||
SubmissionService,
|
||||
TranslateService
|
||||
]
|
||||
@@ -347,17 +361,28 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.get(SubmissionService);
|
||||
spyOn((service as any).store, 'dispatch').and.callThrough()
|
||||
});
|
||||
|
||||
describe('changeSubmissionCollection', () => {
|
||||
it('should dispatch a new ChangeSubmissionCollectionAction', () => {
|
||||
service.changeSubmissionCollection(submissionId, collectionId);
|
||||
const expected = new ChangeSubmissionCollectionAction(submissionId, collectionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createSubmission', () => {
|
||||
it('should create a new submission', () => {
|
||||
service.createSubmission();
|
||||
|
||||
expect((service as any).restService.postToEndpoint).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('depositSubmission', () => {
|
||||
it('should deposit submission', () => {
|
||||
|
||||
const selfUrl = 'https://rest.api/dspace-spring-rest/api/submission/workspaceitems/826';
|
||||
const options: HttpOptions = Object.create({});
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.append('Content-Type', 'text/uri-list');
|
||||
@@ -367,13 +392,84 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect((service as any).restService.postToEndpoint).toHaveBeenCalledWith('workflowitems', selfUrl, null, options);
|
||||
});
|
||||
});
|
||||
|
||||
describe('discardSubmission', () => {
|
||||
it('should discard submission', () => {
|
||||
service.discardSubmission('826');
|
||||
|
||||
expect((service as any).restService.deleteById).toHaveBeenCalledWith('826');
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchInit', () => {
|
||||
it('should dispatch a new InitSubmissionFormAction', () => {
|
||||
service.dispatchInit(
|
||||
collectionId,
|
||||
submissionId,
|
||||
selfUrl,
|
||||
submissionDefinition,
|
||||
{},
|
||||
[]
|
||||
);
|
||||
const expected = new InitSubmissionFormAction(
|
||||
collectionId,
|
||||
submissionId,
|
||||
selfUrl,
|
||||
submissionDefinition,
|
||||
{},
|
||||
[]);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchDeposit', () => {
|
||||
it('should dispatch a new SaveAndDepositSubmissionAction', () => {
|
||||
service.dispatchDeposit(submissionId,);
|
||||
const expected = new SaveAndDepositSubmissionAction(submissionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchDiscard', () => {
|
||||
it('should dispatch a new DiscardSubmissionAction', () => {
|
||||
service.dispatchDiscard(submissionId,);
|
||||
const expected = new DiscardSubmissionAction(submissionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchSave', () => {
|
||||
it('should dispatch a new SaveSubmissionFormAction', () => {
|
||||
service.dispatchSave(submissionId,);
|
||||
const expected = new SaveSubmissionFormAction(submissionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchSaveForLater', () => {
|
||||
it('should dispatch a new SaveForLaterSubmissionFormAction', () => {
|
||||
service.dispatchSaveForLater(submissionId,);
|
||||
const expected = new SaveForLaterSubmissionFormAction(submissionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispatchSaveSection', () => {
|
||||
it('should dispatch a new SaveSubmissionSectionFormAction', () => {
|
||||
service.dispatchSaveSection(submissionId, sectionId);
|
||||
const expected = new SaveSubmissionSectionFormAction(submissionId, sectionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionObject', () => {
|
||||
it('should return submission object state from the store', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('a', {
|
||||
a: subState.objects[826]
|
||||
@@ -384,7 +480,9 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getActiveSectionId', () => {
|
||||
it('should return current active submission form section', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('a', {
|
||||
a: subState.objects[826]
|
||||
@@ -396,7 +494,9 @@ describe('SubmissionService test suite', () => {
|
||||
expect(result).toBeObservable(expected);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionSections', () => {
|
||||
it('should return submission form sections', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('a|', {
|
||||
a: subState.objects[826]
|
||||
@@ -484,7 +584,9 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getDisabledSectionsList', () => {
|
||||
it('should return list of submission disabled sections', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a|', {
|
||||
a: subState.objects[826]
|
||||
@@ -516,7 +618,95 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionObjectLinkName', () => {
|
||||
it('should return properly submission link name', () => {
|
||||
let expected = 'workspaceitems';
|
||||
router.setRoute('/workspaceitems/826/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'workspaceitems';
|
||||
router.setRoute('/submit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'workflowitems';
|
||||
router.setRoute('/workflowitems/826/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'edititems';
|
||||
router.setRoute('/items/9e79b1f2-ae0f-4737-9a4b-990952a8857c/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionScope', () => {
|
||||
it('should return properly submission scope', () => {
|
||||
let expected = SubmissionScopeType.WorkspaceItem;
|
||||
|
||||
router.setRoute('/workspaceitems/826/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
router.setRoute('/submit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
expected = SubmissionScopeType.WorkflowItem;
|
||||
router.setRoute('/workflowitems/826/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
expected = SubmissionScopeType.EditItem;
|
||||
router.setRoute('/items/9e79b1f2-ae0f-4737-9a4b-990952a8857c/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionStatus', () => {
|
||||
it('should return properly submission status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a-b', {
|
||||
a: subState,
|
||||
b: validSubState
|
||||
}));
|
||||
const result = service.getSubmissionStatus('826');
|
||||
const expected = cold('cc-d', {
|
||||
c: false,
|
||||
d: true
|
||||
});
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionSaveProcessingStatus', () => {
|
||||
it('should return submission save processing status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a', {
|
||||
a: subState.objects[826]
|
||||
}));
|
||||
|
||||
const result = service.getSubmissionSaveProcessingStatus('826');
|
||||
const expected = cold('bb', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSubmissionDepositProcessingStatus', () => {
|
||||
it('should return submission deposit processing status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a', {
|
||||
a: subState.objects[826]
|
||||
}));
|
||||
|
||||
const result = service.getSubmissionDepositProcessingStatus('826');
|
||||
const expected = cold('bb', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSectionHidden', () => {
|
||||
it('should return true/false when section is hidden/visible', () => {
|
||||
let section: any = {
|
||||
config: '',
|
||||
@@ -550,83 +740,42 @@ describe('SubmissionService test suite', () => {
|
||||
};
|
||||
expect(service.isSectionHidden(section)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return properly submission link name', () => {
|
||||
let expected = 'workspaceitems';
|
||||
router.setRoute('/workspaceitems/826/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'workspaceitems';
|
||||
router.setRoute('/submit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'workflowitems';
|
||||
router.setRoute('/workflowitems/826/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
|
||||
expected = 'edititems';
|
||||
router.setRoute('/items/9e79b1f2-ae0f-4737-9a4b-990952a8857c/edit');
|
||||
expect(service.getSubmissionObjectLinkName()).toBe(expected);
|
||||
});
|
||||
|
||||
it('should return properly submission scope', () => {
|
||||
let expected = SubmissionScopeType.WorkspaceItem;
|
||||
describe('isSubmissionLoading', () => {
|
||||
it('should return true/false when section is loading/not loading', () => {
|
||||
const spy = spyOn(service, 'getSubmissionObject').and.returnValue(observableOf({isLoading: true}));
|
||||
|
||||
router.setRoute('/workspaceitems/826/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
router.setRoute('/submit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
expected = SubmissionScopeType.WorkflowItem;
|
||||
router.setRoute('/workflowitems/826/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
|
||||
expected = SubmissionScopeType.EditItem;
|
||||
router.setRoute('/items/9e79b1f2-ae0f-4737-9a4b-990952a8857c/edit');
|
||||
expect(service.getSubmissionScope()).toBe(expected);
|
||||
let expected = cold('(b|)', {
|
||||
b: true
|
||||
});
|
||||
|
||||
it('should return properly submission status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a-b', {
|
||||
a: subState,
|
||||
b: validSubState
|
||||
}));
|
||||
const result = service.getSubmissionStatus('826');
|
||||
const expected = cold('cc-d', {
|
||||
c: false,
|
||||
d: true
|
||||
});
|
||||
expect(service.isSubmissionLoading(submissionId)).toBeObservable(expected);
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
spy.and.returnValue(observableOf({isLoading: false}));
|
||||
|
||||
it('should return submission save processing status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a', {
|
||||
a: subState.objects[826]
|
||||
}));
|
||||
|
||||
const result = service.getSubmissionSaveProcessingStatus('826');
|
||||
const expected = cold('bb', {
|
||||
expected = cold('(b|)', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
expect(service.isSubmissionLoading(submissionId)).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return submission deposit processing status', () => {
|
||||
spyOn((service as any).store, 'select').and.returnValue(hot('-a', {
|
||||
a: subState.objects[826]
|
||||
describe('notifyNewSection', () => {
|
||||
it('should return true/false when section is loading/not loading', fakeAsync(() => {
|
||||
const spy = spyOn((service as any).translate, 'get').and.returnValue(observableOf('test'));
|
||||
|
||||
spyOn((service as any).notificationsService, 'info').and.callThrough();
|
||||
|
||||
service.notifyNewSection(submissionId, sectionId);
|
||||
flush();
|
||||
|
||||
expect((service as any).notificationsService.info).toHaveBeenCalledWith(null, 'test', null, true);
|
||||
}));
|
||||
|
||||
const result = service.getSubmissionDepositProcessingStatus('826');
|
||||
const expected = cold('bb', {
|
||||
b: false
|
||||
});
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
describe('redirectToMyDSpace', () => {
|
||||
it('should redirect to MyDspace page', () => {
|
||||
const spy = spyOn((service as any).routeService, 'getPreviousUrl');
|
||||
|
||||
@@ -640,7 +789,39 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect((service as any).router.navigate).toHaveBeenCalledWith(['/mydspace']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resetAllSubmissionObjects', () => {
|
||||
it('should dispatch a new CancelSubmissionFormAction', () => {
|
||||
service.resetAllSubmissionObjects();
|
||||
const expected = new CancelSubmissionFormAction();
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resetSubmissionObject', () => {
|
||||
it('should dispatch a new ResetSubmissionFormAction', () => {
|
||||
service.resetSubmissionObject(
|
||||
collectionId,
|
||||
submissionId,
|
||||
selfUrl,
|
||||
submissionDefinition,
|
||||
{}
|
||||
);
|
||||
const expected = new ResetSubmissionFormAction(
|
||||
collectionId,
|
||||
submissionId,
|
||||
selfUrl,
|
||||
{},
|
||||
submissionDefinition
|
||||
);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('retrieveSubmission', () => {
|
||||
it('should retrieve submission from REST endpoint', () => {
|
||||
(service as any).restService.getDataById.and.returnValue(hot('a|', {
|
||||
a: submissionRestResponse
|
||||
@@ -653,10 +834,20 @@ describe('SubmissionService test suite', () => {
|
||||
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setActiveSection', () => {
|
||||
it('should dispatch a new SetActiveSectionAction', () => {
|
||||
service.setActiveSection(submissionId, sectionId);
|
||||
const expected = new SetActiveSectionAction(submissionId, sectionId);
|
||||
|
||||
expect((service as any).store.dispatch).toHaveBeenCalledWith(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('startAutoSave', () => {
|
||||
it('should start Auto Save', fakeAsync(() => {
|
||||
const duration = config.submission.autosave.timer * (1000 * 60);
|
||||
spyOn((service as any).store, 'dispatch');
|
||||
|
||||
service.startAutoSave('826');
|
||||
const sub = (service as any).timerObs.subscribe();
|
||||
@@ -670,7 +861,9 @@ describe('SubmissionService test suite', () => {
|
||||
sub.unsubscribe();
|
||||
(service as any).autoSaveSub.unsubscribe();
|
||||
}));
|
||||
});
|
||||
|
||||
describe('stopAutoSave', () => {
|
||||
it('should stop Auto Save', () => {
|
||||
service.startAutoSave('826');
|
||||
service.stopAutoSave();
|
||||
@@ -678,3 +871,4 @@ describe('SubmissionService test suite', () => {
|
||||
expect((service as any).autoSaveSub).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -6,7 +6,6 @@ import { Observable, of as observableOf, Subscription, timer as observableTimer
|
||||
import { catchError, distinctUntilChanged, filter, first, map, startWith } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to';
|
||||
|
||||
import { submissionSelector, SubmissionState } from './submission.reducers';
|
||||
import { hasValue, isEmpty, isNotUndefined } from '../shared/empty.util';
|
||||
@@ -18,7 +17,7 @@ import {
|
||||
ResetSubmissionFormAction,
|
||||
SaveAndDepositSubmissionAction,
|
||||
SaveForLaterSubmissionFormAction,
|
||||
SaveSubmissionFormAction,
|
||||
SaveSubmissionFormAction, SaveSubmissionSectionFormAction,
|
||||
SetActiveSectionAction
|
||||
} from './objects/submission-objects.actions';
|
||||
import {
|
||||
@@ -52,7 +51,6 @@ export class SubmissionService {
|
||||
protected restService: SubmissionRestService,
|
||||
protected router: Router,
|
||||
protected routeService: RouteService,
|
||||
protected scrollToService: ScrollToService,
|
||||
protected store: Store<SubmissionState>,
|
||||
protected translate: TranslateService) {
|
||||
}
|
||||
@@ -106,7 +104,7 @@ export class SubmissionService {
|
||||
}
|
||||
|
||||
dispatchSaveSection(submissionId, sectionId) {
|
||||
this.store.dispatch(new SaveSubmissionFormAction(submissionId));
|
||||
this.store.dispatch(new SaveSubmissionSectionFormAction(submissionId, sectionId));
|
||||
}
|
||||
|
||||
getActiveSectionId(submissionId: string): Observable<string> {
|
||||
|
Reference in New Issue
Block a user