From bf828b6389f74fbe3f2adede1e15f9ed43029c96 Mon Sep 17 00:00:00 2001 From: Silviu Popa Date: Wed, 7 Aug 2019 01:39:45 +0300 Subject: [PATCH] [ADF-4782] VisibilityConditions - fix chaining conditions (#4971) * [ADF-4782] VisibilityConditions - fix chaining conditions * add return types --- .../widget-visibility-cloud.service.spec.ts | 19 ++- .../widget-visibility.service.spec.ts | 16 ++- .../services/widget-visibility.service.ts | 25 +++- .../widget-visibility-cloud.service.mock.ts | 125 +++++++++++++++--- .../form/widget-visibility.service.mock.ts | 18 --- 5 files changed, 155 insertions(+), 48 deletions(-) diff --git a/lib/core/form/services/widget-visibility-cloud.service.spec.ts b/lib/core/form/services/widget-visibility-cloud.service.spec.ts index 330d1fa909..8fd7f5a079 100644 --- a/lib/core/form/services/widget-visibility-cloud.service.spec.ts +++ b/lib/core/form/services/widget-visibility-cloud.service.spec.ts @@ -34,7 +34,7 @@ import { AlfrescoApiServiceMock } from '../../mock/alfresco-api.service.mock'; import { fakeFormJson, fakeTaskProcessVariableModels, formTest, formValues, complexVisibilityJsonVisible, - complexVisibilityJsonNotVisible } from 'core/mock/form/widget-visibility-cloud.service.mock'; + nextConditionForm, complexVisibilityJsonNotVisible } from 'core/mock/form/widget-visibility-cloud.service.mock'; declare let jasmine: any; @@ -187,6 +187,23 @@ describe('WidgetVisibilityCloudService', () => { booleanResult = service.evaluateCondition(null, null, undefined); expect(booleanResult).toBeUndefined(); }); + + it('should evaluate true visibility condition with next condition operator', (done) => { + const myForm = new FormModel(nextConditionForm); + service.refreshVisibility(myForm); + const nextConditionFormVIsibility = myForm.getFieldById('Text4'); + expect(nextConditionFormVIsibility.isVisible).toBeTruthy(); + done(); + }); + + it('should evaluate false visibility condition with next condition operator', (done) => { + const myForm = new FormModel(nextConditionForm); + myForm.getFieldById('Text3').value = 'wrong value'; + service.refreshVisibility(myForm); + const nextConditionFormVIsibility = myForm.getFieldById('Text4'); + expect(nextConditionFormVIsibility.isVisible).toBeFalsy(); + done(); + }); }); describe('should retrieve the process variables', () => { diff --git a/lib/core/form/services/widget-visibility.service.spec.ts b/lib/core/form/services/widget-visibility.service.spec.ts index 1e0a5fa4d8..43ba333b55 100644 --- a/lib/core/form/services/widget-visibility.service.spec.ts +++ b/lib/core/form/services/widget-visibility.service.spec.ts @@ -190,11 +190,12 @@ describe('WidgetVisibilityService', () => { }); describe('should retrieve the process variables', () => { - let fakeFormWithField = new FormModel(fakeFormJson); + let fakeFormWithField: FormModel; let visibilityObjTest: WidgetVisibilityModel; const chainedVisibilityObj = new WidgetVisibilityModel({}); beforeEach(() => { + fakeFormWithField = new FormModel(fakeFormJson); visibilityObjTest = new WidgetVisibilityModel({}); fakeFormWithField = new FormModel(fakeFormJson); }); @@ -342,7 +343,8 @@ describe('WidgetVisibilityService', () => { describe('should return the value of the field', () => { let visibilityObjTest: WidgetVisibilityModel; - let fakeFormWithField = new FormModel(fakeFormJson); + let fakeFormWithField: FormModel; + const jsonFieldFake = { id: 'FAKE_FORM_FIELD_ID', value: 'FAKE_FORM_FIELD_VALUE', @@ -358,6 +360,7 @@ describe('WidgetVisibilityService', () => { }); beforeEach(() => { + fakeFormWithField = new FormModel(fakeFormJson); visibilityObjTest = new WidgetVisibilityModel(); fakeFormWithField = new FormModel(fakeFormJson); formTest.values = formValues; @@ -925,13 +928,14 @@ describe('WidgetVisibilityService', () => { describe('Visibility based on form variables', () => { - const fakeFormWithVariables = new FormModel(fakeFormJson); + let fakeFormWithVariables = new FormModel(fakeFormJson); const complexVisibilityModel = new FormModel(complexVisibilityJsonVisible); const complexVisibilityJsonNotVisibleModel = new FormModel(complexVisibilityJsonNotVisible); let visibilityObjTest: WidgetVisibilityModel; beforeEach(() => { visibilityObjTest = new WidgetVisibilityModel(); + fakeFormWithVariables = new FormModel(fakeFormJson); }); it('should set visibility to true when validation for string variables succeeds', () => { @@ -986,7 +990,7 @@ describe('WidgetVisibilityService', () => { it('should set visibility to true when validation for date variables succeeds', () => { visibilityObjTest.leftRestResponseId = 'dob'; visibilityObjTest.operator = '=='; - visibilityObjTest.rightValue = '2019-05-13'; + visibilityObjTest.rightValue = '2019-05-13T00:00:00.000Z'; const isVisible = service.isFieldVisible(fakeFormWithVariables, visibilityObjTest); expect(isVisible).toBeTruthy(); @@ -995,7 +999,7 @@ describe('WidgetVisibilityService', () => { it('should set visibility to false when validation for date variables fails', () => { visibilityObjTest.leftRestResponseId = 'dob'; visibilityObjTest.operator = '=='; - visibilityObjTest.rightValue = '2019-05-15'; + visibilityObjTest.rightValue = '2019-05-15T00:00:00.000Z'; const isVisible = service.isFieldVisible(fakeFormWithVariables, visibilityObjTest); expect(isVisible).toBeFalsy(); @@ -1004,7 +1008,7 @@ describe('WidgetVisibilityService', () => { it('should validate visiblity for form fields by finding the field with id', () => { visibilityObjTest.leftRestResponseId = '0207b649-ff07-4f3a-a589-d10afa507b9b'; visibilityObjTest.operator = '=='; - visibilityObjTest.rightValue = '2019-05-13'; + visibilityObjTest.rightValue = '2019-05-13T00:00:00.000Z'; const isVisible = service.isFieldVisible(fakeFormWithVariables, visibilityObjTest); expect(isVisible).toBeTruthy(); diff --git a/lib/core/form/services/widget-visibility.service.ts b/lib/core/form/services/widget-visibility.service.ts index cc2f9c2c13..915319b586 100644 --- a/lib/core/form/services/widget-visibility.service.ts +++ b/lib/core/form/services/widget-visibility.service.ts @@ -67,14 +67,17 @@ export class WidgetVisibilityService { const leftValue = this.getLeftValue(form, visibilityObj); const rightValue = this.getRightValue(form, visibilityObj); const actualResult = this.evaluateCondition(leftValue, rightValue, visibilityObj.operator); - accumulator.push({ value: actualResult, operator: visibilityObj.nextConditionOperator }); - if (visibilityObj.nextCondition) { - result = this.isFieldVisible(form, visibilityObj.nextCondition, accumulator); - } else { - result = accumulator[0].value ? accumulator[0].value : result; + if (this.isValidOperator(visibilityObj.nextConditionOperator)) { + accumulator.push({ value: actualResult, operator: visibilityObj.nextConditionOperator }); + } + + if (this.isValidCondition(visibilityObj.nextCondition)) { + result = this.isFieldVisible(form, visibilityObj.nextCondition, accumulator); + } else if (accumulator[0] !== undefined) { + result = accumulator[0].value; for (let i = 1; i < accumulator.length; i++) { - if (accumulator[i - 1].operator && accumulator[i].value) { + if (accumulator[i] !== undefined) { result = this.evaluateLogicalOperation( accumulator[i - 1].operator, result, @@ -82,6 +85,8 @@ export class WidgetVisibilityService { ); } } + } else { + result = actualResult; } return !!result; @@ -287,6 +292,14 @@ export class WidgetVisibilityService { return res || {}; } + private isValidOperator(operator: string): boolean { + return operator !== undefined; + } + + private isValidCondition(condition: WidgetVisibilityModel): boolean { + return !!(condition && condition.operator); + } + private handleError(err) { this.logService.error('Error while performing a call'); return throwError('Error while performing a call - Server error'); diff --git a/lib/core/mock/form/widget-visibility-cloud.service.mock.ts b/lib/core/mock/form/widget-visibility-cloud.service.mock.ts index 2d2856792f..b37630aeac 100644 --- a/lib/core/mock/form/widget-visibility-cloud.service.mock.ts +++ b/lib/core/mock/form/widget-visibility-cloud.service.mock.ts @@ -15,23 +15,6 @@ * limitations under the License. */ -/*! - * @license - * Copyright 2019 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 { FormModel, FormValues } from '../../form/components/widgets/core/index'; export let formTest = new FormModel({}); @@ -863,3 +846,111 @@ export let complexVisibilityJsonNotVisible = { 'gridsterForm': false } }; + +export let nextConditionForm = { + id: '9999', + name: 'FORM_PROCESS_VARIABLE_VISIBILITY', + processDefinitionId: 'PROCESS_TEST:9:9999', + processDefinitionName: 'PROCESS_TEST', + processDefinitionKey: 'PROCESS_TEST', + taskId: '999', + taskName: 'TEST', + fields: [ + { + 'id': '60114002-0da2-4513-ab65-845b4e55d3c8', + 'name': 'Label', + 'type': 'container', + 'tab': null, + 'numberOfColumns': 2, + 'fields': { + '1': [ + { + 'id': 'Text1', + 'name': 'Text1', + 'type': 'text', + 'required': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'value': 'multiline' + }, + { + 'id': 'Text3', + 'name': 'Text3', + 'type': 'text', + 'required': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'value': 'one' + } + ], + '2': [ + { + 'id': 'Text2', + 'name': 'Text2', + 'type': 'text', + 'required': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'visibilityCondition': null, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + }, + 'value': 'one' + }, + { + 'id': 'Text4', + 'name': 'Text4', + 'type': 'text', + 'required': false, + 'colspan': 1, + 'placeholder': null, + 'minLength': 0, + 'maxLength': 0, + 'regexPattern': null, + 'visibilityCondition': { + 'leftType': 'field', + 'leftValue': 'Text1', + 'operator': '==', + 'rightValue': 'multiline', + 'rightType': 'value', + 'nextConditionOperator': 'and', + 'nextCondition': { + 'leftType': 'field', + 'leftValue': 'Text2', + 'operator': '==', + 'rightValue': 'Text3', + 'rightType': 'field', + 'nextConditionOperator': '', + 'nextCondition': null + } + }, + 'params': { + 'existingColspan': 1, + 'maxColspan': 2 + } + } + ] + } + } + ] +}; diff --git a/lib/core/mock/form/widget-visibility.service.mock.ts b/lib/core/mock/form/widget-visibility.service.mock.ts index 425fae6e2b..3dddbf21d0 100644 --- a/lib/core/mock/form/widget-visibility.service.mock.ts +++ b/lib/core/mock/form/widget-visibility.service.mock.ts @@ -14,24 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/*! - * @license - * Copyright 2019 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 { FormModel, FormValues } from '../../form/components/widgets/core/index'; export let formTest = new FormModel({});