magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::super::*;
use super::support::*;

#[test]
fn active_modals_ignore_layout_shortcuts() {
    let modal_key = modified_key(KeyCode::Right, KeyModifiers::CONTROL | KeyModifiers::SHIFT);

    let mut session = MissionControlState::default();
    session.open_session_picker(
        vec![crate::tui::state::SessionPickerRow {
            id: "session-a".into(),
            label: "session-a".into(),
            is_current: false,
            preview: None,
        }],
        1,
    );
    handle_key(modal_key, &mut session);
    assert_eq!(
        session.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut skills = MissionControlState::default();
    skills.open_skills_modal(
        vec![crate::tui::state::SkillToggleRow {
            name: "skill-a".into(),
            source: "test".to_string(),
            enabled: true,
        }],
        1,
    );
    handle_key(modal_key, &mut skills);
    assert_eq!(
        skills.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut subagents = MissionControlState::default();
    subagents.open_subagents_modal(
        vec![crate::tui::state::SubagentProfileToggleRow {
            id: "agent-a".into(),
            description: "Agent A".into(),
            enabled: true,
        }],
        1,
    );
    handle_key(modal_key, &mut subagents);
    assert_eq!(
        subagents.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut mcp = MissionControlState::default();
    mcp.open_mcp_modal(
        vec![crate::tui::state::McpServerToggleRow {
            name: "server-a".into(),
            kind: "stdio",
            enabled: true,
        }],
        1,
    );
    handle_key(modal_key, &mut mcp);
    assert_eq!(
        mcp.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut system = MissionControlState::default();
    system.open_system_prompt_modal("modal".into());
    handle_key(modal_key, &mut system);
    assert_eq!(
        system.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut connect = MissionControlState::default();
    connect.open_connect_provider(
        vec![crate::tui::state::LoginProviderEntry {
            id: "openai-codex".into(),
            label: "OpenAI Codex".into(),
            description: String::new(),
            status: String::new(),
        }],
        None,
    );
    handle_key(modal_key, &mut connect);
    assert_eq!(
        connect.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut oauth = MissionControlState::default();
    oauth.open_connect_provider(Vec::new(), None);
    oauth.start_connect_oauth("openai-codex".into());
    handle_key(modal_key, &mut oauth);
    assert_eq!(
        oauth.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );

    let mut model = MissionControlState {
        provider: "openai-codex".to_string(),
        model: "gpt-a".to_string(),
        ..Default::default()
    };
    model.open_model_picker(
        vec![crate::model_catalog::ModelCatalogEntry::new_codex("gpt-a")],
        std::collections::BTreeSet::new(),
        None,
        1,
    );
    handle_key(modal_key, &mut model);
    assert_eq!(
        model.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );
}

#[test]
fn mcp_modal_enter_toggles_selected_server() {
    let mut state = MissionControlState::default();
    state.open_mcp_modal(
        vec![
            crate::tui::state::McpServerToggleRow {
                name: "server-a".into(),
                kind: "stdio",
                enabled: true,
            },
            crate::tui::state::McpServerToggleRow {
                name: "server-b".into(),
                kind: "http",
                enabled: false,
            },
        ],
        2,
    );

    assert_eq!(
        handle_key(key(KeyCode::Down), &mut state),
        InputAction::None
    );
    assert_eq!(
        handle_key(key(KeyCode::Enter), &mut state),
        InputAction::SetMcpServerEnabled {
            name: "server-b".into(),
            enabled: true
        }
    );
}

#[test]
fn active_modals_ignore_pane_focus_shortcuts() {
    let pane_focus_key = modified_key(KeyCode::Char('1'), KeyModifiers::ALT);
    let mut state = MissionControlState {
        focus_pane: crate::tui::state::TuiFocusPane::Prompt,
        ..Default::default()
    };
    state.open_session_picker(
        vec![crate::tui::state::SessionPickerRow {
            id: "session-a".into(),
            label: "session-a".into(),
            is_current: false,
            preview: None,
        }],
        1,
    );

    handle_key(pane_focus_key, &mut state);

    assert!(state.is_prompt_focused());
    assert!(state.session_picker_visible());
}

#[test]
fn modal_priority_prefers_session_picker_over_later_modals() {
    let mut state = MissionControlState::default();
    state.open_skills_modal(
        vec![crate::tui::state::SkillToggleRow {
            name: "skill-a".to_string(),
            source: "test".to_string(),
            enabled: true,
        }],
        1,
    );
    state.open_session_picker(
        vec![crate::tui::state::SessionPickerRow {
            id: "session-a".to_string(),
            label: "session-a".to_string(),
            is_current: false,
            preview: None,
        }],
        1,
    );

    assert!(matches!(
        handle_key(key(KeyCode::Enter), &mut state),
        InputAction::SelectSession(session) if session == "session-a"
    ));
    assert!(!state.session_picker_visible());
    assert!(state.skills_modal_visible());
    assert!(state.modals.skills_modal.as_ref().unwrap().rows[0].enabled);
}

#[test]
fn subagent_viewer_precedes_logout_confirmation_without_confirming_it() {
    let mut state = MissionControlState::default();
    let batch = ActivityId::new("precedence-batch");
    state.apply_activity_event(ActivityEvent::Started {
        id: batch.clone(),
        parent_id: None,
        kind: ActivityKind::SubagentBatch,
        status: ActivityStatus::Running,
        metadata: ActivityMetadata::new("subagents"),
    });
    let first = batch.child("g1");
    let second = batch.child("g2");
    for task in [&first, &second] {
        state.apply_activity_event(ActivityEvent::Started {
            id: task.clone(),
            parent_id: Some(batch.clone()),
            kind: ActivityKind::SubagentTask,
            status: ActivityStatus::Running,
            metadata: ActivityMetadata::new(task.as_str()),
        });
    }
    assert!(state.open_subagent_viewer(batch, first.clone()));
    state.open_logout_confirmation("provider".to_string(), "Provider".to_string());

    assert_eq!(
        state.top_modal(),
        Some(crate::tui::state::ModalKind::SubagentViewer)
    );
    assert_eq!(
        handle_key(key(KeyCode::Enter), &mut state),
        InputAction::None
    );
    assert_eq!(state.subagent_viewer_selected_task_id(), Some(first));
    assert!(state.modals.logout_confirmation.is_some());

    assert_eq!(
        handle_key(key(KeyCode::Right), &mut state),
        InputAction::None
    );
    assert_eq!(state.subagent_viewer_selected_task_id(), Some(second));
    assert!(state.modals.logout_confirmation.is_some());

    assert_eq!(handle_key(key(KeyCode::Esc), &mut state), InputAction::None);
    assert!(!state.subagent_viewer_visible());
    assert!(state.modals.logout_confirmation.is_some());
}