diff --git a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts new file mode 100644 index 0000000000..aef4797676 --- /dev/null +++ b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts @@ -0,0 +1,47 @@ +import { FormFieldModel } from '../models/form-field.model'; +import { DynamicConcatModel } from '../ds-dynamic-form-ui/models/ds-dynamic-concat.model'; +import { SeriesFieldParser } from './series-field-parser'; +import { DateFieldParser } from './date-field-parser'; +import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model'; + +describe('DateFieldParser test suite', () => { + let field: FormFieldModel; + + const initFormValues = {}; + const readOnly = false; + + beforeEach(() => { + field = { + 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; + + }); + + it('should init parser properly', () => { + const parser = new DateFieldParser(field, initFormValues, readOnly); + + expect(parser instanceof DateFieldParser).toBe(true); + }); + + it('should return a DynamicDsDatePickerModel object', () => { + const parser = new DateFieldParser(field, initFormValues, readOnly); + + const fieldModel = parser.parse(); + + expect(fieldModel instanceof DynamicDsDatePickerModel).toBe(true); + }); + +}); diff --git a/src/app/shared/form/builder/parsers/date-field-parser.ts b/src/app/shared/form/builder/parsers/date-field-parser.ts index 6ad244f298..2c997211f1 100644 --- a/src/app/shared/form/builder/parsers/date-field-parser.ts +++ b/src/app/shared/form/builder/parsers/date-field-parser.ts @@ -1,6 +1,5 @@ import { FieldParser } from './field-parser'; import { DynamicDatePickerModelConfig } from '@ng-dynamic-forms/core'; -import { FormFieldModel } from '../models/form-field.model'; import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model'; import { isNotEmpty } from '../../../empty.util'; import { DS_DATE_PICKER_SEPARATOR } from '../ds-dynamic-form-ui/models/date-picker/date-picker.component'; diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts new file mode 100644 index 0000000000..700c824051 --- /dev/null +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts @@ -0,0 +1,55 @@ +import { FormFieldModel } from '../models/form-field.model'; +import { DropdownFieldParser } from './dropdown-field-parser'; +import { DynamicScrollableDropdownModel } from '../ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model'; + +describe('DropdownFieldParser test suite', () => { + let field: FormFieldModel; + + const authorityUuid = 'testScopeUUID'; + const initFormValues = {}; + const readOnly = false; + + beforeEach(() => { + field = { + 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; + + }); + + it('should init parser properly', () => { + const parser = new DropdownFieldParser(field, initFormValues, readOnly, authorityUuid); + + expect(parser instanceof DropdownFieldParser).toBe(true); + }); + + it('should return a DynamicScrollableDropdownModel object', () => { + const parser = new DropdownFieldParser(field, initFormValues, readOnly, authorityUuid); + + const fieldModel = parser.parse(); + + expect(fieldModel instanceof DynamicScrollableDropdownModel).toBe(true); + }); + + it('should throw when authority is not passed', () => { + field.selectableMetadata[0].authority = null; + const parser = new DropdownFieldParser(field, initFormValues, readOnly, authorityUuid); + + expect(() => parser.parse()) + .toThrow(); + }); + +}); diff --git a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts index b458929e7c..384ae880dc 100644 --- a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts @@ -1,10 +1,4 @@ import { FormFieldModel } from '../models/form-field.model'; -import { OneboxFieldParser } from './onebox-field-parser'; -import { DynamicQualdropModel } from '../ds-dynamic-form-ui/models/ds-dynamic-qualdrop.model'; -import { DynamicTypeaheadModel } from '../ds-dynamic-form-ui/models/typeahead/dynamic-typeahead.model'; -import { DsDynamicInputModel } from '../ds-dynamic-form-ui/models/ds-dynamic-input.model'; -import { ConcatFieldParser } from './concat-field-parser'; -import { NameFieldParser } from './name-field-parser'; import { DynamicConcatModel } from '../ds-dynamic-form-ui/models/ds-dynamic-concat.model'; import { SeriesFieldParser } from './series-field-parser'; diff --git a/src/app/shared/form/form.service.spec.ts b/src/app/shared/form/form.service.spec.ts index b72bbbd0d6..7155743764 100644 --- a/src/app/shared/form/form.service.spec.ts +++ b/src/app/shared/form/form.service.spec.ts @@ -1,21 +1,45 @@ import { Store, StoreModule } from '@ngrx/store'; import { async, inject, TestBed } from '@angular/core/testing'; -import 'rxjs/add/observable/of'; +import { FormGroup } from '@angular/forms'; + +import { + DynamicFormControlModel, + DynamicFormService, + DynamicFormValidationService, + DynamicInputModel +} from '@ng-dynamic-forms/core'; + import { FormService } from './form.service'; import { FormBuilderService } from './builder/form-builder.service'; import { AppState } from '../../app.reducer'; -import { DynamicPathable } from '@ng-dynamic-forms/core/src/model/misc/dynamic-form-control-path.model'; -import { DynamicFormControlModel } from '@ng-dynamic-forms/core'; import { formReducer } from './form.reducers'; -describe('FormService', () => { +describe('FormService test suite', () => { const formId = 'testForm'; let service: FormService; + let builderService: FormBuilderService; + let formGroup: FormGroup; + + const formModel: DynamicFormControlModel[] = [ + new DynamicInputModel({id: 'author', value: 'test'}), + new DynamicInputModel({ + id: 'title', + validators: { + required: null + }, + errorMessages: { + required: 'Title is required' + } + }), + new DynamicInputModel({id: 'date'}), + new DynamicInputModel({id: 'description'}), + ]; + const formData = { - 'dc.contributor.author': null, - 'dc.title': ['test'], - 'dc.date.issued': null, - 'dc.description': null + author: ['test'], + title: null, + date: null, + description: null }; const formState = { testForm: { @@ -25,31 +49,27 @@ describe('FormService', () => { } }; - const formBuilderServiceStub: any = { - getPath: (model: DynamicPathable) => [], - /* tslint:disable:no-empty */ - clearAllModelsValue: (groupModel: DynamicFormControlModel[]) => { - } - /* tslint:enable:no-empty */ - }; - beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ StoreModule.forRoot({formReducer}) ], providers: [ - {provide: FormBuilderService, useValue: formBuilderServiceStub}, + DynamicFormService, + DynamicFormValidationService, + FormBuilderService, ] }).compileComponents(); })); - beforeEach(inject([Store], (store: Store) => { + beforeEach(inject([Store, FormBuilderService], (store: Store, formBuilderService: FormBuilderService) => { store .subscribe((state) => { state.forms = formState; }); - service = new FormService(formBuilderServiceStub, store); + builderService = formBuilderService; + formGroup = builderService.createFormGroup(formModel); + service = new FormService(formBuilderService, store); })); it('should check whether form state is init', () => { @@ -70,4 +90,54 @@ describe('FormService', () => { }); }); + it('should return form unique id', () => { + const formId1 = service.getUniqueId(formId); + const formId2 = service.getUniqueId(formId); + + expect(formId1).not.toEqual(formId2); + }); + + it('should validate all form fields', () => { + service.validateAllFormFields(formGroup); + + expect(formGroup.controls.author.touched).toBe(true); + expect(formGroup.controls.author.status).toBe('VALID'); + + expect(formGroup.controls.title.touched).toBe(true); + expect(formGroup.controls.title.status).toBe('INVALID'); + + expect(formGroup.controls.date.touched).toBe(true); + + expect(formGroup.controls.description.touched).toBe(true); + }); + + it('should add error to field', () => { + const control = builderService.getFormControlById('description', formGroup, formModel); + const model = builderService.findById('description', formModel); + + service.addErrorToField(control, model, 'Test error message'); + const errorKeys = Object.keys(control.errors); + + expect(errorKeys.length).toBe(1); + + expect(control.hasError(errorKeys[0])).toBe(true); + + expect(formGroup.controls.description.touched).toBe(true); + }); + + it('should remove error from field', () => { + const control = builderService.getFormControlById('description', formGroup, formModel); + const model = builderService.findById('description', formModel); + + service.addErrorToField(control, model, 'Test error message'); + const errorKeys = Object.keys(control.errors); + + service.removeErrorFromField(control, model, errorKeys[0]); + + expect(errorKeys.length).toBe(1); + + expect(control.hasError(errorKeys[0])).toBe(false); + + expect(formGroup.controls.description.touched).toBe(false); + }); }); diff --git a/src/app/shared/form/form.service.ts b/src/app/shared/form/form.service.ts index f13bae1532..823b00d69b 100644 --- a/src/app/shared/form/form.service.ts +++ b/src/app/shared/form/form.service.ts @@ -65,15 +65,6 @@ export class FormService { }); } - public setValue(formGroup: FormGroup, fieldModel: DynamicFormControlModel, fieldId: string, value: any) { - if (isNotEmpty(fieldModel)) { - const path = this.formBuilderService.getPath(fieldModel); - const fieldControl = formGroup.get(path); - fieldControl.markAsDirty(); - fieldControl.setValue(value); - } - } - public addErrorToField(field: AbstractControl, model: DynamicFormControlModel, message: string) { const error = {}; // create the error object @@ -104,15 +95,20 @@ export class FormService { field.markAsTouched(); } - public removeErrorFromField(field: AbstractControl, model: DynamicFormControlModel, message) { + public removeErrorFromField(field: AbstractControl, model: DynamicFormControlModel, messageKey: string) { const error = {}; - // Use correct error messages from the model - const lastArray = message.split('.'); - if (lastArray && lastArray.length > 0) { - const last = lastArray[lastArray.length - 1]; - error[last] = null; + if (messageKey.includes('.')) { + // Use correct error messages from the model + const lastArray = messageKey.split('.'); + if (lastArray && lastArray.length > 0) { + const last = lastArray[lastArray.length - 1]; + error[last] = null; + } + } else { + error[messageKey] = null; } + field.setErrors(error); field.markAsUntouched(); }