-
Notifications
You must be signed in to change notification settings - Fork 332
Description
Issue found in version 1.5.7
I want to use the functionality provided by json-schema-validator to apply defaults as part of the validation process, so I have changed the logic in my app to use the walk method instead of validate. However, I am now facing validation errors that were never raised as part of the validate call. The error is related to how we automatically generate nullable types in the app, which means definitions end up like this:
"REASON" : {
"oneOf" : [ {
"type" : "string"
}, {
"type" : "null"
} ]
}I am aware that the type of the property could be defined like: "type" = ["string", "null"] and this makes the walk method behave the same as validate. But unfortunately, it is not possible to apply this approach when the two types are object and null, so you must use oneOf and the walk method still raises validation errors. Please see sample unit test in Kotlin below to reproduce the problem using the object and null approach (easily swappable for oneOf string and null as well):
@Test
fun `test validate vs walk-validate`() {
val simpleSchema = """
{
"properties" : {
"USER_NAME" : {
"description" : "User name",
"type" : "string",
"default" : "JohnDoe"
},
"VALIDATE" : {
"type" : "boolean"
},
"REASON" : {
"oneOf" : [ {
"type" : "object",
"properties" : {
"TEXT" : {
"type" : "string"
}
}
}, {
"type" : "null"
} ]
}
},
"required" : [ "VALIDATE" ],
"additionalProperties" : true,
"description" : "Test",
"title": "Test",
"${'$'}defs" : { },
"type" : "object"
}
""".trimIndent()
val simplePayload = """
{
"VALIDATE": true
}
""".trimIndent()
val config = SchemaValidatorsConfig.builder()
.applyDefaultsStrategy(
ApplyDefaultsStrategy(true, true, true)
)
.build()
val schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909)
val schema = schemaFactory.getSchema(simpleSchema, config)
val objectMapper = ObjectMapper()
val jsonNode = objectMapper.readTree(simplePayload) as ObjectNode
assertTrue(!jsonNode.has("USER_NAME"))
val validationResult = schema.validate(jsonNode)
assertTrue(validationResult.isEmpty()) // Works as expected
val walkValidation = schema.walk(jsonNode, true)
assertTrue(jsonNode.has("USER_NAME")) // jsonNode now contains USER_NAME as expected
assertEquals(1, walkValidation.validationMessages.size) // but there is one validation error...
assertEquals(
"/REASON: must be valid to one and only one schema, but 2 are valid with indexes '0, 1'",
walkValidation.validationMessages.first().toString()
)
}