Skip to content

Commit 0fbc4bf

Browse files
committed
test(rmcp-client): expose expired OAuth auth status
1 parent b89ce9a commit 0fbc4bf

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

codex-rs/rmcp-client/tests/streamable_http_oauth_startup.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ use std::time::Duration;
44

55
use codex_config::types::OAuthCredentialsStoreMode;
66
use codex_exec_server::Environment;
7+
use codex_rmcp_client::McpAuthStatus;
78
use codex_rmcp_client::RmcpClient;
89
use codex_rmcp_client::StoredOAuthTokens;
910
use codex_rmcp_client::WrappedOAuthTokenResponse;
11+
use codex_rmcp_client::determine_streamable_http_auth_status;
1012
use codex_rmcp_client::save_oauth_tokens;
1113
use oauth2::AccessToken;
1214
use oauth2::RefreshToken;
@@ -33,6 +35,7 @@ const EXPIRED_ACCESS_TOKEN: &str = "expired-access-token";
3335
const REFRESH_TOKEN: &str = "valid-refresh-token";
3436
const REFRESHED_ACCESS_TOKEN: &str = "refreshed-access-token";
3537
const CHILD_SERVER_URL_ENV: &str = "MCP_TEST_OAUTH_STARTUP_SERVER_URL";
38+
const UNREFRESHABLE_SERVER_URL: &str = "https://unrefreshable.example/mcp";
3639

3740
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
3841
async fn refreshes_expired_persisted_token_before_initialize() -> anyhow::Result<()> {
@@ -112,6 +115,59 @@ async fn refreshes_expired_persisted_token_before_initialize() -> anyhow::Result
112115
Ok(())
113116
}
114117

118+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
119+
async fn reports_expired_unrefreshable_credentials_as_not_logged_in() -> anyhow::Result<()> {
120+
let codex_home = TempDir::new()?;
121+
122+
let status = Command::new(std::env::current_exe()?)
123+
.args([
124+
"expired_unrefreshable_auth_status_child",
125+
"--exact",
126+
"--ignored",
127+
"--nocapture",
128+
])
129+
.env("CODEX_HOME", codex_home.path())
130+
.status()
131+
.await?;
132+
133+
assert!(
134+
status.success(),
135+
"expired unrefreshable auth status child failed: {status}"
136+
);
137+
Ok(())
138+
}
139+
140+
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
141+
#[ignore = "spawned by reports_expired_unrefreshable_credentials_as_not_logged_in"]
142+
async fn expired_unrefreshable_auth_status_child() -> anyhow::Result<()> {
143+
let response = OAuthTokenResponse::new(
144+
AccessToken::new(EXPIRED_ACCESS_TOKEN.to_string()),
145+
BasicTokenType::Bearer,
146+
VendorExtraTokenFields::default(),
147+
);
148+
let tokens = StoredOAuthTokens {
149+
server_name: SERVER_NAME.to_string(),
150+
url: UNREFRESHABLE_SERVER_URL.to_string(),
151+
client_id: "test-client-id".to_string(),
152+
token_response: WrappedOAuthTokenResponse(response),
153+
expires_at: Some(0),
154+
};
155+
save_oauth_tokens(SERVER_NAME, &tokens, OAuthCredentialsStoreMode::File)?;
156+
157+
let status = determine_streamable_http_auth_status(
158+
SERVER_NAME,
159+
UNREFRESHABLE_SERVER_URL,
160+
/*bearer_token_env_var*/ None,
161+
/*http_headers*/ None,
162+
/*env_http_headers*/ None,
163+
OAuthCredentialsStoreMode::File,
164+
)
165+
.await?;
166+
167+
assert_eq!(status, McpAuthStatus::NotLoggedIn);
168+
Ok(())
169+
}
170+
115171
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
116172
#[ignore = "spawned by refreshes_expired_persisted_token_before_initialize"]
117173
async fn oauth_startup_child() -> anyhow::Result<()> {

0 commit comments

Comments
 (0)