use tempfile::tempdir;
use super::{AGENT, step_dir, write_file, write_tool};
use crate::steps_view::{Doc, detail};
#[test]
fn detail_parses_records_splits_response_and_derives_tool_is_error() {
let dir = tempdir().unwrap();
let ws = dir.path();
write_file(ws, "001", "meta.json", br#"{"commit":"c"}"#);
write_file(ws, "001", "request.json", br#"{"model":"opus"}"#);
write_file(
ws,
"001",
"staging.json",
br#"[{"type":"text","text":"hi"}]"#,
);
write_file(
ws,
"001",
"response.json",
b"{\"type\":\"message_start\"}\nnot json\n{\"type\":\"end\"}\n",
);
write_tool(ws, "001", "toolu_1", b"{}", Some(br#"{"exit_code":0}"#));
write_tool(ws, "001", "toolu_2", b"{}", Some(br#"{"exit_code":2}"#));
write_tool(ws, "001", "toolu_0", b"{}", Some(b"oops"));
write_tool(ws, "001", "toolu_3", b"{}", Some(br#"{"stdout":"x"}"#));
std::fs::write(step_dir(ws, "001").join("tools").join(".keep"), b"").unwrap();
let d = detail(ws, AGENT, "001");
assert!(matches!(d.meta, Doc::Json { .. }));
assert!(matches!(d.request, Doc::Json { .. }));
assert!(matches!(d.staging, Doc::Json { .. }));
assert_eq!(d.response.len(), 3);
assert!(matches!(d.response[0], Doc::Json { .. }));
assert_eq!(d.response[1], Doc::Unparsed(b"not json".to_vec()));
assert!(matches!(d.response[2], Doc::Json { .. }));
let ids: Vec<&str> = d.tools.iter().map(|t| t.tool_id.as_str()).collect();
assert_eq!(ids, vec!["toolu_0", "toolu_1", "toolu_2", "toolu_3"]);
let errs: Vec<bool> = d.tools.iter().map(|t| t.is_error).collect();
assert_eq!(errs, vec![false, false, true, false]);
assert_eq!(d.tools[0].output, Doc::Unparsed(b"oops".to_vec()));
}
#[test]
fn a_malformed_record_is_unparsed_not_absent_and_siblings_still_build() {
let dir = tempdir().unwrap();
let ws = dir.path();
write_file(ws, "001", "request.json", b"{ this is not json");
write_file(ws, "001", "meta.json", br#"{"commit":"c0ffee"}"#);
write_file(ws, "001", "staging.json", b" \n");
let d = detail(ws, AGENT, "001");
assert_eq!(
d.request,
Doc::Unparsed(b"{ this is not json".to_vec()),
"malformed keeps its bytes AND says it is malformed"
);
assert_eq!(d.staging, Doc::Unparsed(b" \n".to_vec()));
assert!(
matches!(d.meta, Doc::Json { .. }),
"the sibling record parses"
);
assert!(d.response.is_empty(), "no response.json ⇒ no events");
}
#[test]
fn detail_is_forgiving_when_every_file_is_absent() {
let dir = tempdir().unwrap();
let d = detail(dir.path(), AGENT, "001");
assert_eq!(d.meta, Doc::Absent);
assert_eq!(d.request, Doc::Absent);
assert_eq!(d.staging, Doc::Absent);
assert!(d.response.is_empty());
assert!(d.tools.is_empty());
assert_eq!(d.seq, "001");
}