use mcpkit::error::JsonRpcError;
use mcpkit::protocol::{Message, Notification, Request, RequestId, Response};
use serde_json::json;
#[test]
fn test_request_id_number() -> Result<(), Box<dyn std::error::Error>> {
let id = RequestId::Number(42);
let json = serde_json::to_value(&id)?;
assert_eq!(json, json!(42));
let parsed: RequestId = serde_json::from_value(json)?;
assert_eq!(parsed, RequestId::Number(42));
Ok(())
}
#[test]
fn test_request_id_string() -> Result<(), Box<dyn std::error::Error>> {
let id = RequestId::String("request-123".to_string());
let json = serde_json::to_value(&id)?;
assert_eq!(json, json!("request-123"));
let parsed: RequestId = serde_json::from_value(json)?;
assert_eq!(parsed, RequestId::String("request-123".to_string()));
Ok(())
}
#[test]
fn test_request_serialization() -> Result<(), Box<dyn std::error::Error>> {
let request = Request::new("tools/list", 1u64);
let json = serde_json::to_value(&request)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["id"], 1);
assert_eq!(json["method"], "tools/list");
Ok(())
}
#[test]
fn test_request_with_params() -> Result<(), Box<dyn std::error::Error>> {
let request = Request::with_params("tools/call", 1u64, json!({"name": "search"}));
let json = serde_json::to_value(&request)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["id"], 1);
assert_eq!(json["method"], "tools/call");
assert!(json["params"].is_object());
Ok(())
}
#[test]
fn test_response_success() -> Result<(), Box<dyn std::error::Error>> {
let response = Response::success(1u64, json!({"tools": []}));
let json = serde_json::to_value(&response)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["id"], 1);
assert!(json["result"].is_object());
assert!(json.get("error").is_none());
Ok(())
}
#[test]
fn test_response_error() -> Result<(), Box<dyn std::error::Error>> {
let error = JsonRpcError {
code: -32600,
message: "Invalid Request".to_string(),
data: None,
};
let response = Response::error(1u64, error);
let json = serde_json::to_value(&response)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["id"], 1);
assert!(json.get("result").is_none());
assert!(json["error"].is_object());
assert_eq!(json["error"]["code"], -32600);
assert_eq!(json["error"]["message"], "Invalid Request");
Ok(())
}
#[test]
fn test_notification_serialization() -> Result<(), Box<dyn std::error::Error>> {
let notification = Notification::new("notifications/initialized");
let json = serde_json::to_value(¬ification)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["method"], "notifications/initialized");
assert!(json.get("id").is_none()); Ok(())
}
#[test]
fn test_notification_with_params() -> Result<(), Box<dyn std::error::Error>> {
let notification = Notification::with_params("notifications/progress", json!({"progress": 50}));
let json = serde_json::to_value(¬ification)?;
assert_eq!(json["jsonrpc"], "2.0");
assert_eq!(json["method"], "notifications/progress");
assert!(json["params"].is_object());
assert!(json.get("id").is_none());
Ok(())
}
#[test]
fn test_message_parsing() -> Result<(), Box<dyn std::error::Error>> {
let request_json = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
});
let msg: Message = serde_json::from_value(request_json)?;
assert!(matches!(msg, Message::Request(_)));
let response_json = json!({
"jsonrpc": "2.0",
"id": 1,
"result": {"tools": []}
});
let msg: Message = serde_json::from_value(response_json)?;
assert!(matches!(msg, Message::Response(_)));
let notification_json = json!({
"jsonrpc": "2.0",
"method": "notifications/initialized"
});
let msg: Message = serde_json::from_value(notification_json)?;
assert!(matches!(msg, Message::Notification(_)));
Ok(())
}
#[test]
fn test_standard_error_codes() {
let parse_error = JsonRpcError::parse_error("Parse error");
assert_eq!(parse_error.code, -32700);
let invalid_request = JsonRpcError::invalid_request("Invalid Request");
assert_eq!(invalid_request.code, -32600);
let method_not_found = JsonRpcError::method_not_found("Method not found");
assert_eq!(method_not_found.code, -32601);
let invalid_params = JsonRpcError::invalid_params("Invalid params");
assert_eq!(invalid_params.code, -32602);
let internal_error = JsonRpcError::internal_error("Internal error");
assert_eq!(internal_error.code, -32603);
}
#[test]
fn test_request_params_optional() {
let without_params = Request::new("test", 1u64);
assert!(without_params.params.is_none());
let with_params = Request::new("test", 2u64).params(json!({"key": "value"}));
assert!(with_params.params.is_some());
}
#[test]
fn test_batch_not_supported() {
let batch_json = json!([
{"jsonrpc": "2.0", "id": 1, "method": "test"},
{"jsonrpc": "2.0", "id": 2, "method": "test"}
]);
let result: Result<Message, _> = serde_json::from_value(batch_json);
assert!(result.is_err());
}
#[test]
fn test_null_id_handling() {
let json = json!({
"jsonrpc": "2.0",
"id": null,
"method": "test"
});
let result: Result<Request, _> = serde_json::from_value(json);
let _ = result;
}
#[test]
fn test_response_without_result_or_error() {
let valid_success = json!({
"jsonrpc": "2.0",
"id": 1,
"result": null
});
let parsed: Result<Response, _> = serde_json::from_value(valid_success);
assert!(parsed.is_ok());
}
#[test]
fn test_response_is_success_and_is_error() {
let success = Response::success(1u64, json!({}));
assert!(success.is_success());
assert!(!success.is_error());
let error = Response::error(1u64, JsonRpcError::internal_error("error"));
assert!(!error.is_success());
assert!(error.is_error());
}
#[test]
fn test_request_id_from_impls() {
let id: RequestId = 42u64.into();
assert_eq!(id, RequestId::Number(42));
let id: RequestId = "test".to_string().into();
assert_eq!(id, RequestId::String("test".to_string()));
let id: RequestId = "test".into();
assert_eq!(id, RequestId::String("test".to_string()));
}
#[test]
fn test_request_id_display() {
assert_eq!(RequestId::Number(42).to_string(), "42");
assert_eq!(RequestId::String("test".to_string()).to_string(), "test");
}
#[test]
fn test_message_helper_methods() {
let request = Request::new("tools/list", 1u64);
let msg: Message = request.into();
assert!(msg.is_request());
assert!(!msg.is_response());
assert!(!msg.is_notification());
assert_eq!(msg.method(), Some("tools/list"));
assert!(msg.id().is_some());
assert!(msg.as_request().is_some());
assert!(msg.as_response().is_none());
assert!(msg.as_notification().is_none());
}