fixed conditional errors with false schemas and unevaluatedProperties
This commit is contained in:
117
src/tests.rs
117
src/tests.rs
@ -335,7 +335,7 @@ fn test_validate_json_schema_oneof_validation_errors() {
|
||||
let result_empty_obj = validate_json_schema(schema_id, jsonb(invalid_empty_obj));
|
||||
// Now we expect 2 errors because required fields are split into individual errors
|
||||
assert_failure_with_json!(result_empty_obj, 2);
|
||||
let errors_empty = result_empty_obj.0["errors"].as_array().expect("Expected error array for empty object");
|
||||
let errors_empty = result_empty_obj.0["errors"].as_array().unwrap();
|
||||
assert_eq!(errors_empty.len(), 2, "Expected two errors for missing required fields");
|
||||
|
||||
// Check that we have errors for both missing fields
|
||||
@ -628,6 +628,121 @@ fn test_auto_strict_validation() {
|
||||
|
||||
let result_permissive = validate_json_schema(schema_id_permissive, jsonb(instance_with_extra));
|
||||
assert_success_with_json!(result_permissive, "Instance with extra property should pass when additionalProperties is explicitly true, even with strict=true");
|
||||
|
||||
// Test 7: Schema with conditionals (if/then/else) should NOT add unevaluatedProperties to conditional branches
|
||||
let schema_id_conditional = "conditional_strict_test";
|
||||
let conditional_schema = json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": { "type": "string", "enum": ["checking", "savings"] },
|
||||
"creating": { "type": "boolean" }
|
||||
},
|
||||
"if": {
|
||||
"properties": {
|
||||
"creating": { "const": true }
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"properties": {
|
||||
"account_number": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{4,17}$"
|
||||
},
|
||||
"routing_number": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{9}$"
|
||||
}
|
||||
},
|
||||
"required": ["account_number", "routing_number"]
|
||||
}
|
||||
});
|
||||
|
||||
let _ = cache_json_schema(schema_id_conditional, jsonb(conditional_schema), true); // strict=true
|
||||
|
||||
// Valid data with properties from both main schema and then clause
|
||||
let valid_conditional = json!({
|
||||
"kind": "checking",
|
||||
"creating": true,
|
||||
"account_number": "1234567890",
|
||||
"routing_number": "123456789"
|
||||
});
|
||||
|
||||
let result_conditional = validate_json_schema(schema_id_conditional, jsonb(valid_conditional));
|
||||
assert_success_with_json!(result_conditional, "Conditional properties should be recognized as evaluated");
|
||||
|
||||
// Invalid: extra property not defined anywhere
|
||||
let invalid_conditional = json!({
|
||||
"kind": "checking",
|
||||
"creating": true,
|
||||
"account_number": "1234567890",
|
||||
"routing_number": "123456789",
|
||||
"extra": "not allowed"
|
||||
});
|
||||
|
||||
let result_invalid_conditional = validate_json_schema(schema_id_conditional, jsonb(invalid_conditional));
|
||||
assert_failure_with_json!(result_invalid_conditional, 1, "Schema validation always fails");
|
||||
let errors_conditional = result_invalid_conditional.0["errors"].as_array().unwrap();
|
||||
assert_eq!(errors_conditional[0]["code"], "FALSE_SCHEMA");
|
||||
assert_eq!(errors_conditional[0]["details"]["path"], "/extra");
|
||||
|
||||
// Test the specific edge case: pattern validation failure in a conditional branch
|
||||
// We filter out FALSE_SCHEMA errors when there are other validation errors
|
||||
let pattern_failure = json!({
|
||||
"kind": "checking",
|
||||
"creating": true,
|
||||
"account_number": "22", // Too short - will fail pattern validation
|
||||
"routing_number": "123456789" // Valid, but would be unevaluated - filtered out
|
||||
});
|
||||
|
||||
let result_pattern = validate_json_schema(schema_id_conditional, jsonb(pattern_failure));
|
||||
let pattern_errors = result_pattern.0["errors"].as_array().unwrap();
|
||||
|
||||
// We expect only 1 error: PATTERN_VIOLATED for account_number
|
||||
// FALSE_SCHEMA for routing_number is filtered out because there's a real validation error
|
||||
assert_failure_with_json!(result_pattern, 1);
|
||||
assert_eq!(pattern_errors[0]["code"], "PATTERN_VIOLATED");
|
||||
assert_eq!(pattern_errors[0]["details"]["path"], "/account_number");
|
||||
|
||||
// Test case where both fields have pattern violations
|
||||
let both_pattern_failures = json!({
|
||||
"kind": "checking",
|
||||
"creating": true,
|
||||
"account_number": "22", // Too short - will fail pattern validation
|
||||
"routing_number": "123" // Too short - will fail pattern validation
|
||||
});
|
||||
|
||||
let result_both = validate_json_schema(schema_id_conditional, jsonb(both_pattern_failures));
|
||||
let both_errors = result_both.0["errors"].as_array().unwrap();
|
||||
|
||||
// We expect 2 errors: both PATTERN_VIOLATED
|
||||
assert_failure_with_json!(result_both, 2);
|
||||
|
||||
assert!(both_errors.iter().any(|e|
|
||||
e["code"] == "PATTERN_VIOLATED" &&
|
||||
e["details"]["path"] == "/account_number"
|
||||
), "Should have pattern violation for account_number");
|
||||
|
||||
assert!(both_errors.iter().any(|e|
|
||||
e["code"] == "PATTERN_VIOLATED" &&
|
||||
e["details"]["path"] == "/routing_number"
|
||||
), "Should have pattern violation for routing_number");
|
||||
|
||||
// Test case where there are only FALSE_SCHEMA errors (no other validation errors)
|
||||
let only_false_schema = json!({
|
||||
"kind": "checking",
|
||||
"creating": true,
|
||||
"account_number": "1234567890", // Valid
|
||||
"routing_number": "123456789", // Valid
|
||||
"extra": "not allowed" // Will cause FALSE_SCHEMA
|
||||
});
|
||||
|
||||
let result_only_false = validate_json_schema(schema_id_conditional, jsonb(only_false_schema));
|
||||
let only_false_errors = result_only_false.0["errors"].as_array().unwrap();
|
||||
|
||||
// We expect 1 FALSE_SCHEMA error since there are no other validation errors
|
||||
assert_failure_with_json!(result_only_false, 1);
|
||||
assert_eq!(only_false_errors[0]["code"], "FALSE_SCHEMA");
|
||||
assert_eq!(only_false_errors[0]["details"]["path"], "/extra");
|
||||
}
|
||||
|
||||
#[pg_test]
|
||||
|
||||
Reference in New Issue
Block a user