use super::support::*;
use super::*;
#[test]
fn submit_new_rejects_while_provider_run_active() {
let temp = tempfile::TempDir::new().unwrap();
let (sender, receiver) = bounded::<TuiEvent>(4);
let mut app = test_app(&temp, sender);
app.active_run = true;
let mut ui_state = state::MissionControlState::default();
app.submit("/new".to_string(), &mut ui_state, &receiver, test_area());
assert!(app.state.current_session.is_none());
assert_eq!(
ui_state.status,
"cannot start a new session while a prompt is running"
);
assert!(receiver.try_recv().is_err());
}
#[test]
fn submit_new_preserves_queued_controller_events_for_centralized_drain() {
let temp = tempfile::TempDir::new().unwrap();
let (sender, receiver) = bounded::<TuiEvent>(8);
let mut app = test_app(&temp, sender.clone());
let mut ui_state = state::MissionControlState {
..Default::default()
};
ui_state.apply_output_event(&OutputEvent::UserPrompt {
text: "visible old".to_string(),
});
ui_state.apply_activity_event(ActivityEvent::Started {
id: crate::output::ActivityId::new("visible-old-tool"),
parent_id: None,
kind: crate::output::ActivityKind::Tool,
status: crate::output::ActivityStatus::Running,
metadata: crate::output::ActivityMetadata::new("visible old tool"),
});
sender
.send(TuiEvent::Output(OutputEvent::UserPrompt {
text: "queued old".to_string(),
}))
.unwrap();
sender
.send(TuiEvent::Activity(ActivityEvent::Started {
id: crate::output::ActivityId::new("queued-old-tool"),
parent_id: None,
kind: crate::output::ActivityKind::Tool,
status: crate::output::ActivityStatus::Running,
metadata: crate::output::ActivityMetadata::new("queued old tool"),
}))
.unwrap();
sender.send(TuiEvent::Done).unwrap();
sender
.send(TuiEvent::RunFinished {
worker_id: 0,
final_event: None,
})
.unwrap();
app.submit(
" /new ".to_string(),
&mut ui_state,
&receiver,
test_area(),
);
let status = ui_state.status.clone();
assert_eq!(receiver.len(), 4);
assert!(status.starts_with("new session: "));
assert_eq!(ui_state.status, status);
assert!(ui_state.transcript.is_empty());
assert_eq!(ui_state.selected_activity_text(), "No activity selected.");
assert!(ui_state.nodes.is_empty());
assert_eq!(ui_state.help_offset(), 0);
assert!(app.state.current_session.is_some());
assert!(app.worker.is_none());
assert!(!app.active_run);
}
#[test]
fn submit_new_with_args_resets_ui_and_creates_no_worker() {
let temp = tempfile::TempDir::new().unwrap();
let (sender, receiver) = bounded::<TuiEvent>(4);
let mut app = test_app(&temp, sender);
let mut ui_state = state::MissionControlState::default();
ui_state.apply_output_event(&OutputEvent::UserPrompt {
text: "old".to_string(),
});
app.submit(
"/new extra".to_string(),
&mut ui_state,
&receiver,
test_area(),
);
assert!(ui_state.status.starts_with("new session: "));
assert!(ui_state.transcript.is_empty());
assert!(app.state.current_session.is_some());
assert!(app.worker.is_none());
assert!(!app.active_run);
let drained = drain_tui_events(&receiver, &mut ui_state);
assert!(!drained.changed);
assert!(!drained.run_finished);
}
#[test]
fn submit_quit_with_args_creates_no_worker() {
let temp = tempfile::TempDir::new().unwrap();
let (sender, receiver) = bounded::<TuiEvent>(4);
let mut app = test_app(&temp, sender);
let mut ui_state = state::MissionControlState::default();
app.submit(
"/quit extra".to_string(),
&mut ui_state,
&receiver,
test_area(),
);
assert!(app.worker.is_none());
assert!(!app.active_run);
assert!(receiver.try_recv().is_err());
}
#[test]
fn submit_invalid_model_command_reports_error_and_creates_no_worker() {
let temp = tempfile::TempDir::new().unwrap();
let manager = SessionManager::new(temp.path().join("sessions"));
let session = manager.create().unwrap();
let (sender, receiver) = bounded::<TuiEvent>(4);
let mut app = test_app_with_active_session(&temp, sender, Some(session.clone()));
let mut ui_state = state::MissionControlState {
provider: "openai".to_string(),
model: "test-model".to_string(),
..Default::default()
};
app.submit(
"/setmodel gpt-next".to_string(),
&mut ui_state,
&receiver,
test_area(),
);
reap_model_selection_worker(&mut app, &mut ui_state, &receiver);
assert_eq!(
ui_state.status,
"model id must use provider/model-name format"
);
assert!(receiver.try_recv().is_err());
assert!(app.worker.is_none());
assert!(!app.active_run);
let events = session.read_events().unwrap();
assert_eq!(events.len(), 1);
assert_eq!(events[0].event_type, "diagnostic");
assert_eq!(
events[0].payload["message"],
"model id must use provider/model-name format"
);
}