mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 03:23:07 +00:00
Added more tests
This commit is contained in:
@@ -9,6 +9,13 @@ describe('RowParser test suite', () => {
|
|||||||
let row1: FormRowModel;
|
let row1: FormRowModel;
|
||||||
let row2: FormRowModel;
|
let row2: FormRowModel;
|
||||||
let row3: FormRowModel;
|
let row3: FormRowModel;
|
||||||
|
let row4: FormRowModel;
|
||||||
|
let row5: FormRowModel;
|
||||||
|
let row6: FormRowModel;
|
||||||
|
let row7: FormRowModel;
|
||||||
|
let row8: FormRowModel;
|
||||||
|
let row9: FormRowModel;
|
||||||
|
let row10: FormRowModel;
|
||||||
|
|
||||||
const scopeUUID = 'testScopeUUID';
|
const scopeUUID = 'testScopeUUID';
|
||||||
const initFormValues = {};
|
const initFormValues = {};
|
||||||
@@ -77,9 +84,10 @@ describe('RowParser test suite', () => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
languageCodes: []
|
languageCodes: []
|
||||||
}
|
} as FormFieldModel
|
||||||
]
|
]
|
||||||
} as FormRowModel;
|
} as FormRowModel;
|
||||||
|
|
||||||
row3 = {
|
row3 = {
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
@@ -96,7 +104,7 @@ describe('RowParser test suite', () => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
languageCodes: []
|
languageCodes: []
|
||||||
},
|
} as FormFieldModel,
|
||||||
{
|
{
|
||||||
input: {type: 'onebox'},
|
input: {type: 'onebox'},
|
||||||
label: 'Other title',
|
label: 'Other title',
|
||||||
@@ -112,14 +120,248 @@ describe('RowParser test suite', () => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
languageCodes: []
|
languageCodes: []
|
||||||
}
|
} as FormFieldModel
|
||||||
]
|
]
|
||||||
} as FormRowModel;
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row4 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'dropdown'
|
||||||
|
},
|
||||||
|
label: 'Type',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Select the tyupe.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'type',
|
||||||
|
authority: 'common_types_dataset',
|
||||||
|
closed: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel,
|
||||||
|
{
|
||||||
|
input: {type: 'series'},
|
||||||
|
label: 'Series/Report No.',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Enter the series and number assigned to this item by your community.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'series',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row5 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'lookup-name'
|
||||||
|
},
|
||||||
|
label: 'Author',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Enter the name of the author.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'author',
|
||||||
|
authority: 'RPAuthority',
|
||||||
|
closed: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row6 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'list'
|
||||||
|
},
|
||||||
|
label: 'Type',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: true,
|
||||||
|
hints: 'Select the type.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'type',
|
||||||
|
authority: 'type_programme',
|
||||||
|
closed: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row7 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'date'
|
||||||
|
},
|
||||||
|
label: 'Date of Issue.',
|
||||||
|
mandatory: 'true',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Please give the date of previous publication or public distribution. You can leave out the day and/or month if they aren\'t applicable.',
|
||||||
|
mandatoryMessage: 'You must enter at least the year.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'date',
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row8 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'tag'
|
||||||
|
},
|
||||||
|
label: 'Keywords',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Local controlled vocabulary.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'subject',
|
||||||
|
authority: 'JOURNALAuthority',
|
||||||
|
closed: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row9 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'textarea'
|
||||||
|
},
|
||||||
|
label: 'Description',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Enter a description.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'description'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
|
|
||||||
|
row10 = {
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'group'
|
||||||
|
},
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'onebox'
|
||||||
|
},
|
||||||
|
label: 'Author',
|
||||||
|
mandatory: 'false',
|
||||||
|
repeatable: false,
|
||||||
|
hints: 'Enter the name of the author.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'author'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: {
|
||||||
|
type: 'onebox'
|
||||||
|
},
|
||||||
|
label: 'Affiliation',
|
||||||
|
mandatory: false,
|
||||||
|
repeatable: true,
|
||||||
|
hints: 'Enter the affiliation of the author.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'affiliation'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
label: 'Authors',
|
||||||
|
mandatory: 'true',
|
||||||
|
repeatable: false,
|
||||||
|
mandatoryMessage: 'Entering at least the first author is mandatory.',
|
||||||
|
hints: 'Enter the names of the authors of this item.',
|
||||||
|
selectableMetadata: [
|
||||||
|
{
|
||||||
|
metadata: 'author'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
languageCodes: []
|
||||||
|
} as FormFieldModel
|
||||||
|
]
|
||||||
|
} as FormRowModel;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init parser properly', () => {
|
it('should init parser properly', () => {
|
||||||
const parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly);
|
let parser = new RowParser(row1, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row2, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row3, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row4, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row5, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row6, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row7, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row8, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row9, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
|
|
||||||
|
parser = new RowParser(row10, scopeUUID, initFormValues, submissionScope, readOnly);
|
||||||
|
|
||||||
expect(parser instanceof RowParser).toBe(true);
|
expect(parser instanceof RowParser).toBe(true);
|
||||||
});
|
});
|
||||||
|
@@ -1,13 +1,16 @@
|
|||||||
// Load the implementations that should be tested
|
|
||||||
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { ChangeDetectorRef, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing';
|
import { async, ComponentFixture, inject, TestBed, } from '@angular/core/testing';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
|
||||||
import 'rxjs/add/observable/of';
|
import 'rxjs/add/observable/of';
|
||||||
import { DynamicFormControlModel, DynamicFormValidationService, DynamicInputModel } from '@ng-dynamic-forms/core';
|
import {
|
||||||
|
DynamicFormArrayModel,
|
||||||
|
DynamicFormControlEvent,
|
||||||
|
DynamicFormControlModel,
|
||||||
|
DynamicFormValidationService,
|
||||||
|
DynamicInputModel
|
||||||
|
} from '@ng-dynamic-forms/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
@@ -16,6 +19,9 @@ import { FormComponent } from './form.component';
|
|||||||
import { FormService } from './form.service';
|
import { FormService } from './form.service';
|
||||||
import { FormBuilderService } from './builder/form-builder.service';
|
import { FormBuilderService } from './builder/form-builder.service';
|
||||||
import { FormState } from './form.reducers';
|
import { FormState } from './form.reducers';
|
||||||
|
import { FormChangeAction, FormStatusChangeAction } from './form.actions';
|
||||||
|
import { MockStore } from '../testing/mock-store';
|
||||||
|
import { FormFieldMetadataValueObject } from './builder/models/form-field-metadata-value.model';
|
||||||
|
|
||||||
function createTestComponent<T>(html: string, type: { new(...args: any[]): T }): ComponentFixture<T> {
|
function createTestComponent<T>(html: string, type: { new(...args: any[]): T }): ComponentFixture<T> {
|
||||||
TestBed.overrideComponent(type, {
|
TestBed.overrideComponent(type, {
|
||||||
@@ -76,33 +82,47 @@ export const TEST_FORM_MODEL = [
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
export const TEST_FORM_GROUP = {
|
export const TEST_FORM_MODEL_WITH_ARRAY = [
|
||||||
dc_title: new FormControl(),
|
new DynamicFormArrayModel({
|
||||||
dc_title_alternative: new FormControl(),
|
|
||||||
dc_publisher: new FormControl(),
|
|
||||||
dc_identifier_citation: new FormControl(),
|
|
||||||
dc_identifier_issn: new FormControl()
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Form component', () => {
|
id: 'bootstrapFormArray',
|
||||||
|
initialCount: 1,
|
||||||
|
label: 'Form Array',
|
||||||
|
groupFactory: () => {
|
||||||
|
return [
|
||||||
|
new DynamicInputModel({
|
||||||
|
|
||||||
|
id: 'bootstrapArrayGroupInput',
|
||||||
|
placeholder: 'example array group input',
|
||||||
|
readOnly: false
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('FormComponent test suite', () => {
|
||||||
|
|
||||||
let testComp: TestComponent;
|
let testComp: TestComponent;
|
||||||
|
let formComp: FormComponent;
|
||||||
let testFixture: ComponentFixture<TestComponent>;
|
let testFixture: ComponentFixture<TestComponent>;
|
||||||
|
let formFixture: ComponentFixture<FormComponent>;
|
||||||
|
const formState: FormState = {
|
||||||
|
testForm: {
|
||||||
|
data: {
|
||||||
|
dc_title: null,
|
||||||
|
dc_title_alternative: null,
|
||||||
|
dc_publisher: null,
|
||||||
|
dc_identifier_citation: null,
|
||||||
|
dc_identifier_issn: null
|
||||||
|
},
|
||||||
|
valid: false,
|
||||||
|
errors: []
|
||||||
|
}
|
||||||
|
};
|
||||||
let html;
|
let html;
|
||||||
const formServiceStub = {
|
|
||||||
getFormData: (formId) => Observable.of([])
|
|
||||||
}
|
|
||||||
const formBuilderServiceStub = {
|
|
||||||
createFormGroup: (formModel) => new FormGroup(TEST_FORM_GROUP)
|
|
||||||
}
|
|
||||||
const submissionFormsConfigServiceStub = {};
|
|
||||||
|
|
||||||
const store: Store<FormState> = jasmine.createSpyObj('store', {
|
const store: MockStore<FormState> = new MockStore<FormState>(formState);
|
||||||
/* tslint:disable:no-empty */
|
|
||||||
dispatch: {},
|
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
select: Observable.of({})
|
|
||||||
});
|
|
||||||
|
|
||||||
// async beforeEach
|
// async beforeEach
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
@@ -135,6 +155,7 @@ describe('Form component', () => {
|
|||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
// synchronous beforeEach
|
// synchronous beforeEach
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
html = `
|
html = `
|
||||||
@@ -147,11 +168,252 @@ describe('Form component', () => {
|
|||||||
testComp = testFixture.componentInstance;
|
testComp = testFixture.componentInstance;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create Form Component', inject([FormComponent], (app: FormComponent) => {
|
it('should create FormComponent', inject([FormComponent], (app: FormComponent) => {
|
||||||
|
|
||||||
expect(app).toBeDefined();
|
expect(app).toBeDefined();
|
||||||
}));
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
formFixture = TestBed.createComponent(FormComponent);
|
||||||
|
formComp = formFixture.componentInstance; // FormComponent test instance
|
||||||
|
formComp.formId = 'testForm';
|
||||||
|
formComp.formModel = TEST_FORM_MODEL;
|
||||||
|
formComp.displaySubmit = false;
|
||||||
|
formFixture.detectChanges();
|
||||||
|
spyOn(store, 'dispatch');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
formFixture.destroy();
|
||||||
|
formComp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch a FormStatusChangeAction when Form group status changes', () => {
|
||||||
|
const control = formComp.formGroup.get(['dc_title']);
|
||||||
|
control.setValue('Test Title');
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(new FormStatusChangeAction('testForm', formComp.formGroup.valid));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display form errors when errors are added to the state', () => {
|
||||||
|
const errors = [{
|
||||||
|
fieldId: 'dc_title',
|
||||||
|
message: 'error.validation.required'
|
||||||
|
}];
|
||||||
|
|
||||||
|
formState.testForm.errors = errors;
|
||||||
|
store.nextState(formState);
|
||||||
|
formFixture.detectChanges();
|
||||||
|
|
||||||
|
expect((formComp as any).formErrors).toEqual(errors);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove form errors when errors are empty in the state', () => {
|
||||||
|
(formComp as any).formErrors = [{
|
||||||
|
fieldId: 'dc_title',
|
||||||
|
message: 'error.validation.required'
|
||||||
|
}];
|
||||||
|
const errors = [];
|
||||||
|
|
||||||
|
formState.testForm.errors = errors;
|
||||||
|
store.nextState(formState);
|
||||||
|
formFixture.detectChanges();
|
||||||
|
|
||||||
|
expect((formComp as any).formErrors).toEqual(errors);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should dispatch FormChangeAction on form change', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
const event = {
|
||||||
|
$event: new FormFieldMetadataValueObject('Test Title'),
|
||||||
|
context: null,
|
||||||
|
control: formComp.formGroup.get('dc_title'),
|
||||||
|
group: formComp.formGroup,
|
||||||
|
model: formComp.formModel[0],
|
||||||
|
type: 'change'
|
||||||
|
} as DynamicFormControlEvent;
|
||||||
|
|
||||||
|
spyOn(formComp.change, 'emit');
|
||||||
|
|
||||||
|
formComp.onChange(event);
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testForm', service.getValueFromModel(formComp.formModel)));
|
||||||
|
expect(formComp.change.emit).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit change on form change', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
const event = {
|
||||||
|
$event: new FormFieldMetadataValueObject('Test Title'),
|
||||||
|
context: null,
|
||||||
|
control: formComp.formGroup.get('dc_title'),
|
||||||
|
group: formComp.formGroup,
|
||||||
|
model: formComp.formModel[0],
|
||||||
|
type: 'change'
|
||||||
|
} as DynamicFormControlEvent;
|
||||||
|
|
||||||
|
spyOn(formComp.change, 'emit');
|
||||||
|
|
||||||
|
formComp.onChange(event);
|
||||||
|
|
||||||
|
expect(formComp.change.emit).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not emit change Event on form change when emitChange is false', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
const event = {
|
||||||
|
$event: new FormFieldMetadataValueObject('Test Title'),
|
||||||
|
context: null,
|
||||||
|
control: formComp.formGroup.get('dc_title'),
|
||||||
|
group: formComp.formGroup,
|
||||||
|
model: formComp.formModel[0],
|
||||||
|
type: 'change'
|
||||||
|
} as DynamicFormControlEvent;
|
||||||
|
|
||||||
|
formComp.emitChange = false;
|
||||||
|
spyOn(formComp.change, 'emit');
|
||||||
|
|
||||||
|
formComp.onChange(event);
|
||||||
|
|
||||||
|
expect(formComp.change.emit).not.toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit blur Event on blur', () => {
|
||||||
|
const event = {
|
||||||
|
$event: new FocusEvent('blur'),
|
||||||
|
context: null,
|
||||||
|
control: formComp.formGroup.get('dc_title'),
|
||||||
|
group: formComp.formGroup,
|
||||||
|
model: formComp.formModel[0],
|
||||||
|
type: 'blur'
|
||||||
|
} as DynamicFormControlEvent;
|
||||||
|
|
||||||
|
spyOn(formComp.blur, 'emit');
|
||||||
|
|
||||||
|
formComp.onBlur(event);
|
||||||
|
|
||||||
|
expect(formComp.blur.emit).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit focus Event on focus', () => {
|
||||||
|
const event = {
|
||||||
|
$event: new FocusEvent('focus'),
|
||||||
|
context: null,
|
||||||
|
control: formComp.formGroup.get('dc_title'),
|
||||||
|
group: formComp.formGroup,
|
||||||
|
model: formComp.formModel[0],
|
||||||
|
type: 'focus'
|
||||||
|
} as DynamicFormControlEvent;
|
||||||
|
|
||||||
|
spyOn(formComp.focus, 'emit');
|
||||||
|
|
||||||
|
formComp.onFocus(event);
|
||||||
|
|
||||||
|
expect(formComp.focus.emit).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return Observable of form status', () => {
|
||||||
|
|
||||||
|
const control = formComp.formGroup.get(['dc_title']);
|
||||||
|
control.setValue('Test Title');
|
||||||
|
formState.testForm.valid = true;
|
||||||
|
store.nextState(formState);
|
||||||
|
formFixture.detectChanges();
|
||||||
|
|
||||||
|
formComp.isValid().subscribe((valid) => {
|
||||||
|
expect(valid).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit submit Event on form submit whether the form is valid', () => {
|
||||||
|
|
||||||
|
const control = formComp.formGroup.get(['dc_title']);
|
||||||
|
control.setValue('Test Title');
|
||||||
|
formState.testForm.valid = true;
|
||||||
|
spyOn(formComp.submit, 'emit');
|
||||||
|
|
||||||
|
store.nextState(formState);
|
||||||
|
formFixture.detectChanges();
|
||||||
|
|
||||||
|
formComp.onSubmit();
|
||||||
|
expect(formComp.submit.emit).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not emit submit Event on form submit whether the form is not valid', () => {
|
||||||
|
|
||||||
|
spyOn((formComp as any).formService, 'validateAllFormFields');
|
||||||
|
|
||||||
|
store.nextState(formState);
|
||||||
|
formFixture.detectChanges();
|
||||||
|
|
||||||
|
formComp.onSubmit();
|
||||||
|
expect((formComp as any).formService.validateAllFormFields).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset form group', () => {
|
||||||
|
|
||||||
|
spyOn(formComp.formGroup, 'reset');
|
||||||
|
|
||||||
|
formComp.reset();
|
||||||
|
|
||||||
|
expect(formComp.formGroup.reset).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
|
||||||
|
formFixture = TestBed.createComponent(FormComponent);
|
||||||
|
formComp = formFixture.componentInstance; // FormComponent test instance
|
||||||
|
formComp.formId = 'testFormArray';
|
||||||
|
formComp.formModel = TEST_FORM_MODEL_WITH_ARRAY;
|
||||||
|
formComp.displaySubmit = false;
|
||||||
|
formFixture.detectChanges();
|
||||||
|
spyOn(store, 'dispatch');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
formFixture.destroy();
|
||||||
|
formComp = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return ReadOnly property from array item', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
const readOnly = formComp.isItemReadOnly(formComp.formModel[0] as DynamicFormArrayModel, 0);
|
||||||
|
|
||||||
|
expect(readOnly).toBe(false);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should dispatch FormChangeAction when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit addArrayItem Event when an item has been added to an array', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
spyOn(formComp.addArrayItem, 'emit');
|
||||||
|
|
||||||
|
formComp.insertItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
|
||||||
|
|
||||||
|
expect(formComp.addArrayItem.emit).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should dispatch FormChangeAction when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(new FormChangeAction('testFormArray', service.getValueFromModel(formComp.formModel)));
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should emit removeArrayItem Event when an item has been removed from an array', inject([FormBuilderService], (service: FormBuilderService) => {
|
||||||
|
spyOn(formComp.removeArrayItem, 'emit');
|
||||||
|
|
||||||
|
formComp.removeItem(new Event('click'), formComp.formModel[0] as DynamicFormArrayModel, 1);
|
||||||
|
|
||||||
|
expect(formComp.removeArrayItem.emit).toHaveBeenCalled();
|
||||||
|
}));
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// declare a test component
|
// declare a test component
|
||||||
|
@@ -21,7 +21,7 @@ import {
|
|||||||
import { FormBuilderService } from './builder/form-builder.service';
|
import { FormBuilderService } from './builder/form-builder.service';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { hasValue, isNotNull, isNull } from '../empty.util';
|
import { hasValue, isNotEmpty, isNotNull, isNull } from '../empty.util';
|
||||||
import { FormService } from './form.service';
|
import { FormService } from './form.service';
|
||||||
import { formObjectFromIdSelector } from './selectors';
|
import { formObjectFromIdSelector } from './selectors';
|
||||||
import { FormEntry, FormError } from './form.reducers';
|
import { FormEntry, FormError } from './form.reducers';
|
||||||
@@ -154,7 +154,7 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
this.subs.push(
|
this.subs.push(
|
||||||
this.store.select(formObjectFromIdSelector(this.formId))
|
this.store.select(formObjectFromIdSelector(this.formId))
|
||||||
.filter((formState: FormEntry) => !!formState && !isEmpty(formState.errors))
|
.filter((formState: FormEntry) => !!formState && (isNotEmpty(formState.errors) || isNotEmpty(this.formErrors)))
|
||||||
.map((formState) => formState.errors)
|
.map((formState) => formState.errors)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
// .delay(100) // this terrible delay is here to prevent the detection change error
|
// .delay(100) // this terrible delay is here to prevent the detection change error
|
||||||
@@ -223,7 +223,7 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* Method to keep synchronized form controls values with form state
|
* Method to keep synchronized form controls values with form state
|
||||||
*/
|
*/
|
||||||
private keepSync() {
|
private keepSync(): void {
|
||||||
this.subs.push(this.formService.getFormData(this.formId)
|
this.subs.push(this.formService.getFormData(this.formId)
|
||||||
.subscribe((stateFormData) => {
|
.subscribe((stateFormData) => {
|
||||||
if (!Object.is(stateFormData, this.formGroup.value) && this.formGroup) {
|
if (!Object.is(stateFormData, this.formGroup.value) && this.formGroup) {
|
||||||
@@ -232,15 +232,15 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlur(event) {
|
onBlur(event: DynamicFormControlEvent): void {
|
||||||
this.blur.emit(event);
|
this.blur.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onFocus(event) {
|
onFocus(event: DynamicFormControlEvent): void {
|
||||||
this.focus.emit(event);
|
this.focus.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(event) {
|
onChange(event: DynamicFormControlEvent): void {
|
||||||
const action: FormChangeAction = new FormChangeAction(this.formId, this.formBuilderService.getValueFromModel(this.formModel));
|
const action: FormChangeAction = new FormChangeAction(this.formId, this.formBuilderService.getValueFromModel(this.formModel));
|
||||||
|
|
||||||
this.store.dispatch(action);
|
this.store.dispatch(action);
|
||||||
@@ -260,7 +260,7 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
* Method called on submit.
|
* Method called on submit.
|
||||||
* Emit a new submit Event whether the form is valid, mark fields with error otherwise
|
* Emit a new submit Event whether the form is valid, mark fields with error otherwise
|
||||||
*/
|
*/
|
||||||
onSubmit() {
|
onSubmit(): void {
|
||||||
if (this.getFormGroupValidStatus()) {
|
if (this.getFormGroupValidStatus()) {
|
||||||
this.submit.emit(this.formService.getFormData(this.formId));
|
this.submit.emit(this.formService.getFormData(this.formId));
|
||||||
} else {
|
} else {
|
||||||
@@ -271,7 +271,7 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* Method to reset form fields
|
* Method to reset form fields
|
||||||
*/
|
*/
|
||||||
reset() {
|
reset(): void {
|
||||||
this.formGroup.reset();
|
this.formGroup.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,14 +281,14 @@ export class FormComponent implements OnDestroy, OnInit {
|
|||||||
return model.readOnly;
|
return model.readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeItem($event, arrayContext: DynamicFormArrayModel, index: number) {
|
removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void {
|
||||||
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray;
|
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray;
|
||||||
this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove'));
|
this.removeArrayItem.emit(this.getEvent($event, arrayContext, index, 'remove'));
|
||||||
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
|
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
|
||||||
this.store.dispatch(new FormChangeAction(this.formId, this.formBuilderService.getValueFromModel(this.formModel)));
|
this.store.dispatch(new FormChangeAction(this.formId, this.formBuilderService.getValueFromModel(this.formModel)));
|
||||||
}
|
}
|
||||||
|
|
||||||
insertItem($event, arrayContext: DynamicFormArrayModel, index: number) {
|
insertItem($event, arrayContext: DynamicFormArrayModel, index: number): void {
|
||||||
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray;
|
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as FormArray;
|
||||||
this.formBuilderService.insertFormArrayGroup(index, formArrayControl, arrayContext);
|
this.formBuilderService.insertFormArrayGroup(index, formArrayControl, arrayContext);
|
||||||
this.addArrayItem.emit(this.getEvent($event, arrayContext, index, 'add'));
|
this.addArrayItem.emit(this.getEvent($event, arrayContext, index, 'add'));
|
||||||
|
@@ -9,12 +9,13 @@ export class MockStore<T> extends BehaviorSubject<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dispatch = (action: Action): void => {
|
dispatch = (action: Action): void => {
|
||||||
console.info();
|
// console.info(action);
|
||||||
}
|
};
|
||||||
|
|
||||||
select = <R>(pathOrMapFn: any): Observable<T> => {
|
select = <R>(pathOrMapFn: any): Observable<T> => {
|
||||||
return Observable.of(this.getValue());
|
return this.asObservable()
|
||||||
}
|
.map((value) => pathOrMapFn.projector(value))
|
||||||
|
};
|
||||||
|
|
||||||
nextState(_newState: T) {
|
nextState(_newState: T) {
|
||||||
this.next(_newState);
|
this.next(_newState);
|
||||||
|
Reference in New Issue
Block a user