Skip to content

Commit

Permalink
Merge branch 'master' into chore/fix-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brendanbond committed Sep 7, 2024
2 parents dfe6f35 + d4636f0 commit 4491833
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 34 deletions.
91 changes: 91 additions & 0 deletions src/process/__tests__/fixtures/forDataGridRequired.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"form": {
"name": "dsf",
"path": "dsf",
"type": "form",
"display": "form",
"components": [
{
"label": "Data Grid",
"reorder": false,
"addAnotherPosition": "bottom",
"layoutFixed": false,
"enableRowGroups": false,
"initEmpty": false,
"tableView": false,
"defaultValue": [
{}
],
"validate": {
"required": true
},
"validateWhenHidden": false,
"key": "dataGrid",
"type": "datagrid",
"input": true,
"components": [
{
"label": "Columns",
"columns": [
{
"components": [
{
"label": "Text Field",
"applyMaskOn": "change",
"tableView": true,
"validateWhenHidden": false,
"key": "textField",
"type": "textfield",
"input": true
}
],
"width": 6,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 6
},
{
"components": [],
"width": 6,
"offset": 0,
"push": 0,
"pull": 0,
"size": "md",
"currentWidth": 6
}
],
"key": "columns",
"type": "columns",
"input": false,
"tableView": false
}
]
},
{
"type": "button",
"label": "Submit",
"key": "submit",
"disableOnInvalid": true,
"input": true,
"tableView": false
}
],
"created": "2024-08-07T08:41:53.926Z",
"modified": "2024-08-07T08:41:53.932Z",
"machineName": "tbtzzegecytgzpi:dsf"
},
"submission": {
"data": {

"dataGrid": [
{
"textField": ""
}
],
"submit": true
}

}
}
3 changes: 2 additions & 1 deletion src/process/__tests__/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import clearOnHideWithHiddenParent from './clearOnHideWithHiddenParent.json';
import skipValidForConditionallyHiddenComp from './skipValidForConditionallyHiddenComp.json';
import skipValidForLogicallyHiddenComp from './skipValidForLogicallyHiddenComp.json';
import skipValidWithHiddenParentComp from './skipValidWithHiddenParentComp.json';
import forDataGridRequired from './forDataGridRequired.json';
import data1a from './data1a.json';
import form1 from './form1.json';
import subs from './subs.json';

