Skip to content

Commit 3eb38a2

Browse files
committed
feat: add more error handling
1 parent e2d90b7 commit 3eb38a2

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed

src/jsonLogic.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ function createValidationsScope(schema) {
7979
evaluateValidation,
8080
evaluateValidationRuleInCondition(id, values) {
8181
const validation = validationMap.get(id);
82+
if (validation === undefined)
83+
throw Error(`"${id}" validation in if condition doesn't exist.`);
84+
8285
return evaluateValidation(validation.rule, values);
8386
},
8487
evaluateComputedValueRuleForField(id, values, fieldName) {
@@ -90,6 +93,9 @@ function createValidationsScope(schema) {
9093
},
9194
evaluateComputedValueRuleInCondition(id, values) {
9295
const validation = computedValuesMap.get(id);
96+
if (validation === undefined)
97+
throw Error(`"${id}" computedValue in if condition doesn't exist.`);
98+
9399
return evaluateValidation(validation.rule, values);
94100
},
95101
};
@@ -117,6 +123,10 @@ export function yupSchemaWithCustomJSONLogic({ field, validations, config, id })
117123
const { parentID = 'root' } = config;
118124
const validation = validations.getScope(parentID).validationMap.get(id);
119125

126+
if (validation === undefined) {
127+
throw Error(`Validation "${id}" required for "${field.name}" doesn't exist.`);
128+
}
129+
120130
return (yupSchema) =>
121131
yupSchema.test(
122132
`${field.name}-validation-${id}`,

src/tests/jsonLogic.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ import {
99
schemaWithComputedAttributeThatDoesntExistTitle,
1010
schemaWithComputedAttributes,
1111
schemaWithComputedAttributesAndErrorMessages,
12+
schemaWithDeepVarThatDoesNotExist,
13+
schemaWithDeepVarThatDoesNotExistOnFieldset,
1214
schemaWithInlinedRuleOnComputedAttributeThatReferencesUnknownVar,
1315
schemaWithMissingComputedValue,
1416
schemaWithMissingRule,
1517
schemaWithMissingValueInlineRule,
1618
schemaWithNativeAndJSONLogicChecks,
1719
schemaWithNonRequiredField,
20+
schemaWithPropertyThatDoesNotExistInThatLevelButDoesInFieldset,
1821
schemaWithTwoRules,
22+
schemaWithValidationThatDoesNotExistOnProperty,
23+
schemaWithVarThatDoesNotExist,
1924
} from './jsonLogicFixtures';
2025

2126
describe('cross-value validations', () => {
@@ -98,6 +103,50 @@ describe('cross-value validations', () => {
98103
console.error.mockRestore();
99104
});
100105

106+
it('Should throw when a var does not exist in a rule.', () => {
107+
createHeadlessForm(schemaWithVarThatDoesNotExist, { strictInputType: false });
108+
expect(console.error).toHaveBeenCalledWith(
109+
'JSON Schema invalid!',
110+
Error('"field_b" in rule "a_greater_than_ten" does not exist as a JSON schema property.')
111+
);
112+
});
113+
114+
it('Should throw when a var does not exist in a deeply nested rule', () => {
115+
createHeadlessForm(schemaWithDeepVarThatDoesNotExist, { strictInputType: false });
116+
expect(console.error).toHaveBeenCalledWith(
117+
'JSON Schema invalid!',
118+
Error('"field_b" in rule "a_greater_than_ten" does not exist as a JSON schema property.')
119+
);
120+
});
121+
122+
it('Should throw when a var does not exist in a fieldset.', () => {
123+
createHeadlessForm(schemaWithDeepVarThatDoesNotExistOnFieldset, { strictInputType: false });
124+
expect(console.error).toHaveBeenCalledWith(
125+
'JSON Schema invalid!',
126+
Error('"field_a" in rule "a_greater_than_ten" does not exist as a JSON schema property.')
127+
);
128+
});
129+
130+
it('On a property, it should throw an error for a requiredValidation that does not exist', () => {
131+
createHeadlessForm(schemaWithValidationThatDoesNotExistOnProperty, {
132+
strictInputType: false,
133+
});
134+
expect(console.error).toHaveBeenCalledWith(
135+
'JSON Schema invalid!',
136+
Error(`Validation "iDontExist" required for "field_a" doesn't exist.`)
137+
);
138+
});
139+
140+
it('A top level logic keyword will not be able to reference fieldset properties', () => {
141+
createHeadlessForm(schemaWithPropertyThatDoesNotExistInThatLevelButDoesInFieldset, {
142+
strictInputType: false,
143+
});
144+
expect(console.error).toHaveBeenCalledWith(
145+
'JSON Schema invalid!',
146+
Error('"child" in rule "validation_parent" does not exist as a JSON schema property.')
147+
);
148+
});
149+
101150
it('Should throw when theres a missing rule', () => {
102151
createHeadlessForm(schemaWithMissingRule, { strictInputType: false });
103152
expect(console.error).toHaveBeenCalledWith(

src/tests/jsonLogicFixtures.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,77 @@ export const schemaWithMissingComputedValue = {
108108
required: [],
109109
};
110110

111+
export const schemaWithVarThatDoesNotExist = {
112+
properties: {
113+
field_a: {
114+
type: 'number',
115+
},
116+
},
117+
'x-jsf-logic': {
118+
validations: {
119+
a_greater_than_ten: {
120+
errorMessage: 'Must be greater than 10',
121+
rule: {
122+
'>': [{ var: 'field_b' }, 10],
123+
},
124+
},
125+
},
126+
},
127+
required: [],
128+
};
129+
130+
export const schemaWithDeepVarThatDoesNotExist = {
131+
properties: {
132+
field_a: {
133+
type: 'number',
134+
},
135+
},
136+
'x-jsf-logic': {
137+
validations: {
138+
a_greater_than_ten: {
139+
errorMessage: 'Must be greater than 10',
140+
rule: {
141+
'>': [{ var: 'field_a' }, { '*': [2, { '/': [2, { '*': [1, { var: 'field_b' }] }] }] }],
142+
},
143+
},
144+
},
145+
},
146+
required: [],
147+
};
148+
149+
export const schemaWithDeepVarThatDoesNotExistOnFieldset = {
150+
properties: {
151+
field_a: {
152+
type: 'object',
153+
properties: {
154+
child: {
155+
type: 'number',
156+
},
157+
},
158+
'x-jsf-logic': {
159+
validations: {
160+
a_greater_than_ten: {
161+
errorMessage: 'Must be greater than 10',
162+
rule: {
163+
'>': [{ var: 'child' }, { '*': [2, { '/': [2, { '*': [1, { var: 'field_a' }] }] }] }],
164+
},
165+
},
166+
},
167+
},
168+
},
169+
},
170+
required: [],
171+
};
172+
173+
export const schemaWithValidationThatDoesNotExistOnProperty = {
174+
properties: {
175+
field_a: {
176+
type: 'number',
177+
'x-jsf-logic-validations': ['iDontExist'],
178+
},
179+
},
180+
};
181+
111182
export const multiRuleSchema = {
112183
properties: {
113184
field_a: {
@@ -343,3 +414,42 @@ export const schemaWithComputedAttributesAndErrorMessages = {
343414
},
344415
},
345416
};
417+
418+
export const schemaWithPropertyThatDoesNotExistInThatLevelButDoesInFieldset = {
419+
properties: {
420+
field_a: {
421+
type: 'object',
422+
'x-jsf-presentation': {
423+
inputType: 'fieldset',
424+
},
425+
properties: {
426+
child: {
427+
type: 'number',
428+
'x-jsf-logic-validations': ['child_greater_than_10'],
429+
},
430+
other_child: {
431+
type: 'number',
432+
'x-jsf-logic-validations': ['greater_than_child'],
433+
},
434+
},
435+
required: ['child', 'other_child'],
436+
},
437+
},
438+
'x-jsf-logic': {
439+
validations: {
440+
validation_parent: {
441+
errorMessage: 'Must be greater than 10!',
442+
rule: {
443+
'>': [{ var: 'child' }, 10],
444+
},
445+
},
446+
greater_than_child: {
447+
errorMessage: 'Must be greater than child',
448+
rule: {
449+
'>': [{ var: 'other_child' }, { var: 'child' }],
450+
},
451+
},
452+
},
453+
},
454+
required: ['field_a'],
455+
};

0 commit comments

Comments
 (0)