use super::*;
#[test]
fn view_image_card_projects_running_and_success_contract() {
let running = view_image_card_state(
"view-image-running",
ActivityStatus::Running,
serde_json::json!({"path":"images/pending.png","prompt":"never display this prompt"}),
serde_json::json!({}),
"",
);
let card = &project_cards(&running)[0];
assert_eq!(card.role, TranscriptCardRole::ViewImage);
assert_eq!(card.title, "View Image");
assert_eq!(card.metadata, vec!["images/pending.png"]);
assert!(card.body.is_empty());
assert!(!visual_text(&running).contains("never display this prompt"));
let success = view_image_card_state(
"view-image-success",
ActivityStatus::Success,
serde_json::json!({"path":"relative-request.png","prompt":"private prompt"}),
serde_json::json!({
"path":"/tmp/resolved.png",
"provider":"openai",
"model":"vision-model",
"media_type":"image/png",
"image_bytes":1234,
"prompt_chars":14,
"truncated":true
}),
"line one\nline two\nline three\nline four\nline five\nline six",
);
let card = &project_cards(&success)[0];
assert_eq!(card.title, "View Image");
assert_eq!(
card.metadata,
vec![
"/tmp/resolved.png",
"provider openai",
"model vision-model",
"1234 bytes",
"prompt 14 chars",
"response truncated",
]
);
assert!(!visual_text(&success).contains("private prompt"));
}
#[test]
fn view_image_card_bounds_failures_and_sanitizes_untrusted_text() {
let secret = "view-image-secret-value";
for (status, title) in [
(ActivityStatus::Failed, "View Image"),
(ActivityStatus::Canceled, "View Image • canceled"),
] {
let state = view_image_card_state(
title,
status,
serde_json::json!({"path":format!("token={secret}\u{1b}[31m.png")}),
serde_json::json!({"model":format!("authorization: Bearer {secret}")}),
&format!("authorization: Bearer {secret}\u{1b}[2J\ninternal trace"),
);
let card = &project_cards(&state)[0];
assert_eq!(card.title, title);
assert_eq!(card.body, "authorization: <redacted> <redacted>");
assert!(!card.body.contains('\n'));
let visible = visual_text(&state);
assert!(!visible.contains(secret));
assert!(!visible.contains('\u{1b}'));
}
}