Codex Handbook
tui/src/chatwidget/tests/status_command_tests.rs 164 lines
use super::*;use assert_matches::assert_matches;#[tokio::test]async fn status_command_renders_immediately_and_refreshes_rate_limits_for_chatgpt_auth() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;    set_chatgpt_auth(&mut chat);    chat.dispatch_command(SlashCommand::Status);    let rendered = match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(cell)) => {            lines_to_single_string(&cell.display_lines(/*width*/ 80))        }        other => panic!("expected status output before refresh request, got {other:?}"),    };    assert!(        !rendered.contains("refreshing limits"),        "expected /status to avoid transient refresh text in terminal history, got: {rendered}"    );    let request_id = match rx.try_recv() {        Ok(AppEvent::RefreshRateLimits {            origin: RateLimitRefreshOrigin::StatusCommand { request_id },        }) => request_id,        other => panic!("expected rate-limit refresh request, got {other:?}"),    };    pretty_assertions::assert_eq!(request_id, 0);}#[tokio::test]async fn status_command_refresh_updates_cached_limits_for_future_status_outputs() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;    set_chatgpt_auth(&mut chat);    chat.dispatch_command(SlashCommand::Status);    match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(_)) => {}        other => panic!("expected status output before refresh request, got {other:?}"),    }    let first_request_id = match rx.try_recv() {        Ok(AppEvent::RefreshRateLimits {            origin: RateLimitRefreshOrigin::StatusCommand { request_id },        }) => request_id,        other => panic!("expected rate-limit refresh request, got {other:?}"),    };    chat.on_rate_limit_snapshot(Some(snapshot(/*percent*/ 92.0)));    chat.finish_status_rate_limit_refresh(first_request_id);    drain_insert_history(&mut rx);    chat.dispatch_command(SlashCommand::Status);    let refreshed = match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(cell)) => {            lines_to_single_string(&cell.display_lines(/*width*/ 80))        }        other => panic!("expected refreshed status output, got {other:?}"),    };    assert!(        refreshed.contains("8% left"),        "expected a future /status output to use refreshed cached limits, got: {refreshed}"    );}#[tokio::test]async fn status_command_renders_immediately_without_rate_limit_refresh() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;    chat.dispatch_command(SlashCommand::Status);    assert_matches!(rx.try_recv(), Ok(AppEvent::InsertHistoryCell(_)));    assert!(        !std::iter::from_fn(|| rx.try_recv().ok())            .any(|event| matches!(event, AppEvent::RefreshRateLimits { .. })),        "non-ChatGPT sessions should not request a rate-limit refresh for /status"    );}#[tokio::test]async fn status_command_uses_catalog_default_reasoning_when_config_empty() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.4")).await;    chat.config.model_reasoning_effort = None;    chat.dispatch_command(SlashCommand::Status);    let rendered = match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(cell)) => {            lines_to_single_string(&cell.display_lines(/*width*/ 80))        }        other => panic!("expected status output, got {other:?}"),    };    assert!(        rendered.contains("gpt-5.4 (reasoning medium, summaries auto)"),        "expected /status to render the catalog default reasoning effort, got: {rendered}"    );}#[tokio::test]async fn status_command_renders_instruction_sources_from_thread_session() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;    chat.instruction_source_paths = vec![chat.config.cwd.join("AGENTS.md")];    chat.dispatch_command(SlashCommand::Status);    let rendered = match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(cell)) => {            lines_to_single_string(&cell.display_lines(/*width*/ 80))        }        other => panic!("expected status output, got {other:?}"),    };    assert!(        rendered.contains("Agents.md"),        "expected /status to render app-server instruction sources, got: {rendered}"    );    assert!(        !rendered.contains("Agents.md  <none>"),        "expected /status to avoid stale <none> when app-server provided instruction sources, got: {rendered}"    );}#[tokio::test]async fn status_command_overlapping_refreshes_update_matching_cells_only() {    let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;    set_chatgpt_auth(&mut chat);    chat.dispatch_command(SlashCommand::Status);    match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(_)) => {}        other => panic!("expected first status output, got {other:?}"),    }    let first_request_id = match rx.try_recv() {        Ok(AppEvent::RefreshRateLimits {            origin: RateLimitRefreshOrigin::StatusCommand { request_id },        }) => request_id,        other => panic!("expected first refresh request, got {other:?}"),    };    chat.dispatch_command(SlashCommand::Status);    let second_rendered = match rx.try_recv() {        Ok(AppEvent::InsertHistoryCell(cell)) => {            lines_to_single_string(&cell.display_lines(/*width*/ 80))        }        other => panic!("expected second status output, got {other:?}"),    };    let second_request_id = match rx.try_recv() {        Ok(AppEvent::RefreshRateLimits {            origin: RateLimitRefreshOrigin::StatusCommand { request_id },        }) => request_id,        other => panic!("expected second refresh request, got {other:?}"),    };    assert_ne!(first_request_id, second_request_id);    assert!(        !second_rendered.contains("refreshing limits"),        "expected /status to avoid transient refresh text in terminal history, got: {second_rendered}"    );    chat.finish_status_rate_limit_refresh(first_request_id);    pretty_assertions::assert_eq!(chat.refreshing_status_outputs.len(), 1);    chat.on_rate_limit_snapshot(Some(snapshot(/*percent*/ 92.0)));    chat.finish_status_rate_limit_refresh(second_request_id);    assert!(chat.refreshing_status_outputs.is_empty());}