boon now included
This commit is contained in:
44
src/lib.rs
44
src/lib.rs
@ -371,11 +371,10 @@ fn validate_json_schema(schema_id: &str, instance: JsonB) -> JsonB {
|
||||
let mut error_list = Vec::new();
|
||||
collect_errors(&validation_error, &mut error_list);
|
||||
let errors = format_errors(error_list, &instance_value, schema_id);
|
||||
let filtered_errors = filter_false_schema_errors(errors);
|
||||
if filtered_errors.is_empty() {
|
||||
if errors.is_empty() {
|
||||
JsonB(json!({ "response": "success" }))
|
||||
} else {
|
||||
JsonB(json!({ "errors": filtered_errors }))
|
||||
JsonB(json!({ "errors": errors }))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -391,19 +390,6 @@ fn collect_errors(error: &ValidationError, errors_list: &mut Vec<Error>) {
|
||||
ErrorKind::Group | ErrorKind::AllOf | ErrorKind::AnyOf | ErrorKind::Not | ErrorKind::OneOf(_)
|
||||
);
|
||||
|
||||
// Special handling for FalseSchema - if it has causes, use those instead
|
||||
if matches!(&error.kind, ErrorKind::FalseSchema) {
|
||||
if !error.causes.is_empty() {
|
||||
// FalseSchema often wraps more specific errors in if/then conditionals
|
||||
for cause in &error.causes {
|
||||
collect_errors(cause, errors_list);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If FalseSchema has no causes, it's likely from unevaluatedProperties
|
||||
// We'll handle it as a leaf error below
|
||||
}
|
||||
|
||||
if error.causes.is_empty() && !is_structural {
|
||||
let base_path = error.instance_location.to_string();
|
||||
|
||||
@ -892,32 +878,6 @@ fn handle_one_of_error(base_path: &str, matched: &Option<(usize, usize)>) -> Vec
|
||||
}]
|
||||
}
|
||||
|
||||
// Filter out FALSE_SCHEMA errors if there are other validation errors
|
||||
fn filter_false_schema_errors(errors: Vec<Value>) -> Vec<Value> {
|
||||
// Check if there are any non-FALSE_SCHEMA errors
|
||||
let has_non_false_schema = errors.iter().any(|e| {
|
||||
e.get("code")
|
||||
.and_then(|c| c.as_str())
|
||||
.map(|code| code != "FALSE_SCHEMA")
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
if has_non_false_schema {
|
||||
// Filter out FALSE_SCHEMA errors
|
||||
errors.into_iter()
|
||||
.filter(|e| {
|
||||
e.get("code")
|
||||
.and_then(|c| c.as_str())
|
||||
.map(|code| code != "FALSE_SCHEMA")
|
||||
.unwrap_or(true)
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
// Keep all errors (they're all FALSE_SCHEMA)
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
||||
// Formats errors according to DropError structure
|
||||
fn format_errors(errors: Vec<Error>, instance: &Value, schema_id: &str) -> Vec<Value> {
|
||||
// Deduplicate by instance_path and format as DropError
|
||||
|
||||
@ -764,6 +764,52 @@ pub fn title_override_schemas() -> JsonB {
|
||||
cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs))
|
||||
}
|
||||
|
||||
pub fn format_with_ref_schemas() -> JsonB {
|
||||
let enums = json!([]);
|
||||
let types = json!([
|
||||
{
|
||||
"name": "entity",
|
||||
"schemas": [{
|
||||
"$id": "entity",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "string", "format": "uuid" },
|
||||
"type": { "type": "string" },
|
||||
"name": { "type": "string" }
|
||||
},
|
||||
"required": ["id", "type"]
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "job",
|
||||
"schemas": [{
|
||||
"$id": "job",
|
||||
"$ref": "entity",
|
||||
"properties": {
|
||||
"worker_id": { "type": "string", "format": "uuid" }
|
||||
}
|
||||
}]
|
||||
}
|
||||
]);
|
||||
|
||||
let puncs = json!([{
|
||||
"name": "save_job",
|
||||
"public": true,
|
||||
"schemas": [
|
||||
{
|
||||
"$id": "save_job.request",
|
||||
"$ref": "job"
|
||||
},
|
||||
{
|
||||
"$id": "save_job.response",
|
||||
"$ref": "job"
|
||||
}
|
||||
]
|
||||
}]);
|
||||
|
||||
cache_json_schemas(jsonb(enums), jsonb(types), jsonb(puncs))
|
||||
}
|
||||
|
||||
pub fn type_matching_schemas() -> JsonB {
|
||||
let enums = json!([]);
|
||||
let types = json!([
|
||||
|
||||
19
src/tests.rs
19
src/tests.rs
@ -488,6 +488,25 @@ fn test_validate_format_empty_string() {
|
||||
assert_success(&result);
|
||||
}
|
||||
|
||||
#[pg_test]
|
||||
fn test_validate_format_empty_string_with_ref() {
|
||||
let cache_result = format_with_ref_schemas();
|
||||
assert_success(&cache_result);
|
||||
|
||||
// Test that an optional field with a format constraint passes validation
|
||||
// when the value is an empty string, even when the schema is referenced by a punc.
|
||||
let instance = json!({
|
||||
"id": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"type": "job",
|
||||
"worker_id": "" // Optional field with format, but empty string
|
||||
});
|
||||
|
||||
let result = validate_json_schema("save_job.request", jsonb(instance));
|
||||
|
||||
// This should succeed because empty strings are ignored for format validation.
|
||||
assert_success(&result);
|
||||
}
|
||||
|
||||
#[pg_test]
|
||||
fn test_validate_property_merging() {
|
||||
let cache_result = property_merging_schemas();
|
||||
|
||||
Reference in New Issue
Block a user