#[cfg(test)]
mod tests {
use crate::protocol_impl::McpProtocolHandlerImpl;
use serde_json::{json, Value};
#[tokio::test]
async fn test_valid_jsonrpc_request_parsing() {
let mut handler = McpProtocolHandlerImpl::new();
let valid_request = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {}
}
});
let result = handler.handle_message(valid_request).await;
assert!(result.is_ok());
let response = result.unwrap();
assert_eq!(response["jsonrpc"], "2.0");
assert_eq!(response["id"], 1);
assert!(response.get("result").is_some());
}
#[tokio::test]
async fn test_missing_required_fields() {
let mut handler = McpProtocolHandlerImpl::new();
let missing_jsonrpc = json!({
"id": 1,
"method": "initialize",
"params": {}
});
let result = handler.handle_message(missing_jsonrpc).await;
match result {
Ok(response) => {
assert!(response.get("error").is_some());
}
Err(_) => {
}
}
let missing_method = json!({
"jsonrpc": "2.0",
"id": 1,
"params": {}
});
let result = handler.handle_message(missing_method).await;
match result {
Ok(response) => {
assert!(response.get("error").is_some());
}
Err(_) => {
}
}
}
#[tokio::test]
async fn test_id_type_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 numeric_id = json!({
"jsonrpc": "2.0",
"id": 42,
"method": "tools/list",
"params": {}
});
let result = handler.handle_message(numeric_id).await.unwrap();
assert_eq!(result["id"], 42);
let string_id = json!({
"jsonrpc": "2.0",
"id": "test-id-123",
"method": "tools/list",
"params": {}
});
let result = handler.handle_message(string_id).await.unwrap();
assert_eq!(result["id"], "test-id-123");
let null_id = json!({
"jsonrpc": "2.0",
"id": null,
"method": "notifications/initialized",
"params": {}
});
let result = handler.handle_message(null_id).await.unwrap();
assert_eq!(result["id"], Value::Null);
}
#[tokio::test]
async fn test_parameter_validation() {
let mut handler = McpProtocolHandlerImpl::new();
let valid_init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": {
"listChanged": true
}
},
"clientInfo": {
"name": "test-client",
"version": "1.0.0"
}
}
});
let result = handler.handle_message(valid_init).await.unwrap();
assert!(result.get("result").is_some());
let empty_params = json!({
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
});
let result = handler.handle_message(empty_params).await.unwrap();
assert!(result.get("result").is_some());
let no_params = json!({
"jsonrpc": "2.0",
"id": 3,
"method": "tools/list"
});
let result = handler.handle_message(no_params).await.unwrap();
assert!(result.get("result").is_some());
}
#[tokio::test]
async fn test_protocol_version_negotiation() {
let mut handler = McpProtocolHandlerImpl::new();
let supported_version = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
let result = handler.handle_message(supported_version).await.unwrap();
assert_eq!(result["result"]["protocolVersion"], "2025-06-18");
let mut handler2 = McpProtocolHandlerImpl::new();
let supported_version2 = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26"
}
});
let result = handler2.handle_message(supported_version2).await.unwrap();
assert_eq!(result["result"]["protocolVersion"], "2025-03-26");
let mut handler3 = McpProtocolHandlerImpl::new();
let unsupported_version = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-01-01"
}
});
let result = handler3.handle_message(unsupported_version).await.unwrap();
assert!(result.get("error").is_some());
assert_eq!(result["error"]["code"], -32603); }
#[tokio::test]
async fn test_notification_handling() {
let mut handler = McpProtocolHandlerImpl::new();
let cancel_notification = json!({
"jsonrpc": "2.0",
"method": "notifications/cancel",
"params": {
"requestId": "some-request"
}
});
let result = handler.handle_message(cancel_notification).await.unwrap();
assert!(result.get("id").is_none() || result.get("id") == Some(&Value::Null));
let init = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18"
}
});
handler.handle_message(init).await.unwrap();
let initialized_notification = json!({
"jsonrpc": "2.0",
"method": "notifications/initialized"
});
let result = handler
.handle_message(initialized_notification)
.await
.unwrap();
assert!(result.as_object().unwrap().is_empty() || result.get("id").is_some());
}
#[tokio::test]
async fn test_batch_request_rejection() {
let mut handler = McpProtocolHandlerImpl::new();
let batch_request = json!([
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
},
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}
]);
let _result = handler.handle_message(batch_request).await;
}
#[tokio::test]
async fn test_malformed_json_handling() {
let mut handler = McpProtocolHandlerImpl::new();
let invalid_id_type = json!({
"jsonrpc": "2.0",
"id": {"invalid": "object"},
"method": "initialize",
"params": {}
});
let result = handler.handle_message(invalid_id_type).await;
assert!(result.is_ok());
let invalid_method_type = json!({
"jsonrpc": "2.0",
"id": 1,
"method": 123, "params": {}
});
let result = handler.handle_message(invalid_method_type).await;
assert!(result.is_err() || result.unwrap().get("error").is_some());
}
#[tokio::test]
async fn test_large_message_handling() {
let mut handler = McpProtocolHandlerImpl::new();
let mut large_data = Vec::new();
for i in 0..1000 {
large_data.push(format!("item_{i}"));
}
let large_message = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "test-client",
"version": "1.0.0",
"metadata": large_data
}
}
});
let result = handler.handle_message(large_message).await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_message_ordering() {
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 requests = vec![
json!({
"jsonrpc": "2.0",
"id": 100,
"method": "tools/list",
"params": {}
}),
json!({
"jsonrpc": "2.0",
"id": 200,
"method": "tools/list",
"params": {}
}),
json!({
"jsonrpc": "2.0",
"id": 300,
"method": "tools/list",
"params": {}
}),
];
let mut responses = Vec::new();
for request in requests {
let response = handler.handle_message(request).await.unwrap();
responses.push(response);
}
assert_eq!(responses[0]["id"], 100);
assert_eq!(responses[1]["id"], 200);
assert_eq!(responses[2]["id"], 300);
}
}