Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d19bf100e | |||
| fb333c6cbb |
@ -146,7 +146,7 @@ fn format_drop_errors(raw_errors: Vec<(String, String, String)>, instance: &Valu
|
|||||||
|
|
||||||
// 2. Deduplicate by instance_path and format as DropError
|
// 2. Deduplicate by instance_path and format as DropError
|
||||||
let mut unique_errors: HashMap<String, Value> = HashMap::new();
|
let mut unique_errors: HashMap<String, Value> = HashMap::new();
|
||||||
for (instance_path, schema_path, message) in plausible_errors {
|
for (instance_path, _schema_path, message) in plausible_errors {
|
||||||
if let Entry::Vacant(entry) = unique_errors.entry(instance_path.clone()) {
|
if let Entry::Vacant(entry) = unique_errors.entry(instance_path.clone()) {
|
||||||
// Convert message to error code and make it human readable
|
// Convert message to error code and make it human readable
|
||||||
let (code, human_message) = enhance_error_message(&message);
|
let (code, human_message) = enhance_error_message(&message);
|
||||||
@ -158,11 +158,8 @@ fn format_drop_errors(raw_errors: Vec<(String, String, String)>, instance: &Valu
|
|||||||
"code": code,
|
"code": code,
|
||||||
"message": human_message,
|
"message": human_message,
|
||||||
"details": {
|
"details": {
|
||||||
"path": schema_path,
|
"path": instance_path,
|
||||||
"context": json!({
|
"context": failing_value,
|
||||||
"instance_path": instance_path,
|
|
||||||
"failing_value": failing_value
|
|
||||||
}),
|
|
||||||
"cause": message // Original error message
|
"cause": message // Original error message
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
23
src/tests.rs
23
src/tests.rs
@ -153,16 +153,15 @@ fn test_cache_and_validate_json_schema() {
|
|||||||
let invalid_result_type = validate_json_schema(schema_id, jsonb(invalid_instance_type));
|
let invalid_result_type = validate_json_schema(schema_id, jsonb(invalid_instance_type));
|
||||||
assert_failure_with_json!(invalid_result_type, 1, "Value is below the minimum allowed", "Validation with invalid type should fail.");
|
assert_failure_with_json!(invalid_result_type, 1, "Value is below the minimum allowed", "Validation with invalid type should fail.");
|
||||||
let errors_type = invalid_result_type.0["errors"].as_array().unwrap();
|
let errors_type = invalid_result_type.0["errors"].as_array().unwrap();
|
||||||
assert_eq!(errors_type[0]["details"]["context"]["instance_path"], "/age");
|
assert_eq!(errors_type[0]["details"]["path"], "/age");
|
||||||
assert_eq!(errors_type[0]["details"]["path"], "urn:my_schema#/properties/age");
|
assert_eq!(errors_type[0]["details"]["context"], -5);
|
||||||
assert_eq!(errors_type[0]["code"], "MINIMUM_VIOLATED");
|
assert_eq!(errors_type[0]["code"], "MINIMUM_VIOLATED");
|
||||||
|
|
||||||
// Missing field
|
// Missing field
|
||||||
let invalid_result_missing = validate_json_schema(schema_id, jsonb(invalid_instance_missing));
|
let invalid_result_missing = validate_json_schema(schema_id, jsonb(invalid_instance_missing));
|
||||||
assert_failure_with_json!(invalid_result_missing, 1, "Required field is missing", "Validation with missing field should fail.");
|
assert_failure_with_json!(invalid_result_missing, 1, "Required field is missing", "Validation with missing field should fail.");
|
||||||
let errors_missing = invalid_result_missing.0["errors"].as_array().unwrap();
|
let errors_missing = invalid_result_missing.0["errors"].as_array().unwrap();
|
||||||
assert_eq!(errors_missing[0]["details"]["context"]["instance_path"], "");
|
assert_eq!(errors_missing[0]["details"]["path"], "");
|
||||||
assert_eq!(errors_missing[0]["details"]["path"], "urn:my_schema#");
|
|
||||||
assert_eq!(errors_missing[0]["code"], "REQUIRED_FIELD_MISSING");
|
assert_eq!(errors_missing[0]["code"], "REQUIRED_FIELD_MISSING");
|
||||||
|
|
||||||
// Schema not found
|
// Schema not found
|
||||||
@ -208,9 +207,9 @@ fn test_cache_invalid_json_schema() {
|
|||||||
// Both errors should have ENUM_VIOLATED code
|
// Both errors should have ENUM_VIOLATED code
|
||||||
assert_eq!(errors_array[0]["code"], "ENUM_VIOLATED");
|
assert_eq!(errors_array[0]["code"], "ENUM_VIOLATED");
|
||||||
assert_eq!(errors_array[1]["code"], "ENUM_VIOLATED");
|
assert_eq!(errors_array[1]["code"], "ENUM_VIOLATED");
|
||||||
// Check instance paths are preserved in context
|
// Check instance paths are preserved in path field
|
||||||
let paths: Vec<&str> = errors_array.iter()
|
let paths: Vec<&str> = errors_array.iter()
|
||||||
.map(|e| e["details"]["context"]["instance_path"].as_str().unwrap())
|
.map(|e| e["details"]["path"].as_str().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
assert!(paths.contains(&"/type"));
|
assert!(paths.contains(&"/type"));
|
||||||
assert!(paths.contains(&"/type/0"));
|
assert!(paths.contains(&"/type/0"));
|
||||||
@ -283,11 +282,11 @@ fn test_validate_json_schema_oneof_validation_errors() {
|
|||||||
// Explicitly check that both expected errors are present, ignoring order
|
// Explicitly check that both expected errors are present, ignoring order
|
||||||
let errors_string = result_invalid_string.0["errors"].as_array().expect("Expected error array for invalid string");
|
let errors_string = result_invalid_string.0["errors"].as_array().expect("Expected error array for invalid string");
|
||||||
assert!(errors_string.iter().any(|e|
|
assert!(errors_string.iter().any(|e|
|
||||||
e["details"]["context"]["instance_path"] == "/string_prop" &&
|
e["details"]["path"] == "/string_prop" &&
|
||||||
e["code"] == "MAX_LENGTH_VIOLATED"
|
e["code"] == "MAX_LENGTH_VIOLATED"
|
||||||
), "Missing maxLength error");
|
), "Missing maxLength error");
|
||||||
assert!(errors_string.iter().any(|e|
|
assert!(errors_string.iter().any(|e|
|
||||||
e["details"]["context"]["instance_path"] == "" &&
|
e["details"]["path"] == "" &&
|
||||||
e["code"] == "REQUIRED_FIELD_MISSING"
|
e["code"] == "REQUIRED_FIELD_MISSING"
|
||||||
), "Missing number_prop required error");
|
), "Missing number_prop required error");
|
||||||
|
|
||||||
@ -299,11 +298,11 @@ fn test_validate_json_schema_oneof_validation_errors() {
|
|||||||
// Explicitly check that both expected errors are present, ignoring order
|
// Explicitly check that both expected errors are present, ignoring order
|
||||||
let errors_number = result_invalid_number.0["errors"].as_array().expect("Expected error array for invalid number");
|
let errors_number = result_invalid_number.0["errors"].as_array().expect("Expected error array for invalid number");
|
||||||
assert!(errors_number.iter().any(|e|
|
assert!(errors_number.iter().any(|e|
|
||||||
e["details"]["context"]["instance_path"] == "/number_prop" &&
|
e["details"]["path"] == "/number_prop" &&
|
||||||
e["code"] == "MINIMUM_VIOLATED"
|
e["code"] == "MINIMUM_VIOLATED"
|
||||||
), "Missing minimum error");
|
), "Missing minimum error");
|
||||||
assert!(errors_number.iter().any(|e|
|
assert!(errors_number.iter().any(|e|
|
||||||
e["details"]["context"]["instance_path"] == "" &&
|
e["details"]["path"] == "" &&
|
||||||
e["code"] == "REQUIRED_FIELD_MISSING"
|
e["code"] == "REQUIRED_FIELD_MISSING"
|
||||||
), "Missing string_prop required error");
|
), "Missing string_prop required error");
|
||||||
|
|
||||||
@ -317,7 +316,7 @@ fn test_validate_json_schema_oneof_validation_errors() {
|
|||||||
let errors_bool = result_invalid_bool.0["errors"].as_array().expect("Expected error array for invalid bool");
|
let errors_bool = result_invalid_bool.0["errors"].as_array().expect("Expected error array for invalid bool");
|
||||||
assert_eq!(errors_bool.len(), 1, "Expected exactly one error after deduplication");
|
assert_eq!(errors_bool.len(), 1, "Expected exactly one error after deduplication");
|
||||||
assert_eq!(errors_bool[0]["code"], "TYPE_MISMATCH");
|
assert_eq!(errors_bool[0]["code"], "TYPE_MISMATCH");
|
||||||
assert_eq!(errors_bool[0]["details"]["context"]["instance_path"], "");
|
assert_eq!(errors_bool[0]["details"]["path"], "");
|
||||||
|
|
||||||
// --- Test case 4: Fails missing required for both branches ---
|
// --- Test case 4: Fails missing required for both branches ---
|
||||||
// Input: empty object, expected string_prop (branch 0) OR number_prop (branch 1)
|
// Input: empty object, expected string_prop (branch 0) OR number_prop (branch 1)
|
||||||
@ -329,7 +328,7 @@ fn test_validate_json_schema_oneof_validation_errors() {
|
|||||||
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().expect("Expected error array for empty object");
|
||||||
assert_eq!(errors_empty.len(), 1, "Expected exactly one error after filtering empty object");
|
assert_eq!(errors_empty.len(), 1, "Expected exactly one error after filtering empty object");
|
||||||
assert_eq!(errors_empty[0]["code"], "REQUIRED_FIELD_MISSING");
|
assert_eq!(errors_empty[0]["code"], "REQUIRED_FIELD_MISSING");
|
||||||
assert_eq!(errors_empty[0]["details"]["context"]["instance_path"], "");
|
assert_eq!(errors_empty[0]["details"]["path"], "");
|
||||||
// The human message should be generic
|
// The human message should be generic
|
||||||
assert_eq!(errors_empty[0]["message"], "Required field is missing");
|
assert_eq!(errors_empty[0]["message"], "Required field is missing");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user