Added more tests

This commit is contained in:
Giuseppe Digilio
2018-06-18 12:54:12 +02:00
parent b371bdff44
commit 4a2e2b754b
13 changed files with 298 additions and 29 deletions

View File

@@ -0,0 +1,277 @@
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement, SimpleChange } from '@angular/core';
import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TextMaskModule } from 'angular2-text-mask';
import {
DynamicCheckboxGroupModel,
DynamicCheckboxModel,
DynamicColorPickerModel,
DynamicDatePickerModel,
DynamicEditorModel,
DynamicFileUploadModel,
DynamicFormArrayModel,
DynamicFormControlModel,
DynamicFormGroupModel,
DynamicFormsCoreModule,
DynamicFormService,
DynamicInputModel,
DynamicRadioGroupModel,
DynamicRatingModel,
DynamicSelectModel,
DynamicSliderModel,
DynamicSwitchModel,
DynamicTextAreaModel,
DynamicTimePickerModel
} from '@ng-dynamic-forms/core';
import { DsDynamicFormControlComponent, NGBootstrapFormControlType } from './ds-dynamic-form-control.component';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '../../../shared.module';
import { DynamicDsDatePickerModel } from './models/date-picker/date-picker.model';
import { DynamicGroupModel } from './models/dynamic-group/dynamic-group.model';
import { DynamicListCheckboxGroupModel } from './models/list/dynamic-list-checkbox-group.model';
import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model';
import { DynamicListRadioGroupModel } from './models/list/dynamic-list-radio-group.model';
import { DynamicLookupModel } from './models/lookup/dynamic-lookup.model';
import { DynamicScrollableDropdownModel } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
import { DynamicTagModel } from './models/tag/dynamic-tag.model';
import { DynamicTypeaheadModel } from './models/typeahead/dynamic-typeahead.model';
import { DynamicComboboxModel } from './models/ds-dynamic-combobox.model';
describe('DsDynamicFormControlComponent test suite', () => {
const authorityOptions: AuthorityOptions = {
closed: false,
metadata: 'list',
name: 'type_programme',
scope: 'c1c16450-d56f-41bc-bb81-27f1d1eb5c23'
};
const formModel = [
new DynamicCheckboxModel({id: 'checkbox'}),
new DynamicCheckboxGroupModel({id: 'checkboxGroup', group: []}),
new DynamicColorPickerModel({id: 'colorpicker'}),
new DynamicDatePickerModel({id: 'datepicker'}),
new DynamicEditorModel({id: 'editor'}),
new DynamicFileUploadModel({id: 'upload', url: ''}),
new DynamicFormArrayModel({id: 'formArray', groupFactory: () => []}),
new DynamicFormGroupModel({id: 'formGroup', group: []}),
new DynamicInputModel({id: 'input', maxLength: 51}),
new DynamicRadioGroupModel({id: 'radioGroup'}),
new DynamicRatingModel({id: 'rating'}),
new DynamicSelectModel({id: 'select', options: [{value: 'One'}, {value: 'Two'}], value: 'One'}),
new DynamicSliderModel({id: 'slider'}),
new DynamicSwitchModel({id: 'switch'}),
new DynamicTextAreaModel({id: 'textarea'}),
new DynamicTimePickerModel({id: 'timepicker'}),
new DynamicTypeaheadModel({id: 'typeahead'}),
new DynamicScrollableDropdownModel({id: 'scrollableDropdown', authorityOptions: authorityOptions}),
new DynamicTagModel({id: 'tag'}),
new DynamicListCheckboxGroupModel({id: 'checkboxList', authorityOptions: authorityOptions, repeatable: true}),
new DynamicListRadioGroupModel({id: 'radioList', authorityOptions: authorityOptions, repeatable: false}),
new DynamicGroupModel({
id: 'relationGroup',
formConfiguration: [],
mandatoryField: '',
name: 'relationGroup',
relationFields: [],
scopeUUID: '',
submissionScope: ''
}),
new DynamicDsDatePickerModel({id: 'datepicker'}),
new DynamicLookupModel({id: 'lookup', separator: ','}),
new DynamicComboboxModel({id: 'combobox', readOnly: false})
];
const testModel = formModel[8];
let formGroup: FormGroup;
let fixture: ComponentFixture<DsDynamicFormControlComponent>;
let component: DsDynamicFormControlComponent;
let debugElement: DebugElement;
let testElement: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
ReactiveFormsModule,
NgbModule.forRoot(),
DynamicFormsCoreModule.forRoot(),
SharedModule,
TranslateModule.forRoot(),
TextMaskModule,
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents().then(() => {
fixture = TestBed.createComponent(DsDynamicFormControlComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
}));
beforeEach(inject([DynamicFormService], (service: DynamicFormService) => {
formGroup = service.createFormGroup(formModel);
component.group = formGroup;
component.model = testModel;
component.ngOnChanges({
group: new SimpleChange(null, component.group, true),
model: new SimpleChange(null, component.model, true)
});
fixture.detectChanges();
testElement = debugElement.query(By.css(`input[id='${testModel.id}']`));
}));
it('should initialize correctly', () => {
expect(component.context).toBeNull();
expect(component.control instanceof FormControl).toBe(true);
expect(component.group instanceof FormGroup).toBe(true);
expect(component.model instanceof DynamicFormControlModel).toBe(true);
expect(component.hasErrorMessaging).toBe(false);
expect(component.asBootstrapFormGroup).toBe(true);
expect(component.onControlValueChanges).toBeDefined();
expect(component.onModelDisabledUpdates).toBeDefined();
expect(component.onModelValueUpdates).toBeDefined();
expect(component.blur).toBeDefined();
expect(component.change).toBeDefined();
expect(component.focus).toBeDefined();
expect(component.onValueChange).toBeDefined();
expect(component.onBlur).toBeDefined();
expect(component.onFocus).toBeDefined();
expect(component.isValid).toBe(true);
expect(component.isInvalid).toBe(false);
expect(component.showErrorMessages).toBe(false);
expect(component.type).toBe(NGBootstrapFormControlType.Input);
});
it('should have an input element', () => {
expect(testElement instanceof DebugElement).toBe(true);
});
it('should listen to native blur events', () => {
spyOn(component, 'onBlur');
testElement.triggerEventHandler('blur', null);
expect(component.onBlur).toHaveBeenCalled();
});
it('should listen to native focus events', () => {
spyOn(component, 'onFocus');
testElement.triggerEventHandler('focus', null);
expect(component.onFocus).toHaveBeenCalled();
});
it('should listen to native change event', () => {
spyOn(component, 'onValueChange');
testElement.triggerEventHandler('change', null);
expect(component.onValueChange).toHaveBeenCalled();
});
it('should update model value when control value changes', () => {
spyOn(component, 'onControlValueChanges');
component.control.setValue('test');
expect(component.onControlValueChanges).toHaveBeenCalled();
});
it('should update control value when model value changes', () => {
spyOn(component, 'onModelValueUpdates');
(testModel as DynamicInputModel).valueUpdates.next('test');
expect(component.onModelValueUpdates).toHaveBeenCalled();
});
it('should update control activation when model disabled property changes', () => {
spyOn(component, 'onModelDisabledUpdates');
testModel.disabledUpdates.next(true);
expect(component.onModelDisabledUpdates).toHaveBeenCalled();
});
it('should determine correct form control type', () => {
const testFn = DsDynamicFormControlComponent.getFormControlType;
expect(testFn(formModel[0])).toEqual(NGBootstrapFormControlType.Checkbox);
expect(testFn(formModel[1])).toEqual(NGBootstrapFormControlType.CheckboxGroup);
expect(testFn(formModel[2])).toBeNull();
expect(testFn(formModel[3])).toEqual(NGBootstrapFormControlType.DatePicker);
(formModel[3] as DynamicDatePickerModel).inline = true;
expect(testFn(formModel[3])).toEqual(NGBootstrapFormControlType.Calendar);
expect(testFn(formModel[4])).toBeNull();
expect(testFn(formModel[5])).toBeNull();
expect(testFn(formModel[6])).toEqual(NGBootstrapFormControlType.Array);
expect(testFn(formModel[7])).toEqual(NGBootstrapFormControlType.Group);
expect(testFn(formModel[8])).toEqual(NGBootstrapFormControlType.Input);
expect(testFn(formModel[9])).toEqual(NGBootstrapFormControlType.RadioGroup);
expect(testFn(formModel[10])).toBeNull();
expect(testFn(formModel[11])).toEqual(NGBootstrapFormControlType.Select);
expect(testFn(formModel[12])).toBeNull();
expect(testFn(formModel[13])).toBeNull();
expect(testFn(formModel[14])).toEqual(NGBootstrapFormControlType.TextArea);
expect(testFn(formModel[15])).toEqual(NGBootstrapFormControlType.TimePicker);
expect(testFn(formModel[16])).toEqual(NGBootstrapFormControlType.TypeAhead);
expect(testFn(formModel[17])).toEqual(NGBootstrapFormControlType.ScrollableDropdown);
expect(testFn(formModel[18])).toEqual(NGBootstrapFormControlType.Tag);
expect(testFn(formModel[19])).toEqual(NGBootstrapFormControlType.List);
expect(testFn(formModel[20])).toEqual(NGBootstrapFormControlType.List);
expect(testFn(formModel[21])).toEqual(NGBootstrapFormControlType.Relation);
expect(testFn(formModel[22])).toEqual(NGBootstrapFormControlType.Date);
expect(testFn(formModel[23])).toEqual(NGBootstrapFormControlType.Lookup);
expect(testFn(formModel[24])).toEqual(NGBootstrapFormControlType.Group);
});
});

