diff --git a/server/src/router.rs b/server/src/router.rs index 326ae3a..6916b85 100644 --- a/server/src/router.rs +++ b/server/src/router.rs @@ -353,4 +353,58 @@ mod tests { assert_eq!(res_list["id"], 1); assert!(res_list["result"]["tools"].as_array().unwrap().len() > 10); } + + #[tokio::test] + async fn test_tool_call_success_and_error_responses() { + let dir = tempdir().unwrap(); + let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap())); + let handler = MemoryHandler::new(state); + + // 1. Test successful tool call (e.g. read_graph) + let req_success = json!({ + "jsonrpc": "2.0", + "id": 2, + "method": "tools/call", + "params": { + "name": "read_graph", + "arguments": {} + } + }); + let res_success = handler.handle_request(req_success).await.unwrap(); + assert_eq!(res_success["jsonrpc"], "2.0"); + assert_eq!(res_success["id"], 2); + // A successful tool call should return a result with isError: false + assert_eq!(res_success["result"]["isError"], false); + assert!(res_success["result"]["content"].as_array().is_some()); + + // 2. Test tool call semantic failure (e.g. updating a task that does not exist) + let req_fail = json!({ + "jsonrpc": "2.0", + "id": 3, + "method": "tools/call", + "params": { + "name": "update_task_status", + "arguments": { + "id": "nonexistent_task_123", + "status": "in_progress" + } + } + }); + let res_fail = handler.handle_request(req_fail).await.unwrap(); + assert_eq!(res_fail["jsonrpc"], "2.0"); + assert_eq!(res_fail["id"], 3); + // Semantic failures must explicitly return isError: true inside the result to halt the LLM + assert_eq!(res_fail["result"]["isError"], true); + assert!(res_fail["result"]["content"][0]["text"].as_str().unwrap().contains("not found")); + + // 3. Test unknown JSON-RPC method returns JSON-RPC protocol error + let req_unknown = json!({ + "jsonrpc": "2.0", + "id": 4, + "method": "unknown_method_xyz" + }); + let res_unknown = handler.handle_request(req_unknown).await.unwrap(); + assert!(res_unknown.get("error").is_some()); + assert_eq!(res_unknown["error"]["code"], -32601); + } }