Codex Handbook
core/src/session/mcp_tests.rs 269 lines
use super::*;use rmcp::model::BooleanSchema;use rmcp::model::ElicitationSchema;use rmcp::model::PrimitiveSchema;use serde_json::json;fn meta(value: Value) -> Option<Meta> {    let Value::Object(map) = value else {        panic!("metadata must be an object");    };    Some(Meta(map))}fn guardian_meta(tool_params: Option<Value>) -> Option<Meta> {    let mut value = json!({        "codex_approval_kind": "mcp_tool_call",        "codex_request_type": "approval_request",        "connector_id": "browser-use",        "connector_name": "Browser Use",        "tool_name": "access_browser_origin",        "tool_title": "Access browser origin",    });    if let Some(tool_params) = tool_params {        value["tool_params"] = tool_params;    }    meta(value)}fn form_request(meta: Option<Meta>) -> ElicitationReviewRequest {    ElicitationReviewRequest {        server_name: "browser-use".to_string(),        request_id: rmcp::model::NumberOrString::Number(7),        elicitation: CreateElicitationRequestParams::FormElicitationParams {            meta,            message: "Allow origin?".to_string(),            requested_schema: ElicitationSchema::builder()                .build()                .expect("schema should build"),        },    }}#[test]fn guardian_elicitation_review_request_builds_mcp_tool_call() {    let request = form_request(guardian_meta(Some(json!({        "origin": "https://example.com",    }))));    let GuardianElicitationReview::ApprovalRequest(guardian_request) =        guardian_elicitation_review_request(&request)    else {        panic!("expected Guardian MCP tool call request");    };    let crate::guardian::GuardianApprovalRequest::McpToolCall {        id,        server,        tool_name,        arguments,        connector_id,        connector_name,        connector_description,        tool_title,        tool_description,        annotations,    } = *guardian_request    else {        panic!("expected Guardian MCP tool call request");    };    assert_eq!(id, "mcp_elicitation:browser-use:7");    assert_eq!(server, "browser-use");    assert_eq!(tool_name, "access_browser_origin");    assert_eq!(arguments, Some(json!({ "origin": "https://example.com" })));    assert_eq!(connector_id.as_deref(), Some("browser-use"));    assert_eq!(connector_name.as_deref(), Some("Browser Use"));    assert_eq!(connector_description, None);    assert_eq!(tool_title.as_deref(), Some("Access browser origin"));    assert_eq!(tool_description, None);    assert_eq!(annotations, None);}#[test]fn guardian_elicitation_review_request_defaults_missing_tool_params() {    let request = form_request(guardian_meta(/*tool_params*/ None));    let GuardianElicitationReview::ApprovalRequest(guardian_request) =        guardian_elicitation_review_request(&request)    else {        panic!("expected Guardian MCP tool call request");    };    let crate::guardian::GuardianApprovalRequest::McpToolCall { arguments, .. } = *guardian_request    else {        panic!("expected Guardian MCP tool call request");    };    assert_eq!(arguments, Some(json!({})));}#[test]fn plugin_install_elicitation_telemetry_metadata_requires_install_tool_suggestion() {    let event = EventMsg::ElicitationRequest(ElicitationRequestEvent {        turn_id: Some("turn-1".to_string()),        server_name: "codex_apps".to_string(),        id: codex_protocol::mcp::RequestId::String("request-1".to_string()),        request: codex_protocol::approvals::ElicitationRequest::Form {            meta: Some(json!({                "codex_approval_kind": "tool_suggestion",                "suggest_type": "install",                "tool_type": "plugin",                "tool_id": "slack@openai-curated",                "tool_name": "Slack",            })),            message: "Install Slack?".to_string(),            requested_schema: json!({                "type": "object",                "properties": {},            }),        },    });    assert_eq!(        plugin_install_elicitation_telemetry_metadata(&event),        Some(PluginInstallElicitationTelemetryMetadata {            tool_type: "plugin".to_string(),            tool_id: "slack@openai-curated".to_string(),            tool_name: "Slack".to_string(),        })    );    let enable_event = EventMsg::ElicitationRequest(ElicitationRequestEvent {        turn_id: Some("turn-1".to_string()),        server_name: "codex_apps".to_string(),        id: codex_protocol::mcp::RequestId::String("request-2".to_string()),        request: codex_protocol::approvals::ElicitationRequest::Form {            meta: Some(json!({                "codex_approval_kind": "tool_suggestion",                "suggest_type": "enable",                "tool_type": "plugin",                "tool_id": "slack@openai-curated",                "tool_name": "Slack",            })),            message: "Enable Slack?".to_string(),            requested_schema: json!({                "type": "object",                "properties": {},            }),        },    });    assert_eq!(        plugin_install_elicitation_telemetry_metadata(&enable_event),        None    );}#[test]fn guardian_elicitation_review_request_requires_opt_in() {    let request = form_request(meta(json!({        "codex_approval_kind": "mcp_tool_call",        "tool_name": "access_browser_origin",    })));    assert_eq!(        guardian_elicitation_review_request(&request),        GuardianElicitationReview::NotRequested    );}#[test]fn guardian_elicitation_review_request_declines_unsupported_opt_in_shapes() {    let url_request = ElicitationReviewRequest {        server_name: "browser-use".to_string(),        request_id: rmcp::model::NumberOrString::Number(8),        elicitation: CreateElicitationRequestParams::UrlElicitationParams {            meta: guardian_meta(Some(json!({}))),            message: "Open URL".to_string(),            url: "https://example.com".to_string(),            elicitation_id: "elicit-1".to_string(),        },    };    assert!(matches!(        guardian_elicitation_review_request(&url_request),        GuardianElicitationReview::Decline(_)    ));    let non_empty_schema_request = ElicitationReviewRequest {        server_name: "browser-use".to_string(),        request_id: rmcp::model::NumberOrString::Number(9),        elicitation: CreateElicitationRequestParams::FormElicitationParams {            meta: guardian_meta(Some(json!({}))),            message: "Allow origin?".to_string(),            requested_schema: ElicitationSchema::builder()                .required_property("confirmed", PrimitiveSchema::Boolean(BooleanSchema::new()))                .build()                .expect("schema should build"),        },    };    assert!(matches!(        guardian_elicitation_review_request(&non_empty_schema_request),        GuardianElicitationReview::Decline(_)    ));    let missing_tool_name_request = form_request(meta(json!({        "codex_approval_kind": "mcp_tool_call",        "codex_request_type": "approval_request",    })));    assert!(matches!(        guardian_elicitation_review_request(&missing_tool_name_request),        GuardianElicitationReview::Decline(_)    ));}#[test]fn guardian_decisions_map_to_elicitation_responses_without_session_state() {    assert_eq!(        mcp_elicitation_response_from_guardian_decision_parts(            ReviewDecision::Approved,            /*denial_message*/ None,        ),        ElicitationResponse {            action: ElicitationAction::Accept,            content: Some(json!({})),            meta: Some(json!({                "approvals_reviewer": ApprovalsReviewer::AutoReview,            })),        }    );    assert_eq!(        mcp_elicitation_response_from_guardian_decision_parts(            ReviewDecision::Denied,            Some("Denied by Guardian".to_string()),        ),        ElicitationResponse {            action: ElicitationAction::Decline,            content: None,            meta: Some(json!({                "approvals_reviewer": ApprovalsReviewer::AutoReview,                "message": "Denied by Guardian",            })),        }    );    assert_eq!(        mcp_elicitation_response_from_guardian_decision_parts(            ReviewDecision::TimedOut,            /*denial_message*/ None,        ),        ElicitationResponse {            action: ElicitationAction::Decline,            content: None,            meta: Some(json!({                "approvals_reviewer": ApprovalsReviewer::AutoReview,                "message": crate::guardian::guardian_timeout_message(),            })),        }    );    assert_eq!(        mcp_elicitation_response_from_guardian_decision_parts(            ReviewDecision::Abort,            /*denial_message*/ None,        ),        ElicitationResponse {            action: ElicitationAction::Cancel,            content: None,            meta: Some(json!({                "approvals_reviewer": ApprovalsReviewer::AutoReview,            })),        }    );}