View File

@@ -55,10 +55,10 @@ export const enum NGBootstrapFormControlType {
TimePicker = 11, // 'TIMEPICKER' TimePicker = 11, // 'TIMEPICKER'
TypeAhead = 12, // 'TYPEAHEAD' TypeAhead = 12, // 'TYPEAHEAD'
ScrollableDropdown = 13, // 'SCROLLABLE_DROPDOWN' ScrollableDropdown = 13, // 'SCROLLABLE_DROPDOWN'
TypeTag = 14, // 'TYPETAG' Tag = 14, // 'TAG'
List = 15, // 'TYPELIST' List = 15, // 'TYPELIST'
Relation = 16, // Dynamic Group Relation = 16, // 'RELATION'
DsDatePicker = 17, // Ds Date Picker Date = 17, // 'DATE'
Lookup = 18, // LOOKUP Lookup = 18, // LOOKUP
} }
@@ -109,7 +109,6 @@ export class DsDynamicFormControlComponent extends DynamicFormControlComponent i
return datepickerModel.inline ? NGBootstrapFormControlType.Calendar : NGBootstrapFormControlType.DatePicker; return datepickerModel.inline ? NGBootstrapFormControlType.Calendar : NGBootstrapFormControlType.DatePicker;
case DYNAMIC_FORM_CONTROL_TYPE_GROUP: case DYNAMIC_FORM_CONTROL_TYPE_GROUP:
// return (model instanceof DynamicGroupModel) ? NGBootstrapFormControlType.DynamicGroup : NGBootstrapFormControlType.Group;
return NGBootstrapFormControlType.Group; return NGBootstrapFormControlType.Group;
case DYNAMIC_FORM_CONTROL_TYPE_INPUT: case DYNAMIC_FORM_CONTROL_TYPE_INPUT:
@@ -134,13 +133,13 @@ export class DsDynamicFormControlComponent extends DynamicFormControlComponent i
return NGBootstrapFormControlType.ScrollableDropdown; return NGBootstrapFormControlType.ScrollableDropdown;
case DYNAMIC_FORM_CONTROL_TYPE_TAG: case DYNAMIC_FORM_CONTROL_TYPE_TAG:
return NGBootstrapFormControlType.TypeTag; return NGBootstrapFormControlType.Tag;
case DYNAMIC_FORM_CONTROL_TYPE_RELATION: case DYNAMIC_FORM_CONTROL_TYPE_RELATION:
return NGBootstrapFormControlType.Relation; return NGBootstrapFormControlType.Relation;
case DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER: case DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER:
return NGBootstrapFormControlType.DsDatePicker; return NGBootstrapFormControlType.Date;
case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP: case DYNAMIC_FORM_CONTROL_TYPE_LOOKUP:
return NGBootstrapFormControlType.Lookup; return NGBootstrapFormControlType.Lookup;

