Codex Handbook
app-server/tests/suite/v2/windows_sandbox_setup.rs 91 lines
use anyhow::Context;use anyhow::Result;use app_test_support::TestAppServer;use app_test_support::create_mock_responses_server_sequence_unchecked;use app_test_support::to_response;use app_test_support::write_mock_responses_config_toml;use codex_app_server_protocol::JSONRPCResponse;use codex_app_server_protocol::RequestId;use codex_app_server_protocol::WindowsSandboxSetupCompletedNotification;use codex_app_server_protocol::WindowsSandboxSetupMode;use codex_app_server_protocol::WindowsSandboxSetupStartParams;use codex_app_server_protocol::WindowsSandboxSetupStartResponse;use pretty_assertions::assert_eq;use std::collections::BTreeMap;use tempfile::TempDir;use tokio::time::timeout;const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);#[tokio::test]async fn windows_sandbox_setup_start_emits_completion_notification() -> Result<()> {    let responses = Vec::new();    let server = create_mock_responses_server_sequence_unchecked(responses).await;    let codex_home = TempDir::new()?;    write_mock_responses_config_toml(        codex_home.path(),        &server.uri(),        &BTreeMap::new(),        /*auto_compact_limit*/ 500_000,        Some(false),        "mock_provider",        "compact prompt",    )?;    let mut mcp = TestAppServer::new(codex_home.path()).await?;    timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;    let request_id = mcp        .send_windows_sandbox_setup_start_request(WindowsSandboxSetupStartParams {            mode: WindowsSandboxSetupMode::Unelevated,            cwd: None,        })        .await?;    let response: JSONRPCResponse = timeout(        DEFAULT_READ_TIMEOUT,        mcp.read_stream_until_response_message(RequestId::Integer(request_id)),    )    .await??;    let start_payload: WindowsSandboxSetupStartResponse = to_response(response)?;    assert!(start_payload.started);    let notification = timeout(        DEFAULT_READ_TIMEOUT,        mcp.read_stream_until_notification_message("windowsSandbox/setupCompleted"),    )    .await??;    let payload: WindowsSandboxSetupCompletedNotification = serde_json::from_value(        notification            .params            .context("missing windowsSandbox/setupCompleted params")?,    )?;    assert_eq!(payload.mode, WindowsSandboxSetupMode::Unelevated);    Ok(())}#[tokio::test]async fn windows_sandbox_setup_start_rejects_relative_cwd() -> Result<()> {    let codex_home = TempDir::new()?;    let mut mcp = TestAppServer::new(codex_home.path()).await?;    timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;    let request_id = mcp        .send_raw_request(            "windowsSandbox/setupStart",            Some(serde_json::json!({                "mode": "unelevated",                "cwd": "relative-root",            })),        )        .await?;    let err = timeout(        DEFAULT_READ_TIMEOUT,        mcp.read_stream_until_error_message(RequestId::Integer(request_id)),    )    .await??;    assert_eq!(err.error.code, -32600);    assert!(err.error.message.contains("Invalid request"));    Ok(())}