#[cfg(test)]
mod tests {
use crate::protocol_impl::McpProtocolHandlerImpl;
use crate::transport::{TransportCapabilities, TransportInfo, TransportType};
use serde_json::{json, Value};
use warp::http::HeaderMap;
#[tokio::test]
async fn test_empty_and_null_parameters() {
let mut handler = McpProtocolHandlerImpl::new();
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
handler.handle_message(init).await.unwrap();
let empty_params = json!({
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {}
});
let result = handler.handle_message(empty_params).await.unwrap();
assert!(result.get("error").is_some());
let null_params = json!({
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": null
});
let result = handler.handle_message(null_params).await.unwrap();
assert!(result.get("error").is_some());
}
#[tokio::test]
async fn test_extreme_data_sizes() {
let mut handler = McpProtocolHandlerImpl::new();
let long_string = "a".repeat(1_000_000);
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"clientInfo": {
"name": long_string
}
}
});
let result = handler.handle_message(init).await.unwrap();
assert!(result.get("result").is_some());
let mut deeply_nested = json!({});
let mut current = &mut deeply_nested;
for i in 0..100 {
current[format!("level_{}", i)] = json!({});
current = &mut current[format!("level_{}", i)];
}
current["value"] = json!("deep");
let deep_request = json!({
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "echo",
"arguments": deeply_nested
}
});
let result = handler.handle_message(deep_request).await.unwrap();
assert!(result.get("id").is_some());
}
#[tokio::test]
async fn test_unicode_and_special_characters() {
let mut handler = McpProtocolHandlerImpl::new();
let unicode_tests = vec![
"Hello 世界", "Привет мир", "🚀🔧🌟", "\u{200B}invisible\u{200B}", "line\nbreak\ttab", r#"quotes"and'stuff"#, ];
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"clientInfo": {
"name": unicode_tests[0],
"version": unicode_tests[1]
}
}
});
let result = handler.handle_message(init).await.unwrap();
assert!(result.get("result").is_some());
for (i, test_str) in unicode_tests.iter().enumerate() {
let echo = json!({
"jsonrpc": "2.0",
"id": i + 2,
"method": "tools/call",
"params": {
"name": "echo",
"arguments": {
"message": test_str
}
}
});
let result = handler.handle_message(echo).await.unwrap();
if let Some(result_val) = result.get("result") {
if let Some(content_array) = result_val.get("content").and_then(|c| c.as_array()) {
if let Some(first_content) = content_array.first() {
if let Some(text) = first_content.get("text").and_then(|t| t.as_str()) {
if let Ok(parsed) = serde_json::from_str::<Value>(text) {
if let Some(echo_val) = parsed.get("echo").and_then(|e| e.as_str()) {
assert_eq!(echo_val, *test_str);
}
}
}
}
}
}
}
}
#[tokio::test]
async fn test_malformed_jsonrpc_requests() {
let mut handler = McpProtocolHandlerImpl::new();
let no_jsonrpc = json!({
"id": 1,
"method": "initialize",
"params": {}
});
let result = handler.handle_message(no_jsonrpc).await;
assert!(result.is_err());
let wrong_version = json!({
"jsonrpc": "1.0",
"id": 2,
"method": "initialize",
"params": {}
});
let result = handler.handle_message(wrong_version).await;
assert!(result.is_err());
let numeric_method = json!({
"jsonrpc": "2.0",
"id": 3,
"method": 12345,
"params": {}
});
let result = handler.handle_message(numeric_method).await;
assert!(result.is_err());
let array_id = json!({
"jsonrpc": "2.0",
"id": [1, 2, 3],
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
let result = handler.handle_message(array_id).await.unwrap();
assert_eq!(result["id"], json!([1, 2, 3]));
}
#[test]
fn test_transport_edge_cases() {
let mut headers = HeaderMap::new();
headers.insert("upgrade", "websocket".parse().unwrap());
headers.insert("connection", "close".parse().unwrap());
let capabilities = TransportCapabilities::from_headers(&headers);
assert!(!capabilities.supports_websocket);
let mut headers = HeaderMap::new();
headers.insert("accept", "text/html, application/json, */*".parse().unwrap());
headers.insert("connection", "keep-alive, upgrade".parse().unwrap());
headers.insert("upgrade", "websocket".parse().unwrap());
let capabilities = TransportCapabilities::from_headers(&headers);
assert!(capabilities.supports_websocket);
let capabilities = TransportCapabilities {
supports_websocket: true,
supports_sse: false,
supports_http_only: true,
client_info: Some("test-client".to_string()),
protocol_version: Some("2025-06-18".to_string()),
};
let special_endpoints = vec![
"/mcp/endpoint with spaces",
"/mcp/端点", "/mcp/🚀", "//double//slashes//",
];
for endpoint in special_endpoints {
let info = TransportInfo::new(&capabilities, "test", "1.0", endpoint);
let json = info.to_json();
let transports = json["mcp_server"]["available_transports"].as_object().unwrap();
assert!(transports.contains_key("websocket"));
assert!(transports.contains_key("http"));
}
}
#[tokio::test]
async fn test_concurrent_message_handling() {
let mut handler = McpProtocolHandlerImpl::new();
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
handler.handle_message(init).await.unwrap();
let mut tasks = vec![];
for i in 0..10 {
let request = json!({
"jsonrpc": "2.0",
"id": i + 100,
"method": "tools/list",
"params": {}
});
let req = request.clone();
tasks.push(tokio::spawn(async move {
let mut local_handler = McpProtocolHandlerImpl::new();
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
local_handler.handle_message(init).await.unwrap();
local_handler.handle_message(req).await
}));
}
for task in tasks {
let result = task.await.unwrap().unwrap();
assert!(result.get("result").is_some());
}
}
#[tokio::test]
async fn test_protocol_version_edge_cases() {
let mut handler = McpProtocolHandlerImpl::new();
let empty_version = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": ""
}
});
let result = handler.handle_message(empty_version).await.unwrap();
assert!(result.get("error").is_some());
let whitespace_version = json!({
"jsonrpc": "2.0",
"id": 2,
"method": "initialize",
"params": {
"protocolVersion": " \t\n "
}
});
let result = handler.handle_message(whitespace_version).await.unwrap();
assert!(result.get("error").is_some());
let long_version = json!({
"jsonrpc": "2.0",
"id": 3,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18-experimental-beta-preview-release-candidate-final-v2"
}
});
let result = handler.handle_message(long_version).await.unwrap();
assert!(result.get("error").is_some());
let numeric_version = json!({
"jsonrpc": "2.0",
"id": 4,
"method": "initialize",
"params": {
"protocolVersion": 20250618
}
});
let result = handler.handle_message(numeric_version).await.unwrap();
assert!(result.get("error").is_some());
}
}