View File

@@ -2,7 +2,7 @@ import { DynamicDateControlModel, DynamicFormControlLayout, serializable } from
import { DynamicDateControlModelConfig } from '@ng-dynamic-forms/core/src/model/dynamic-date-control.model'; import { DynamicDateControlModelConfig } from '@ng-dynamic-forms/core/src/model/dynamic-date-control.model';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
export const DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER = 'DSDATEPICKER'; export const DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER = 'DATE';
/** /**
* Dynamic Date Picker Model class * Dynamic Date Picker Model class

View File

@@ -9,8 +9,8 @@ export const COMBOBOX_METADATA_SUFFIX = '_COMBO_METADATA';
export const COMBOBOX_VALUE_SUFFIX = '_COMBO_VALUE'; export const COMBOBOX_VALUE_SUFFIX = '_COMBO_VALUE';
export interface DsDynamicComboboxModelConfig extends DynamicFormGroupModelConfig { export interface DsDynamicComboboxModelConfig extends DynamicFormGroupModelConfig {
languageCodes: LanguageCode[]; languageCodes?: LanguageCode[];
language: string; language?: string;
readOnly: boolean; readOnly: boolean;
} }

View File

@@ -9,7 +9,7 @@ import { hasValue } from '../../../../../empty.util';
export interface DynamicListModelConfig extends DynamicRadioGroupModelConfig<any> { export interface DynamicListModelConfig extends DynamicRadioGroupModelConfig<any> {
authorityOptions: AuthorityOptions; authorityOptions: AuthorityOptions;
groupLength: number; groupLength?: number;
repeatable: boolean; repeatable: boolean;
value?: any; value?: any;
} }

View File

@@ -6,8 +6,8 @@ import { AuthorityOptions } from '../../../../../../core/integration/models/auth
export const DYNAMIC_FORM_CONTROL_TYPE_LOOKUP = 'LOOKUP'; export const DYNAMIC_FORM_CONTROL_TYPE_LOOKUP = 'LOOKUP';
export interface DynamicLookupModelConfig extends DsDynamicInputModelConfig { export interface DynamicLookupModelConfig extends DsDynamicInputModelConfig {
maxOptions: number; maxOptions?: number;
value: any; value?: any;
separator: string; separator: string;
} }
@@ -26,7 +26,7 @@ export class DynamicLookupModel extends DsDynamicInputModel {
super(config, layout); super(config, layout);
this.autoComplete = AUTOCOMPLETE_OFF; this.autoComplete = AUTOCOMPLETE_OFF;
this.maxOptions = config.maxOptions; this.maxOptions = config.maxOptions || 10;
this.separator = config.separator; // Defined only for lookup-name this.separator = config.separator; // Defined only for lookup-name
this.valueUpdates.next(config.value); this.valueUpdates.next(config.value);

View File

@@ -6,8 +6,8 @@ export const DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN = 'SCROLLABLE_DROPDOW
export interface DynamicScrollableDropdownModelConfig extends DsDynamicInputModelConfig { export interface DynamicScrollableDropdownModelConfig extends DsDynamicInputModelConfig {
authorityOptions: AuthorityOptions; authorityOptions: AuthorityOptions;
maxOptions: number; maxOptions?: number;
value: any; value?: any;
} }
export class DynamicScrollableDropdownModel extends DsDynamicInputModel { export class DynamicScrollableDropdownModel extends DsDynamicInputModel {
@@ -21,7 +21,7 @@ export class DynamicScrollableDropdownModel extends DsDynamicInputModel {
this.autoComplete = AUTOCOMPLETE_OFF; this.autoComplete = AUTOCOMPLETE_OFF;
this.authorityOptions = config.authorityOptions; this.authorityOptions = config.authorityOptions;
this.maxOptions = config.maxOptions; this.maxOptions = config.maxOptions || 10;
} }
} }

View File

@@ -2,10 +2,10 @@ import { AUTOCOMPLETE_OFF, DynamicFormControlLayout, serializable } from '@ng-dy
import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model'; import { DsDynamicInputModel, DsDynamicInputModelConfig } from '../ds-dynamic-input.model';
import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model'; import { AuthorityOptions } from '../../../../../../core/integration/models/authority-options.model';
export const DYNAMIC_FORM_CONTROL_TYPE_TAG = 'TYPETAG'; export const DYNAMIC_FORM_CONTROL_TYPE_TAG = 'TAG';
export interface DynamicTagModelConfig extends DsDynamicInputModelConfig { export interface DynamicTagModelConfig extends DsDynamicInputModelConfig {
minChars: number; minChars?: number;
value?: any; value?: any;
} }
@@ -20,7 +20,7 @@ export class DynamicTagModel extends DsDynamicInputModel {
super(config, layout); super(config, layout);
this.autoComplete = AUTOCOMPLETE_OFF; this.autoComplete = AUTOCOMPLETE_OFF;
this.minChars = config.minChars; this.minChars = config.minChars || 3;
const value = config.value || []; const value = config.value || [];
this.valueUpdates.next(value) this.valueUpdates.next(value)
} }

View File

@@ -5,8 +5,8 @@ import { AuthorityOptions } from '../../../../../../core/integration/models/auth
export const DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD = 'TYPEAHEAD'; export const DYNAMIC_FORM_CONTROL_TYPE_TYPEAHEAD = 'TYPEAHEAD';
export interface DsDynamicTypeaheadModelConfig extends DsDynamicInputModelConfig { export interface DsDynamicTypeaheadModelConfig extends DsDynamicInputModelConfig {
minChars: number; minChars?: number;
value: any; value?: any;
} }
export class DynamicTypeaheadModel extends DsDynamicInputModel { export class DynamicTypeaheadModel extends DsDynamicInputModel {
@@ -19,7 +19,7 @@ export class DynamicTypeaheadModel extends DsDynamicInputModel {
super(config, layout); super(config, layout);
this.autoComplete = AUTOCOMPLETE_OFF; this.autoComplete = AUTOCOMPLETE_OFF;
this.minChars = config.minChars; this.minChars = config.minChars || 3;
} }
} }

View File

@@ -23,7 +23,6 @@ export class DropdownFieldParser extends FieldParser {
if (isNotEmpty(this.configData.selectableMetadata[0].authority)) { if (isNotEmpty(this.configData.selectableMetadata[0].authority)) {
this.setAuthorityOptions(dropdownModelConfig, this.authorityUuid); this.setAuthorityOptions(dropdownModelConfig, this.authorityUuid);
dropdownModelConfig.maxOptions = 10;
if (isNotEmpty(fieldValue)) { if (isNotEmpty(fieldValue)) {
dropdownModelConfig.value = fieldValue; dropdownModelConfig.value = fieldValue;
} }

View File

@@ -1,8 +1,5 @@
import { FieldParser } from './field-parser'; import { FieldParser } from './field-parser';
import { FormFieldModel } from '../models/form-field.model'; import { FormFieldModel } from '../models/form-field.model';
import { AuthorityValueModel } from '../../../../core/integration/models/authority-value.model';
import { isNotEmpty } from '../../../empty.util';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { DynamicLookupModel, DynamicLookupModelConfig } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup.model'; import { DynamicLookupModel, DynamicLookupModelConfig } from '../ds-dynamic-form-ui/models/lookup/dynamic-lookup.model';
export class LookupFieldParser extends FieldParser { export class LookupFieldParser extends FieldParser {
@@ -19,7 +16,6 @@ export class LookupFieldParser extends FieldParser {
const lookupModelConfig: DynamicLookupModelConfig = this.initModel(); const lookupModelConfig: DynamicLookupModelConfig = this.initModel();
this.setAuthorityOptions(lookupModelConfig, this.authorityUuid); this.setAuthorityOptions(lookupModelConfig, this.authorityUuid);
lookupModelConfig.maxOptions = 10;
this.setValues(lookupModelConfig, fieldValue, true); this.setValues(lookupModelConfig, fieldValue, true);

View File

@@ -81,7 +81,6 @@ export class OneboxFieldParser extends FieldParser {
const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel(); const typeaheadModelConfig: DsDynamicTypeaheadModelConfig = this.initModel();
this.setAuthorityOptions(typeaheadModelConfig, this.authorityUuid); this.setAuthorityOptions(typeaheadModelConfig, this.authorityUuid);
this.setValues(typeaheadModelConfig, fieldValue, true); this.setValues(typeaheadModelConfig, fieldValue, true);
typeaheadModelConfig.minChars = 3;
const typeaheadModel = new DynamicTypeaheadModel(typeaheadModelConfig); const typeaheadModel = new DynamicTypeaheadModel(typeaheadModelConfig);
return typeaheadModel; return typeaheadModel;
} else { } else {

View File

@@ -20,7 +20,6 @@ export class TagFieldParser extends FieldParser {
this.setAuthorityOptions(tagModelConfig, this.authorityUuid); this.setAuthorityOptions(tagModelConfig, this.authorityUuid);
} }
tagModelConfig.minChars = 3;
this.setValues(tagModelConfig, fieldValue, null, true); this.setValues(tagModelConfig, fieldValue, null, true);
const tagModel = new DynamicTagModel(tagModelConfig); const tagModel = new DynamicTagModel(tagModelConfig);