codex-mobile-bridge 0.3.15

Remote bridge and service manager for codex-mobile.
Documentation
use serde_json::json;
use tokio::time::{Duration, timeout};

use crate::app_server::AppServerInbound;
use crate::storage::PRIMARY_RUNTIME_ID;

use super::super::events::handle_app_server_message;
use super::support::bootstrap_test_state;

#[tokio::test]
async fn active_thread_status_does_not_render_running_surface() {
    let state = bootstrap_test_state().await;

    timeout(
        Duration::from_secs(2),
        handle_app_server_message(
            &state,
            AppServerInbound::Notification {
                runtime_id: PRIMARY_RUNTIME_ID.to_string(),
                method: "thread/status/changed".to_string(),
                params: json!({
                    "threadId": "thread-running-surface",
                    "statusInfo": {
                        "kind": "active"
                    }
                }),
            },
        ),
    )
    .await
    .expect("处理 active thread/status/changed 超时")
    .expect("处理 active thread/status/changed 失败");

    let snapshots = state
        .thread_render_snapshots
        .lock()
        .expect("thread render snapshots poisoned");
    let snapshot = snapshots
        .get("thread-running-surface")
        .expect("应创建 thread render snapshot");

    assert!(snapshot.status_surface.is_none());
}

#[tokio::test]
async fn failed_thread_status_uses_error_surface_without_interrupt() {
    let state = bootstrap_test_state().await;

    timeout(
        Duration::from_secs(2),
        handle_app_server_message(
            &state,
            AppServerInbound::Notification {
                runtime_id: PRIMARY_RUNTIME_ID.to_string(),
                method: "thread/status/changed".to_string(),
                params: json!({
                    "threadId": "thread-failed-surface",
                    "statusInfo": {
                        "kind": "failed"
                    }
                }),
            },
        ),
    )
    .await
    .expect("处理 failed thread/status/changed 超时")
    .expect("处理 failed thread/status/changed 失败");

    let snapshots = state
        .thread_render_snapshots
        .lock()
        .expect("thread render snapshots poisoned");
    let snapshot = snapshots
        .get("thread-failed-surface")
        .expect("应创建失败状态 snapshot");
    let surface = snapshot
        .status_surface
        .as_ref()
        .expect("失败状态应生成 status surface");

    assert_eq!("error", surface.kind);
    assert_eq!("Failed", surface.header);
    assert!(!surface.interrupt_visible);
}