From 80b6e15420a7950ba07ca0bcd3f527554c0749ad Mon Sep 17 00:00:00 2001 From: Maurizio Vitale Date: Wed, 4 Oct 2017 14:09:56 +0100 Subject: [PATCH] [ADF-1629] Fix check the visibility before render the form (#2423) --- .../src/assets/formDefinition.mock.ts | 283 ++++++++++++++ .../src/assets/formDefinitionReadonly.mock.ts | 225 +++++++++++ .../assets/formDefinitionVisibiity.mock.ts | 350 ++++++++++++++++++ .../src/components/form.component.ts | 6 +- .../form.component.visibility.spec.ts | 203 ++++++++++ 5 files changed, 1065 insertions(+), 2 deletions(-) create mode 100644 ng2-components/ng2-activiti-form/src/assets/formDefinition.mock.ts create mode 100644 ng2-components/ng2-activiti-form/src/assets/formDefinitionReadonly.mock.ts create mode 100644 ng2-components/ng2-activiti-form/src/assets/formDefinitionVisibiity.mock.ts create mode 100644 ng2-components/ng2-activiti-form/src/components/form.component.visibility.spec.ts diff --git a/ng2-components/ng2-activiti-form/src/assets/formDefinition.mock.ts b/ng2-components/ng2-activiti-form/src/assets/formDefinition.mock.ts new file mode 100644 index 0000000000..58bb09833d --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/assets/formDefinition.mock.ts @@ -0,0 +1,283 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export let formDefinitionTwoTextFields = { + id: 20, + name: 'formTextDefinition', + processDefinitionId: 'textDefinition:1:153', + processDefinitionName: 'textDefinition', + processDefinitionKey: 'textDefinition', + taskId: '159', + taskDefinitionKey: 'sid-D941F49F-2B04-4FBB-9B49-9E95991993E8', + tabs: [], + fields: [ + { + fieldType: 'ContainerRepresentation', + id: '1507044399260', + name: 'Label', + type: 'container', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 2, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + numberOfColumns: 2, + fields: { + '1': [ + { + fieldType: 'FormFieldRepresentation', + id: 'firstname', + name: 'firstName', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 2 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ], + '2': [ + { + fieldType: 'FormFieldRepresentation', + id: 'lastname', + name: 'lastName', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 1 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ] + } + } + ], + outcomes: [], + javascriptEvents: [], + className: '', + style: '', + customFieldTemplates: {}, + metadata: {}, + variables: [], + customFieldsValueInfo: {}, + gridsterForm: false, + globalDateFormat: 'D-M-YYYY' +}; + +export let formDefinitionDropdownField = { + id: 21, + name: 'dropdownDefinition', + processDefinitionId: 'textDefinition:2:163', + processDefinitionName: 'textDefinition', + processDefinitionKey: 'textDefinition', + taskId: '169', + taskDefinitionKey: 'sid-D941F49F-2B04-4FBB-9B49-9E95991993E8', + tabs: [], + fields: [ + { + fieldType: 'ContainerRepresentation', + id: '1507046026940', + name: 'Label', + type: 'container', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 2, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + numberOfColumns: 2, + fields: { + '1': [ + { + fieldType: 'RestFieldRepresentation', + id: 'country', + name: 'country', + type: 'dropdown', + value: 'Choose one...', + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: true, + options: [ + { + id: 'empty', + name: 'Choose one...' + }, + { + id: 'option_1', + name: 'united kingdom' + }, + { + id: 'option_2', + name: 'italy' + }, + { + id: 'option_3', + name: 'france' + } + ], + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 2 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + endpoint: null, + requestHeaders: null + } + ], + '2': [] + } + } + ], + outcomes: [], + javascriptEvents: [], + className: '', + style: '', + customFieldTemplates: {}, + metadata: {}, + variables: [], + customFieldsValueInfo: {}, + gridsterForm: false, + globalDateFormat: 'D-M-YYYY' +}; diff --git a/ng2-components/ng2-activiti-form/src/assets/formDefinitionReadonly.mock.ts b/ng2-components/ng2-activiti-form/src/assets/formDefinitionReadonly.mock.ts new file mode 100644 index 0000000000..36a5ccd66c --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/assets/formDefinitionReadonly.mock.ts @@ -0,0 +1,225 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export let formReadonlyTwoTextFields = { + id: 22, + name: 'formTextDefinition', + processDefinitionId: 'textDefinition:3:182', + processDefinitionName: 'textDefinition', + processDefinitionKey: 'textDefinition', + taskId: '188', + taskDefinitionKey: 'sid-D941F49F-2B04-4FBB-9B49-9E95991993E8', + tabs: [], + fields: [ + { + fieldType: 'ContainerRepresentation', + id: '1507044399260', + name: 'Label', + type: 'container', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 2, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + numberOfColumns: 2, + fields: { + '1': [ + { + fieldType: 'FormFieldRepresentation', + id: 'firstname', + name: 'firstName', + type: 'readonly', + value: 'fakeFirstName', + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 2, + field: { + id: 'firstname', + name: 'firstName', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 0, + sizeY: 0, + row: 0, + col: 0, + visibilityCondition: null + } + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ], + '2': [ + { + fieldType: 'FormFieldRepresentation', + id: 'lastname', + name: 'lastName', + type: 'readonly', + value: 'fakeLastName', + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 1, + field: { + id: 'lastname', + name: 'lastName', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 0, + sizeY: 0, + row: 0, + col: 0, + visibilityCondition: null + } + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ] + } + } + ], + outcomes: [], + javascriptEvents: [], + className: '', + style: '', + customFieldTemplates: {}, + metadata: {}, + variables: [], + customFieldsValueInfo: {}, + gridsterForm: false, + globalDateFormat: 'D-M-YYYY' + }; diff --git a/ng2-components/ng2-activiti-form/src/assets/formDefinitionVisibiity.mock.ts b/ng2-components/ng2-activiti-form/src/assets/formDefinitionVisibiity.mock.ts new file mode 100644 index 0000000000..003a9a76b1 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/assets/formDefinitionVisibiity.mock.ts @@ -0,0 +1,350 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export let formDefVisibilitiFieldDependsOnNextOne = { + id: 19, + processDefinitionId: 'visibility:1:148', + processDefinitionName: 'visibility', + processDefinitionKey: 'visibility', + tabs: [], + fields: [ + { + fieldType: 'ContainerRepresentation', + id: '1506960847579', + name: 'Label', + type: 'container', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 2, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + numberOfColumns: 2, + fields: { + '1': [ + { + fieldType: 'RestFieldRepresentation', + id: 'country', + name: 'country', + type: 'dropdown', + value: 'Choose one...', + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: true, + options: [ + { + id: 'empty', + name: 'Choose one...' + }, + { + id: 'option_1', + name: 'france' + }, + { + id: 'option_2', + name: 'uk' + } + ], + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 2 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: { + leftFormFieldId: 'name', + leftRestResponseId: null, + operator: '==', + rightValue: 'italy', + rightType: null, + rightFormFieldId: '', + rightRestResponseId: '', + nextConditionOperator: '', + nextCondition: null + }, + endpoint: null, + requestHeaders: null + } + ], + '2': [ + { + fieldType: 'FormFieldRepresentation', + id: 'name', + name: 'name', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 1 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ] + } + } + ], + outcomes: [], + javascriptEvents: [], + className: '', + style: '', + customFieldTemplates: {}, + metadata: {}, + variables: [], + customFieldsValueInfo: {}, + gridsterForm: false, + globalDateFormat: 'D-M-YYYY' +}; + +export let formDefVisibilitiFieldDependsOnPreviousOne = { + id: 19, + processDefinitionId: 'visibility:1:148', + processDefinitionName: 'visibility', + processDefinitionKey: 'visibility', + tabs: [], + fields: [ + { + fieldType: 'ContainerRepresentation', + id: '1506960847579', + name: 'Label', + type: 'container', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + dateDisplayFormat: null, + layout: null, + sizeX: 2, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null, + numberOfColumns: 2, + fields: { + '1': [ + { + fieldType: 'FormFieldRepresentation', + id: 'name', + name: 'name', + type: 'text', + value: null, + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: null, + options: null, + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 1 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: null + } + ], + '2': [ + { + fieldType: 'RestFieldRepresentation', + id: 'country', + name: 'country', + type: 'dropdown', + value: 'Choose one...', + required: false, + readOnly: false, + overrideId: false, + colspan: 1, + placeholder: null, + minLength: 0, + maxLength: 0, + minValue: null, + maxValue: null, + regexPattern: null, + optionType: null, + hasEmptyValue: true, + options: [ + { + id: 'empty', + name: 'Choose one...' + }, + { + id: 'option_1', + name: 'france' + }, + { + id: 'option_2', + name: 'uk' + } + ], + restUrl: null, + restResponsePath: null, + restIdProperty: null, + restLabelProperty: null, + tab: null, + className: null, + params: { + existingColspan: 1, + maxColspan: 2 + }, + dateDisplayFormat: null, + layout: { + row: -1, + column: -1, + colspan: 1 + }, + sizeX: 1, + sizeY: 1, + row: -1, + col: -1, + visibilityCondition: { + leftFormFieldId: 'name', + leftRestResponseId: null, + operator: '==', + rightValue: 'italy', + rightType: null, + rightFormFieldId: '', + rightRestResponseId: '', + nextConditionOperator: '', + nextCondition: null + }, + endpoint: null, + requestHeaders: null + } + ] + } + } + ], + outcomes: [], + javascriptEvents: [], + className: '', + style: '', + customFieldTemplates: {}, + metadata: {}, + variables: [], + customFieldsValueInfo: {}, + gridsterForm: false, + globalDateFormat: 'D-M-YYYY' +}; diff --git a/ng2-components/ng2-activiti-form/src/components/form.component.ts b/ng2-components/ng2-activiti-form/src/components/form.component.ts index eacfd57343..61cf971797 100644 --- a/ng2-components/ng2-activiti-form/src/components/form.component.ts +++ b/ng2-components/ng2-activiti-form/src/components/form.component.ts @@ -297,12 +297,14 @@ export class FormComponent implements OnInit, OnChanges { getFormByTaskId(taskId: string): Promise { return new Promise((resolve, reject) => { - this.findProcessVariablesByTaskId(this.taskId).subscribe( (processVariables) => { + this.findProcessVariablesByTaskId(taskId).subscribe( (processVariables) => { this.formService .getTaskForm(taskId) .subscribe( form => { - this.form = this.parseForm(form); + const parsedForm = this.parseForm(form); + this.visibilityService.refreshVisibility(parsedForm); + this.form = parsedForm; this.onFormLoaded(this.form); resolve(this.form); }, diff --git a/ng2-components/ng2-activiti-form/src/components/form.component.visibility.spec.ts b/ng2-components/ng2-activiti-form/src/components/form.component.visibility.spec.ts new file mode 100644 index 0000000000..e9efb1e8da --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/form.component.visibility.spec.ts @@ -0,0 +1,203 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { DebugElement, SimpleChange } from '@angular/core'; +import { Observable } from 'rxjs/Rx'; + +import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { ActivitiFormModule } from '../../index'; +import { formDefinitionDropdownField, formDefinitionTwoTextFields } from '../assets/formDefinition.mock'; +import { formReadonlyTwoTextFields } from '../assets/formDefinitionReadonly.mock'; +import { formDefVisibilitiFieldDependsOnNextOne, formDefVisibilitiFieldDependsOnPreviousOne } from '../assets/formDefinitionVisibiity.mock'; +import { FormService } from './../services/form.service'; +import { FormComponent } from './form.component'; + +/** Duration of the select opening animation. */ +const SELECT_OPEN_ANIMATION = 200; + +/** Duration of the select closing animation and the timeout interval for the backdrop. */ +const SELECT_CLOSE_ANIMATION = 500; + +describe('FormComponent UI and visibiltiy', () => { + let debugElement: DebugElement; + let element: HTMLElement; + let component: FormComponent; + let service: FormService; + let fixture: ComponentFixture; + let formDefinitionSpy: jasmine.Spy; + let taskSpy: jasmine.Spy; + + function openSelect() { + let trigger: HTMLElement; + trigger = fixture.debugElement.query(By.css('[class="mat-select-trigger"]')).nativeElement; + trigger.click(); + fixture.detectChanges(); + } + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + ActivitiFormModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FormComponent); + component = fixture.componentInstance; + element = fixture.nativeElement; + debugElement = fixture.debugElement; + service = fixture.debugElement.injector.get(FormService); + }); + + it('should create instance of FormComponent', () => { + expect(fixture.componentInstance instanceof FormComponent).toBe(true, 'should create FormComponent'); + }); + + describe('form definition', () => { + + it('should display two text fields form definition', () => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formDefinitionTwoTextFields)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + let firstNameEl = fixture.debugElement.query(By.css('#firstname')); + expect(firstNameEl).not.toBeNull(); + expect(firstNameEl).toBeDefined(); + + let lastNameEl = fixture.debugElement.query(By.css('#lastname')); + expect(lastNameEl).not.toBeNull(); + expect(lastNameEl).toBeDefined(); + }); + + it('should display dropdown field', fakeAsync(() => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formDefinitionDropdownField)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + openSelect(); + tick(SELECT_OPEN_ANIMATION); + + const dropdown = fixture.debugElement.queryAll(By.css('#country')); + expect(dropdown).toBeDefined(); + expect(dropdown).not.toBeNull(); + + const optOne = fixture.debugElement.queryAll(By.css('[id="md-option-1"]')); + const optTwo = fixture.debugElement.queryAll(By.css('[id="md-option-2"]')); + const optThree = fixture.debugElement.queryAll(By.css('[id="md-option-3"]')); + + expect(optOne[0].nativeElement.innerText).toEqual('united kingdom'); + expect(optTwo[0].nativeElement.innerText).toEqual('italy'); + expect(optThree[0].nativeElement.innerText).toEqual('france'); + + optTwo[0].nativeElement.click(); + fixture.detectChanges(); + expect(dropdown[0].nativeElement.innerText.trim()).toEqual('italy'); + tick(SELECT_CLOSE_ANIMATION); + })); + + describe('Visibility conditions', () => { + + it('should hide the field based on the next one', () => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formDefVisibilitiFieldDependsOnNextOne)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + let firstEl = fixture.debugElement.query(By.css('#country')); + expect(firstEl).toBeNull(); + + let secondEl = fixture.debugElement.query(By.css('#name')); + expect(secondEl).not.toBeNull(); + expect(secondEl).toBeDefined(); + }); + + it('should hide the field based on the previous one', () => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formDefVisibilitiFieldDependsOnPreviousOne)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + let firstEl = fixture.debugElement.query(By.css('#name')); + expect(firstEl).not.toBeNull(); + expect(firstEl).toBeDefined(); + + let secondEl = fixture.debugElement.query(By.css('#country')); + expect(secondEl).toBeNull(); + }); + + it('should show the hidden field when the visibility condition change to true', () => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formDefVisibilitiFieldDependsOnNextOne)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + let firstEl = fixture.debugElement.query(By.css('#country')); + expect(firstEl).toBeNull(); + + const secondEl = fixture.debugElement.query(By.css('#name')); + expect(secondEl).not.toBeNull(); + + let el = secondEl.nativeElement; + + el.value = 'italy'; + el.dispatchEvent(new Event('input')); + fixture.detectChanges(); + + firstEl = fixture.debugElement.query(By.css('#country')); + expect(firstEl).not.toBeNull(); + }); + }); + + describe('Readonly Form', () => { + it('should display two text fields readonly', () => { + taskSpy = spyOn(service, 'getTask').and.returnValue(Observable.of({})); + formDefinitionSpy = spyOn(service, 'getTaskForm').and.returnValue(Observable.of(formReadonlyTwoTextFields)); + + let change = new SimpleChange(null, 1, true); + component.ngOnChanges({ 'taskId': change }); + fixture.detectChanges(); + + let firstNameEl = fixture.debugElement.query(By.css('#firstname')); + expect(firstNameEl).not.toBeNull(); + expect(firstNameEl).toBeDefined(); + expect(firstNameEl.nativeElement.value).toEqual('fakeFirstName'); + + let lastNameEl = fixture.debugElement.query(By.css('#lastname')); + expect(lastNameEl).not.toBeNull(); + expect(lastNameEl).toBeDefined(); + expect(lastNameEl.nativeElement.value).toEqual('fakeLastName'); + }); + }); + }); +});