From 5061fe7714f764c12cc151d1d4256aed01810239 Mon Sep 17 00:00:00 2001 From: Alex Zamoshchin Date: Mon, 15 Jun 2026 11:54:55 -0700 Subject: [PATCH] Add app approval link ID integration coverage --- .../core/tests/common/apps_test_server.rs | 2 ++ .../core/tests/suite/mcp_turn_metadata.rs | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/codex-rs/core/tests/common/apps_test_server.rs b/codex-rs/core/tests/common/apps_test_server.rs index 7f7873e30b..9b878265cd 100644 --- a/codex-rs/core/tests/common/apps_test_server.rs +++ b/codex-rs/core/tests/common/apps_test_server.rs @@ -43,6 +43,7 @@ pub const CALENDAR_CREATE_EVENT_RESOURCE_URI: &str = "connector://calendar/tools/calendar_create_event"; pub const CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI: &str = "ui://widget/calendar-create-event.html"; +pub const CALENDAR_CREATE_EVENT_LINK_ID: &str = "link_calendar_primary"; const CALENDAR_LIST_EVENTS_RESOURCE_URI: &str = "connector://calendar/tools/calendar_list_events"; pub const DOCUMENT_EXTRACT_TEXT_RESOURCE_URI: &str = "connector://calendar/tools/calendar_extract_text"; @@ -355,6 +356,7 @@ impl Respond for CodexAppsJsonRpcResponder { "connector_id": CONNECTOR_ID, "connector_name": self.connector_name.clone(), "connector_description": self.connector_description.clone(), + "link_id": CALENDAR_CREATE_EVENT_LINK_ID, "openai/outputTemplate": CALENDAR_CREATE_EVENT_MCP_APP_RESOURCE_URI, "_codex_apps": { "resource_uri": CALENDAR_CREATE_EVENT_RESOURCE_URI, diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 21b277bca4..886711caaa 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -5,6 +5,7 @@ use anyhow::Result; use codex_config::types::AppToolApproval; use codex_core::config::Config; use codex_features::Feature; +use codex_protocol::approvals::ElicitationRequest; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::ModeKind; @@ -19,6 +20,7 @@ use codex_protocol::request_user_input::RequestUserInputResponse; use codex_protocol::user_input::UserInput; use core_test_support::PathExt; use core_test_support::apps_test_server::AppsTestServer; +use core_test_support::apps_test_server::CALENDAR_CREATE_EVENT_LINK_ID; use core_test_support::apps_test_server::SEARCH_CALENDAR_CREATE_TOOL; use core_test_support::apps_test_server::SEARCH_CALENDAR_NAMESPACE; use core_test_support::apps_test_server::recorded_apps_tool_call_by_call_id; @@ -127,7 +129,7 @@ async fn submit_user_turn( } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn approved_mcp_tool_call_metadata_records_prior_user_input_request() -> Result<()> { +async fn approved_mcp_tool_call_forwards_link_id_and_records_user_input() -> Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; @@ -203,6 +205,34 @@ async fn approved_mcp_tool_call_metadata_records_prior_user_input_request() -> R panic!("expected apps._default user to route the app approval to the user"); }; + let ElicitationRequest::Form { meta, .. } = &request.request else { + panic!("expected form elicitation for the app tool approval"); + }; + assert_eq!( + meta, + &Some(json!({ + "codex_approval_kind": "mcp_tool_call", + "source": "connector", + "connector_id": "calendar", + "connector_name": "Calendar", + "link_id": CALENDAR_CREATE_EVENT_LINK_ID, + "tool_description": "Create a calendar event.", + "tool_params": { + "title": "Lunch", + "starts_at": "2026-03-10T12:00:00Z" + }, + "tool_params_display": [{ + "name": "starts_at", + "value": "2026-03-10T12:00:00Z", + "display_name": "starts_at" + }, { + "name": "title", + "value": "Lunch", + "display_name": "title" + }] + })) + ); + test.codex .submit(Op::ResolveElicitation { server_name: request.server_name,