use serde_json::Value;
pub fn assert_json_structure_matches(actual: &Value, expected: &Value, path: &str) {
match (actual, expected) {
(Value::Object(actual_map), Value::Object(expected_map)) => {
for (key, expected_value) in expected_map {
let current_path = if path.is_empty() {
key.clone()
} else {
format!("{}.{}", path, key)
};
if is_dynamic_field(key) {
continue;
}
let actual_value = actual_map.get(key).expect(&format!(
"Missing field '{}' in actual response at path '{}'",
key, current_path
));
assert_json_structure_matches(actual_value, expected_value, ¤t_path);
}
}
(Value::Array(actual_arr), Value::Array(expected_arr)) => {
assert_eq!(
actual_arr.len(),
expected_arr.len(),
"Array length mismatch at path '{}'",
path
);
for (i, (actual_item, expected_item)) in
actual_arr.iter().zip(expected_arr.iter()).enumerate()
{
let current_path = format!("{}[{}]", path, i);
assert_json_structure_matches(actual_item, expected_item, ¤t_path);
}
}
(Value::String(_), Value::String(_)) => {
if !is_dynamic_field(path) {
assert_eq!(
actual, expected,
"String value mismatch at path '{}'",
path
);
}
}
(Value::Number(_), Value::Number(_)) => {
if !is_dynamic_field(path) {
assert_eq!(
actual, expected,
"Number value mismatch at path '{}'",
path
);
}
}
(Value::Bool(actual_bool), Value::Bool(expected_bool)) => {
assert_eq!(
actual_bool, expected_bool,
"Boolean value mismatch at path '{}'",
path
);
}
(Value::Null, Value::Null) => {
}
_ => {
panic!(
"Type mismatch at path '{}': actual = {:?}, expected = {:?}",
path, actual, expected
);
}
}
}
fn is_dynamic_field(field: &str) -> bool {
let dynamic_fields = [
"timestamp",
"genome_timestamp",
"connectome_path",
"neuron_count", "synapse_count", "cortical_area_count", ];
dynamic_fields.iter().any(|f| field.contains(f))
}
pub fn assert_success_response(response: &Value) {
assert_eq!(
response.get("success").and_then(|v| v.as_bool()),
Some(true),
"Response should have success: true"
);
assert!(
response.get("data").is_some(),
"Successful response should have 'data' field"
);
assert!(
response.get("timestamp").is_some(),
"Response should have 'timestamp' field"
);
}
pub fn assert_error_response(response: &Value, expected_code: u16) {
assert_eq!(
response.get("code").and_then(|v| v.as_u64()),
Some(expected_code as u64),
"Error response should have correct status code"
);
assert!(
response.get("message").is_some(),
"Error response should have 'message' field"
);
}