Skip to content

Commit c6847ae

Browse files
Eduardo Shiota Yasudaeshiota
authored andcommitted
feat(json-logic): apply computed attrs on nested allOf/anyOf/oneOf properties
1 parent 750947b commit c6847ae

File tree

2 files changed

+83
-34
lines changed

2 files changed

+83
-34
lines changed

src/validation/json-logic.ts

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -162,51 +162,45 @@ function cycleThroughPropertiesAndApplyValues(schemaCopy: JsfSchema, computedVal
162162
cycleThroughAttrsAndApplyValues(propertySchema, computedValues, computedAttrs)
163163
}
164164

165-
if (propertySchema.type === 'object' && propertySchema.properties) {
166-
cycleThroughPropertiesAndApplyValues(propertySchema, computedValues)
165+
// If the schemas has properties, we need to cycle through each one and apply the computed values
166+
if (typeof propertySchema.properties === 'object') {
167+
for (const propertyName in propertySchema.properties) {
168+
processProperty(propertySchema.properties[propertyName])
169+
}
167170
}
168171

169-
// deleting x-jsf-logic-computedAttrs to keep the schema clean
170-
delete propertySchema['x-jsf-logic-computedAttrs']
171-
}
172-
173-
// If the schemas has properties, we need to cycle through each one and apply the computed values
174-
// Otherwise, just process the property
175-
if (schemaCopy.properties) {
176-
for (const propertyName in schemaCopy.properties) {
177-
processProperty(schemaCopy.properties[propertyName])
172+
// If the schema has an if statement, we need to cycle through the properties and apply the computed values
173+
if (typeof propertySchema.if === 'object') {
174+
cycleThroughPropertiesAndApplyValues(propertySchema.if, computedValues)
178175
}
179-
}
180-
else {
181-
processProperty(schemaCopy)
182-
}
183176

184-
// If the schema has an if statement, we need to cycle through the properties and apply the computed values
185-
if (typeof schemaCopy.if === 'object') {
186-
cycleThroughPropertiesAndApplyValues(schemaCopy.if, computedValues)
187-
}
188-
189-
/* If the schema has an allOf or anyOf property, we need to cycle through each property inside it and
190-
* apply the computed values
191-
*/
177+
/* If the schema has an allOf or anyOf property, we need to cycle through each property inside it and
178+
* apply the computed values
179+
*/
192180

193-
if (schemaCopy.allOf && schemaCopy.allOf.length > 0) {
194-
for (const schema of schemaCopy.allOf) {
195-
cycleThroughPropertiesAndApplyValues(schema, computedValues)
181+
if (propertySchema.allOf && propertySchema.allOf.length > 0) {
182+
for (const schema of propertySchema.allOf) {
183+
cycleThroughPropertiesAndApplyValues(schema, computedValues)
184+
}
196185
}
197-
}
198186

199-
if (schemaCopy.anyOf && schemaCopy.anyOf.length > 0) {
200-
for (const schema of schemaCopy.anyOf) {
201-
cycleThroughPropertiesAndApplyValues(schema, computedValues)
187+
if (propertySchema.anyOf && propertySchema.anyOf.length > 0) {
188+
for (const schema of propertySchema.anyOf) {
189+
cycleThroughPropertiesAndApplyValues(schema, computedValues)
190+
}
202191
}
203-
}
204192

205-
if (schemaCopy.oneOf && schemaCopy.oneOf.length > 0) {
206-
for (const schema of schemaCopy.oneOf) {
207-
cycleThroughPropertiesAndApplyValues(schema, computedValues)
193+
if (propertySchema.oneOf && propertySchema.oneOf.length > 0) {
194+
for (const schema of propertySchema.oneOf) {
195+
cycleThroughPropertiesAndApplyValues(schema, computedValues)
196+
}
208197
}
198+
199+
// deleting x-jsf-logic-computedAttrs to keep the schema clean
200+
delete propertySchema['x-jsf-logic-computedAttrs']
209201
}
202+
203+
processProperty(schemaCopy)
210204
}
211205

212206
/**

test/validation/json-logic.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,4 +537,59 @@ describe('applyComputedAttrsToSchema', () => {
537537
expect(conditionValue['x-jsf-logic-computedAttrs']).toBeUndefined()
538538
expect(conditionValue.minimum).toBe(10)
539539
})
540+
541+
it('allows to use computed values inside oneOf statements nested in a property', () => {
542+
const schema: JsfObjectSchema = {
543+
'type': 'object',
544+
'properties': {
545+
maximum_temperature: {
546+
title: 'Maximum room temperature',
547+
type: 'number',
548+
description: 'What is the maximum room temperature in Celsius?',
549+
},
550+
temperature_setting: {
551+
title: 'Select a preset temperature',
552+
type: 'string',
553+
oneOf: [
554+
{
555+
title: 'Low',
556+
const: 18,
557+
},
558+
{
559+
title: 'Medium',
560+
const: 20,
561+
},
562+
{
563+
'title': 'Maximum',
564+
'x-jsf-logic-computedAttrs': {
565+
const: 'maximum_temperature',
566+
},
567+
},
568+
],
569+
},
570+
},
571+
'required': [
572+
'maximum_temperature',
573+
'temperature_setting',
574+
],
575+
'x-jsf-logic': {
576+
computedValues: {
577+
maximum_temperature: {
578+
rule: {
579+
var: 'maximum_temperature',
580+
},
581+
},
582+
},
583+
},
584+
};
585+
586+
// Mock the jsonLogic.apply to return 24
587+
(jsonLogic.apply as jest.Mock).mockReturnValue(24)
588+
589+
const result = JsonLogicValidation.applyComputedAttrsToSchema(schema, schema['x-jsf-logic']?.computedValues, { maximum_temperature: 24 })
590+
591+
const temperatureSetting = result.properties?.temperature_setting as NonBooleanJsfSchema
592+
expect(temperatureSetting['x-jsf-logic-computedAttrs']).toBeUndefined()
593+
expect((temperatureSetting.oneOf?.[2] as NonBooleanJsfSchema)?.const).toBe(24)
594+
})
540595
})

0 commit comments

Comments
 (0)