use super::*;
use async_trait::async_trait;
struct MockTransport {
response: Value,
}
#[async_trait]
impl Transport for MockTransport {
async fn request(&self, _method: &str, _params: Option<Value>) -> Result<Value> {
Ok(self.response.clone())
}
async fn notify(&self, _method: &str, _params: Option<Value>) -> Result<()> {
Ok(())
}
async fn shutdown(&self) -> Result<()> {
Ok(())
}
}
fn client_returning(response: Value) -> McpClient {
McpClient::new_for_test(Arc::new(MockTransport { response }), "mock")
}
#[tokio::test]
async fn is_error_result_is_flagged_as_failure_not_cached_as_success() {
let client = client_returning(serde_json::json!({
"content": [{"type": "text", "text": "boom: something failed"}],
"isError": true,
}));
let value = client
.call_tool("explode", serde_json::json!({}))
.await
.unwrap();
assert_eq!(value.get("isError").and_then(|v| v.as_bool()), Some(true));
assert_eq!(value.get("success").and_then(|v| v.as_bool()), Some(false));
}
#[tokio::test]
async fn successful_result_is_flagged_as_success() {
let client = client_returning(serde_json::json!({
"content": [{"type": "text", "text": "all good"}],
"isError": false,
}));
let value = client
.call_tool("ping", serde_json::json!({}))
.await
.unwrap();
assert_eq!(value.get("success").and_then(|v| v.as_bool()), Some(true));
}
#[tokio::test]
async fn non_text_is_error_result_is_flagged_as_failure() {
let client = client_returning(serde_json::json!({
"content": [{"type": "image", "data": "..."}],
"isError": true,
}));
let value = client
.call_tool("shot", serde_json::json!({}))
.await
.unwrap();
assert_eq!(value.get("success").and_then(|v| v.as_bool()), Some(false));
}