use super::*;
#[test]
fn render_activity_tree_scrolls_to_selected_overflow_item() {
let mut state = MissionControlState::default();
for index in 0..10 {
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new(format!("a{index}")),
parent_id: None,
kind: ActivityKind::Tool,
status: ActivityStatus::Running,
metadata: ActivityMetadata::new(format!("item-{index}")),
});
}
state.selected = 9;
let backend = TestBackend::new(80, 16);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let rendered = terminal
.backend()
.buffer()
.content()
.iter()
.map(|cell| cell.symbol())
.collect::<String>();
assert!(rendered.contains("item-9"));
assert!(!rendered.contains("item-0"));
}
#[test]
fn render_selected_activity_detail_when_activity_selected_after_scrolling() {
let mut state = MissionControlState::default();
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new("a1"),
parent_id: None,
kind: ActivityKind::Tool,
status: ActivityStatus::Running,
metadata: ActivityMetadata::new("bash echo"),
});
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new("a2"),
parent_id: None,
kind: ActivityKind::Tool,
status: ActivityStatus::Success,
metadata: ActivityMetadata::new("read file"),
});
state.selected = 1;
let backend = TestBackend::new(100, 30);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let rendered = terminal
.backend()
.buffer()
.content()
.iter()
.map(|cell| cell.symbol())
.collect::<String>();
assert!(rendered.contains("✓ SUCCESS"));
assert!(rendered.contains("id: a2"));
assert!(rendered.contains("label: read file"));
}
#[test]
fn render_activity_tree_includes_compact_metadata_without_raw_detail_noise() {
let mut state = MissionControlState::default();
let mut metadata = ActivityMetadata::new("bash cargo test");
metadata.detail = Some("bash preview: final output only".to_string());
metadata.fields = vec![
("exit_code".to_string(), "101".to_string()),
("output_lines".to_string(), "12".to_string()),
("timed_out".to_string(), "false".to_string()),
];
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new("tool-1"),
parent_id: None,
kind: ActivityKind::Tool,
status: ActivityStatus::Failed,
metadata,
});
let backend = TestBackend::new(200, 20);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 200, 20), &state);
let rendered = rendered_text_in_area(buffer, layout.activity_tree);
assert!(rendered.contains("bash cargo test • exit 101 • lines 12"));
assert!(!rendered.contains("timed out false"));
assert!(!rendered.contains("final output only"));
}
#[test]
fn render_subagent_activity_tree_includes_identity_metadata() {
let mut state = MissionControlState::default();
let mut metadata = ActivityMetadata::new("g1 • inspect UI");
metadata.fields = vec![("identity".to_string(), "frontend-dev".to_string())];
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new("subagents/g1"),
parent_id: None,
kind: ActivityKind::SubagentTask,
status: ActivityStatus::Running,
metadata,
});
let backend = TestBackend::new(200, 20);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let layout = layout_for(Rect::new(0, 0, 200, 20), &state);
let rendered = rendered_text_in_area(buffer, layout.activity_tree);
assert!(rendered.contains("g1 • inspect UI • identity: frontend-dev"));
}
#[test]
fn render_activity_status_kind_and_selection_styles() {
let mut state = MissionControlState {
focus_pane: crate::tui::state::TuiFocusPane::ActivityTree,
..Default::default()
};
let cases = [
("queued-tool", ActivityStatus::Queued, ActivityKind::Tool),
(
"running-batch",
ActivityStatus::Running,
ActivityKind::SubagentBatch,
),
(
"success-task",
ActivityStatus::Success,
ActivityKind::SubagentTask,
),
(
"failed-assistant",
ActivityStatus::Failed,
ActivityKind::Assistant,
),
(
"canceled-diagnostic",
ActivityStatus::Canceled,
ActivityKind::Diagnostic,
),
];
for (label, status, kind) in cases {
state.apply_activity_event(ActivityEvent::Started {
id: ActivityId::new(label),
parent_id: None,
kind,
status,
metadata: ActivityMetadata::new(label),
});
}
state.selected = 2;
let backend = TestBackend::new(100, 30);
let mut terminal = ratatui::Terminal::new(backend).unwrap();
terminal.draw(|frame| draw(frame, &state)).unwrap();
let buffer = terminal.backend().buffer();
let queued = find_text(buffer, "queued-tool").unwrap();
assert_eq!(buffer[(queued.0 - 4, queued.1)].fg, MATRIX_GREEN.green_dim);
assert_eq!(buffer[(queued.0 - 4, queued.1)].bg, MATRIX_GREEN.background);
assert_eq!(
buffer[(queued.0 - 2, queued.1)].fg,
MATRIX_GREEN.green_bright
);
let running = find_text(buffer, "running-batch").unwrap();
assert_eq!(
buffer[(running.0 - 4, running.1)].fg,
MATRIX_GREEN.green_bright
);
assert_eq!(
buffer[(running.0 - 2, running.1)].fg,
MATRIX_GREEN.cyan_mint
);
let selected = find_text(buffer, "success-task").unwrap();
assert_eq!(buffer[selected].bg, MATRIX_GREEN.selection);
assert_eq!(
buffer[(selected.0 - 4, selected.1)].fg,
MATRIX_GREEN.green_neon
);
assert_eq!(
buffer[(selected.0 - 4, selected.1)].bg,
MATRIX_GREEN.selection
);
assert_eq!(buffer[(selected.0 - 2, selected.1)].fg, MATRIX_GREEN.mint);
let failed = find_text(buffer, "failed-assistant").unwrap();
assert_eq!(
buffer[(failed.0 - 4, failed.1)].fg,
MATRIX_GREEN.lavender_cool
);
assert_eq!(buffer[(failed.0 - 4, failed.1)].bg, MATRIX_GREEN.error_bg);
assert_eq!(buffer[(failed.0 - 2, failed.1)].fg, MATRIX_GREEN.green_neon);
let canceled = find_text(buffer, "canceled-diagnostic").unwrap();
assert_eq!(
buffer[(canceled.0 - 4, canceled.1)].fg,
MATRIX_GREEN.green_dim
);
assert_eq!(
buffer[(canceled.0 - 2, canceled.1)].fg,
MATRIX_GREEN.lavender_cool
);
}