use super::assertions::render_json_assertion;
use crate::e2e::field_access::FieldResolver;
use crate::e2e::fixture::Assertion;
use std::collections::{HashMap, HashSet};
fn result_payload() -> serde_json::Value {
serde_json::json!({
"completed_count": 2,
"failed_count": 0,
"total_count": 2,
"metrics": { "total_lines": 41 }
})
}
fn resolver() -> FieldResolver {
let result_fields: HashSet<String> = ["completed_count", "failed_count", "total_count", "metrics"]
.into_iter()
.map(String::from)
.collect();
FieldResolver::new(
&HashMap::new(),
&HashSet::new(),
&result_fields,
&HashSet::new(),
&HashSet::new(),
)
}
fn render_equals(field: &str, value: serde_json::Value) -> String {
let assertion = Assertion {
assertion_type: "equals".to_string(),
field: Some(field.to_string()),
value: Some(value),
..Assertion::default()
};
let mut out = String::new();
render_json_assertion(&mut out, &assertion, "result", &resolver(), false);
out
}
fn navigated_keys(rendered: &str) -> Vec<String> {
rendered
.split(".object.get(\"")
.skip(1)
.filter_map(|rest| rest.split_once("\")").map(|(key, _)| key.to_string()))
.collect()
}
fn resolve_keys<'a>(payload: &'a serde_json::Value, keys: &[String]) -> Option<&'a serde_json::Value> {
let mut current = payload;
for key in keys {
current = current.get(key)?;
}
Some(current)
}
#[test]
fn namespace_prefixed_field_navigates_the_real_payload_shape() {
let rendered = render_equals("batch.completed_count", serde_json::json!(2));
let keys = navigated_keys(&rendered);
assert_eq!(
keys,
vec!["completed_count".to_string()],
"the virtual `batch` label must not become a JSON key step; rendered:\n{rendered}"
);
let payload = result_payload();
let found = resolve_keys(&payload, &keys)
.unwrap_or_else(|| panic!("emitted key chain {keys:?} resolves to nothing in the payload"));
assert_eq!(found, &serde_json::json!(2), "the emitted chain read the wrong value");
}
#[test]
fn genuinely_nested_field_keeps_its_full_key_chain() {
let rendered = render_equals("metrics.total_lines", serde_json::json!(41));
let keys = navigated_keys(&rendered);
assert_eq!(
keys,
vec!["metrics".to_string(), "total_lines".to_string()],
"a declared result field must not be stripped as a namespace label; rendered:\n{rendered}"
);
let payload = result_payload();
let found = resolve_keys(&payload, &keys)
.unwrap_or_else(|| panic!("emitted key chain {keys:?} resolves to nothing in the payload"));
assert_eq!(found, &serde_json::json!(41), "the emitted chain read the wrong value");
}
#[test]
fn the_pre_fix_key_chain_resolves_to_nothing() {
let pre_fix = ["batch".to_string(), "completed_count".to_string()];
assert!(
resolve_keys(&result_payload(), &pre_fix).is_none(),
"the buggy key chain must not resolve — otherwise the payload checks are vacuous"
);
}