@openmrs/esm-form-engine-lib 2.1.0-pre.1534 → 2.1.0-pre.1540
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/forms/rfe-forms/js-expression-validation-form.json +54 -0
- package/package.json +1 -1
- package/src/form-engine.test.tsx +17 -1
- package/src/provider/form-factory-helper.ts +1 -1
- package/src/validators/js-expression-validator.test.ts +9 -9
- package/src/validators/js-expression-validator.ts +2 -2
@@ -0,0 +1,54 @@
|
|
1
|
+
{
|
2
|
+
"name": "Js expression validation",
|
3
|
+
"uuid": "xxxx",
|
4
|
+
"EncounterType": "xxxx",
|
5
|
+
"referencedForms": [],
|
6
|
+
"processor": "EncounterFormProcessor",
|
7
|
+
"pages": [
|
8
|
+
{
|
9
|
+
"label": "Page 1",
|
10
|
+
"sections": [
|
11
|
+
{
|
12
|
+
"label": "Section 1",
|
13
|
+
"questions": [
|
14
|
+
{
|
15
|
+
"label": "Question 1",
|
16
|
+
"type": "obs",
|
17
|
+
"required": false,
|
18
|
+
"id": "question1",
|
19
|
+
"questionOptions": {
|
20
|
+
"rendering": "text",
|
21
|
+
"concept": "166103AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
22
|
+
"conceptMappings": [
|
23
|
+
{
|
24
|
+
"relationship": "SAME-AS",
|
25
|
+
"type": "PIH",
|
26
|
+
"value": "2724"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"relationship": "SAME-AS",
|
30
|
+
"type": "SNOMED CT",
|
31
|
+
"value": "397678008"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"relationship": "SAME-AS",
|
35
|
+
"type": "CIEL",
|
36
|
+
"value": "166103"
|
37
|
+
}
|
38
|
+
],
|
39
|
+
"showDate": true
|
40
|
+
},
|
41
|
+
"validators": [
|
42
|
+
{
|
43
|
+
"type": "js_expression",
|
44
|
+
"failsWhenExpression": "isEmpty(myValue)",
|
45
|
+
"message": "Empty value not allowed!"
|
46
|
+
}
|
47
|
+
]
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
51
|
+
]
|
52
|
+
}
|
53
|
+
]
|
54
|
+
}
|
package/package.json
CHANGED
package/src/form-engine.test.tsx
CHANGED
@@ -12,7 +12,7 @@ import {
|
|
12
12
|
} from '@openmrs/esm-framework';
|
13
13
|
import { when } from 'jest-when';
|
14
14
|
import * as api from './api';
|
15
|
-
import { assertFormHasAllFields, findCheckboxGroup, findSelectInput } from './utils/test-utils';
|
15
|
+
import { assertFormHasAllFields, findCheckboxGroup, findSelectInput, findTextOrDateInput } from './utils/test-utils';
|
16
16
|
import { evaluatePostSubmissionExpression } from './utils/post-submission-action-helper';
|
17
17
|
import { mockPatient } from '__mocks__/patient.mock';
|
18
18
|
import { mockSessionDataResponse } from '__mocks__/session.mock';
|
@@ -42,6 +42,7 @@ import monthsOnArtForm from '__mocks__/forms/rfe-forms/months-on-art-form.json';
|
|
42
42
|
import nextVisitForm from '__mocks__/forms/rfe-forms/next-visit-test-form.json';
|
43
43
|
import viralLoadStatusForm from '__mocks__/forms/rfe-forms/viral-load-status-form.json';
|
44
44
|
import readOnlyValidationForm from '__mocks__/forms/rfe-forms/read-only-validation-form.json';
|
45
|
+
import jsExpressionValidationForm from '__mocks__/forms/rfe-forms/js-expression-validation-form.json';
|
45
46
|
|
46
47
|
import FormEngine from './form-engine.component';
|
47
48
|
import { type SessionMode } from './types';
|
@@ -262,6 +263,21 @@ describe('Form engine component', () => {
|
|
262
263
|
});
|
263
264
|
});
|
264
265
|
|
266
|
+
describe('js-expression based validation', () => {
|
267
|
+
it('should invoke validation when field value changes', async () => {
|
268
|
+
await act(async () => {
|
269
|
+
renderForm(null, jsExpressionValidationForm);
|
270
|
+
});
|
271
|
+
|
272
|
+
const textField = await findTextOrDateInput(screen, 'Question 1');
|
273
|
+
await user.type(textField, 'Some value');
|
274
|
+
// clear value
|
275
|
+
await user.clear(textField);
|
276
|
+
const errorMessage = await screen.findByText(/Empty value not allowed!/i);
|
277
|
+
expect(errorMessage).toBeInTheDocument();
|
278
|
+
});
|
279
|
+
});
|
280
|
+
|
265
281
|
describe('historical expressions', () => {
|
266
282
|
it('should ascertain getPreviousEncounter() returns an encounter and the historical expression displays on the UI', async () => {
|
267
283
|
renderForm(null, historicalExpressionsForm, 'COVID Assessment');
|
@@ -24,7 +24,7 @@ export function validateForm(context: FormContextProps) {
|
|
24
24
|
const validator = formFieldValidators[validatorConfig.type];
|
25
25
|
if (validator) {
|
26
26
|
const validationResults = validator.validate(field, values[field.id], {
|
27
|
-
|
27
|
+
formFields,
|
28
28
|
values,
|
29
29
|
expressionContext: {
|
30
30
|
patient,
|
@@ -20,22 +20,22 @@ describe('ExpressionValidator - validate', () => {
|
|
20
20
|
it('should evaluate js expressions', () => {
|
21
21
|
// setup
|
22
22
|
const field = allFields.find((f) => f.id == 'htsProviderRemarks');
|
23
|
-
const failsWhenExpression = '!isEmpty(myValue) && isEmpty(
|
23
|
+
const failsWhenExpression = '!isEmpty(myValue) && isEmpty(referredToPreventionServices)';
|
24
24
|
|
25
25
|
// replay
|
26
26
|
let errors = ExpressionValidator.validate(field, 'Remarks..', {
|
27
27
|
failsWhenExpression,
|
28
28
|
expressionContext,
|
29
29
|
values,
|
30
|
-
message: '
|
31
|
-
|
30
|
+
message: 'At least one type of Prevention Services must be selected',
|
31
|
+
formFields: allFields,
|
32
32
|
});
|
33
33
|
|
34
34
|
// verify
|
35
35
|
expect(errors).toEqual([
|
36
36
|
{
|
37
37
|
errCode: 'value.invalid',
|
38
|
-
message: '
|
38
|
+
message: 'At least one type of Prevention Services must be selected',
|
39
39
|
resultType: 'error',
|
40
40
|
},
|
41
41
|
]);
|
@@ -49,14 +49,14 @@ describe('ExpressionValidator - validate', () => {
|
|
49
49
|
expressionContext,
|
50
50
|
values,
|
51
51
|
message: 'Atleast one type of Prevention Services must be selected',
|
52
|
-
|
52
|
+
formFields: allFields,
|
53
53
|
});
|
54
54
|
|
55
55
|
// verify
|
56
56
|
expect(errors).toEqual([]);
|
57
57
|
});
|
58
58
|
|
59
|
-
|
59
|
+
it('should fail if date value is not within the configured bounds', () => {
|
60
60
|
// setup
|
61
61
|
const dateField: FormField = {
|
62
62
|
label: 'Test Date',
|
@@ -81,7 +81,7 @@ describe('ExpressionValidator - validate', () => {
|
|
81
81
|
...dateField.validators[0],
|
82
82
|
expressionContext,
|
83
83
|
values,
|
84
|
-
|
84
|
+
formFields: allFields,
|
85
85
|
});
|
86
86
|
|
87
87
|
// verify
|
@@ -96,7 +96,7 @@ describe('ExpressionValidator - validate', () => {
|
|
96
96
|
...dateField.validators[0],
|
97
97
|
expressionContext,
|
98
98
|
values,
|
99
|
-
|
99
|
+
formFields: allFields,
|
100
100
|
});
|
101
101
|
|
102
102
|
// verify
|
@@ -109,7 +109,7 @@ describe('ExpressionValidator - validate', () => {
|
|
109
109
|
...dateField.validators[0],
|
110
110
|
expressionContext,
|
111
111
|
values,
|
112
|
-
|
112
|
+
formFields: allFields,
|
113
113
|
});
|
114
114
|
|
115
115
|
// verify
|
@@ -5,7 +5,7 @@ interface ExpressionValidatorConfig {
|
|
5
5
|
failsWhenExpression?: string;
|
6
6
|
warnsWhenExpression?: string;
|
7
7
|
message: string;
|
8
|
-
|
8
|
+
formFields: FormField[];
|
9
9
|
expressionContext: ExpressionContext;
|
10
10
|
values: Record<string, any>;
|
11
11
|
}
|
@@ -23,7 +23,7 @@ export const ExpressionValidator: FormFieldValidator = {
|
|
23
23
|
return evaluateExpression(
|
24
24
|
config[key],
|
25
25
|
{ value: field, type: 'field' },
|
26
|
-
config.
|
26
|
+
config.formFields,
|
27
27
|
{ ...config.values, [field.id]: value },
|
28
28
|
config.expressionContext,
|
29
29
|
)
|