export { clearOnHideWithCustomCondition, clearOnHideWithHiddenParent, skipValidForLogicallyHiddenComp, skipValidForConditionallyHiddenComp, skipValidWithHiddenParentComp, data1a, form1, subs };
export { clearOnHideWithCustomCondition, clearOnHideWithHiddenParent, skipValidForLogicallyHiddenComp, skipValidForConditionallyHiddenComp, skipValidWithHiddenParentComp, forDataGridRequired, data1a, form1, subs };
23 changes: 22 additions & 1 deletion src/process/__tests__/process.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import assert from 'node:assert'
import type { ContainerComponent, ValidationScope } from 'types';
import { getComponent } from 'utils/formUtil';
import { process, processSync, ProcessTargets } from '../index';
import { clearOnHideWithCustomCondition, clearOnHideWithHiddenParent, skipValidForConditionallyHiddenComp, skipValidForLogicallyHiddenComp, skipValidWithHiddenParentComp } from './fixtures'
import { clearOnHideWithCustomCondition, clearOnHideWithHiddenParent, forDataGridRequired, skipValidForConditionallyHiddenComp, skipValidForLogicallyHiddenComp, skipValidWithHiddenParentComp } from './fixtures'
/*
describe('Process Tests', () => {
it('Should perform the processes using the processReduced method.', async () => {
Expand Down Expand Up @@ -3188,6 +3188,27 @@ describe('Process Tests', () => {
});
});

it('Should validate when all child components are empty in required Data Grid', async () => {
const { form, submission } = forDataGridRequired;
const context = {
form,
submission,
data: submission.data,
components: form.components,
processors: ProcessTargets.submission,
scope: {},
config: {
server: true,
},
};

processSync(context);
context.processors = ProcessTargets.evaluator;
processSync(context);

expect((context.scope as ValidationScope).errors).to.have.length(1);
});

describe('For EditGrid:', () => {
const components = [
{
Expand Down
17 changes: 9 additions & 8 deletions src/process/conditions/__tests__/conditions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { ConditionsScope, ProcessContext } from 'types';
import { get } from 'lodash';

const processForm = (form: any, submission: any) => {
const context: ProcessContext<ConditionsScope> = {
processors: [conditionProcessInfo],
components: form.components,
data: submission.data,
scope: {},
};
processSync(context);
return context;
const context: ProcessContext<ConditionsScope> = {
processors: [conditionProcessInfo],
components: form.components,
data: submission.data,
form,
scope: {}
};
processSync(context);
return context;
};

describe('Condition processor', () => {
Expand Down
6 changes: 5 additions & 1 deletion src/process/validation/rules/validateRequired.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
AddressComponent,
DayComponent
} from 'types';
import { isEmptyObject } from '../util';
import { isEmptyObject, doesArrayDataHaveValue } from '../util';
import { isComponentNestedDataType } from 'utils/formUtil';
import { ProcessorInfo } from 'types/process/ProcessorInfo';

Expand Down Expand Up @@ -47,6 +47,10 @@ const valueIsPresent = (value: any, considerFalseTruthy: boolean, isNestedDataty
else if (typeof value === 'object' && !isNestedDatatype) {
return Object.values(value).some((val) => valueIsPresent(val, considerFalseTruthy, isNestedDatatype));
}
// If value is an array, check it's children have value
else if (Array.isArray(value) && value.length) {
return doesArrayDataHaveValue(value);
}
return true;
}

Expand Down
29 changes: 29 additions & 0 deletions src/process/validation/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { FieldError } from 'error';
import { Component, ValidationContext } from 'types';
import { Evaluator, unescapeHTML } from 'utils';
import { VALIDATION_ERRORS } from './i18n';
import _isEmpty from 'lodash/isEmpty';
import _isObject from 'lodash/isObject';
import _isPlainObject from 'lodash/isPlainObject';

export function isComponentPersistent(component: Component) {
return component.persistent ? component.persistent : true;
Expand Down Expand Up @@ -92,3 +95,29 @@ export const interpolateErrors = (errors: FieldError[], lang: string = 'en') =>
};
});
};

export const hasValue = (value: any) => {
if (_isObject(value)) {
return !_isEmpty(value);
}

return (typeof value === 'number' && !Number.isNaN(value)) || !!value;
}

export const doesArrayDataHaveValue = (dataValue: any[] = []): boolean => {
if (!Array.isArray(dataValue)) {
return !!dataValue;
}

if (!dataValue.length) {
return false;
}

const isArrayDataComponent = dataValue.every(_isPlainObject);

if (isArrayDataComponent) {
return dataValue.some(value => Object.values(value).some(hasValue));
}

return dataValue.some(hasValue);
};
22 changes: 11 additions & 11 deletions src/utils/conditions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ export function checkCustomConditional(condition: string, context: ConditionsCon

/**
* Checks the legacy conditionals.
*
* @param conditional
* @param context
* @param checkDefault
* @returns
*
* @param conditional
* @param context
* @param checkDefault
* @returns
*/
export function checkLegacyConditional(conditional: LegacyConditional, context: ConditionsContext): boolean | null {
const { row, data, component } = context;
Expand All @@ -75,9 +75,9 @@ export function checkLegacyConditional(conditional: LegacyConditional, context:

/**
* Checks the JSON Conditionals.
* @param conditional
* @param conditional
* @param context
* @returns
* @returns
*/
export function checkJsonConditional(conditional: JSONConditional, context: ConditionsContext): boolean | null {
const { evalContext } = context;
Expand All @@ -90,9 +90,9 @@ export function checkJsonConditional(conditional: JSONConditional, context: Cond

/**
* Checks the simple conditionals.
* @param conditional
* @param context
* @returns
* @param conditional
* @param context
* @returns
*/
export function checkSimpleConditional(conditional: SimpleConditional, context: ConditionsContext): boolean | null {
const { component, data, row, instance, form, components = [] } = context;
Expand All @@ -116,7 +116,7 @@ export function checkSimpleConditional(conditional: SimpleConditional, context:

const ConditionOperator = ConditionOperators[operator];
return ConditionOperator
? new ConditionOperator().getResult({ value, comparedValue, instance, component, conditionComponent, conditionComponentPath })
? new ConditionOperator().getResult({ value, comparedValue, instance, component, conditionComponent, conditionComponentPath, data})
: true;
}), (res) => (res !== null));

Expand Down
4 changes: 2 additions & 2 deletions src/utils/formUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1183,8 +1183,8 @@ function isValueEmpty(component: Component, value: any) {
return value == null || value === '' || (isArray(value) && value.length === 0) || compValueIsEmptyArray;
}

export function isComponentDataEmpty(component: Component, data: any, path: string): boolean {
const value = get(data, path);
export function isComponentDataEmpty(component: Component, data: any, path: string, valueCond?:any): boolean {
const value = isNil(valueCond) ? get(data, path): valueCond;
if (isCheckboxComponent(component)) {
return isValueEmpty(component, value) || value === false;
} else if (isDataGridComponent(component) || isEditGridComponent(component) || isDataTableComponent(component) || hasChildComponents(component)) {
Expand Down
13 changes: 3 additions & 10 deletions src/utils/operators/IsEmptyValue.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isComponentDataEmpty } from 'utils/formUtil';
import ConditionOperator from './ConditionOperator';
import { isEmpty } from 'lodash';

export default class IsEmptyValue extends ConditionOperator {
static get operatorKey() {
Expand All @@ -14,15 +14,8 @@ export default class IsEmptyValue extends ConditionOperator {
return false;
}

execute({ value, instance, conditionComponentPath }) {
const isEmptyValue = isEmpty(value);

if (instance && instance.root) {
const conditionTriggerComponent = instance.root.getComponent(conditionComponentPath);
return conditionTriggerComponent ? conditionTriggerComponent.isEmpty() : isEmptyValue;
}

return isEmptyValue;
execute({ value, conditionComponentPath, data, conditionComponent}) {
return isComponentDataEmpty(conditionComponent, data, conditionComponentPath, value);
}

getResult(options) {
Expand Down

0 comments on commit 4491833

Please sign in to comment.