use do_memory_core::SelfLearningMemory;
use do_memory_mcp::{MemoryMCPServer, SandboxConfig};
use std::sync::Arc;
#[tokio::test]
async fn test_json_validation() -> Result<(), Box<dyn std::error::Error>> {
println!("๐งช Testing MCP Tools JSON Response Validation\n");
let memory = Arc::new(SelfLearningMemory::new());
let server = MemoryMCPServer::new(SandboxConfig::default(), memory).await?;
let mut test_results = Vec::new();
println!("๐ Testing query_memory tool...");
match test_query_memory(&server).await {
Ok(_) => test_results.push(("query_memory", "PASS", "Valid JSON response".to_string())),
Err(e) => test_results.push(("query_memory", "FAIL", format!("Error: {}", e))),
}
println!("๐ Testing analyze_patterns tool...");
match test_analyze_patterns(&server).await {
Ok(_) => test_results.push((
"analyze_patterns",
"PASS",
"Valid JSON response".to_string(),
)),
Err(e) => test_results.push(("analyze_patterns", "FAIL", format!("Error: {}", e))),
}
println!("๐ Testing list_tools...");
match test_list_tools(&server).await {
Ok(_) => test_results.push(("list_tools", "PASS", "Valid JSON response".to_string())),
Err(e) => test_results.push(("list_tools", "FAIL", format!("Error: {}", e))),
}
println!("\n๐ Test Results Summary");
println!("{}", "=".repeat(50));
let passed = test_results
.iter()
.filter(|(_, status, _)| *status == "PASS")
.count();
let failed = test_results
.iter()
.filter(|(_, status, _)| *status == "FAIL")
.count();
let total = test_results.len();
println!("Total Tests: {}", total);
println!("โ
Passed: {}", passed);
println!("โ Failed: {}", failed);
if failed > 0 {
println!("\nโ Failed Tests:");
for (test, status, details) in &test_results {
if *status == "FAIL" {
println!(" - {}: {}", test, details);
}
}
}
println!("\n{}", "=".repeat(50));
if failed == 0 {
println!("๐ All MCP tools return valid JSON responses!");
} else {
println!("โ ๏ธ Some tests failed. Check the details above.");
panic!("Tests failed");
}
Ok(())
}
async fn test_query_memory(server: &MemoryMCPServer) -> Result<(), Box<dyn std::error::Error>> {
let result = server
.query_memory(
"test query".to_string(),
"testing".to_string(),
Some("code_generation".to_string()),
5,
"relevance".to_string(),
None,
)
.await?;
validate_json_structure(&result, "query_memory")?;
if result.get("episodes").is_none() {
return Err("Missing 'episodes' field".into());
}
if result.get("patterns").is_none() {
return Err("Missing 'patterns' field".into());
}
if result.get("insights").is_none() {
return Err("Missing 'insights' field".into());
}
Ok(())
}
async fn test_analyze_patterns(server: &MemoryMCPServer) -> Result<(), Box<dyn std::error::Error>> {
let result = server
.analyze_patterns("code_generation".to_string(), 0.7, 10, None)
.await?;
validate_json_structure(&result, "analyze_patterns")?;
if result.get("patterns").is_none() {
return Err("Missing 'patterns' field".into());
}
if result.get("statistics").is_none() {
return Err("Missing 'statistics' field".into());
}
Ok(())
}
async fn test_list_tools(server: &MemoryMCPServer) -> Result<(), Box<dyn std::error::Error>> {
let tools = server.list_tools().await;
for tool in &tools {
if tool.name.is_empty() {
return Err("Tool missing name".into());
}
if tool.description.is_empty() {
return Err("Tool missing description".into());
}
let _: serde_json::Value = serde_json::from_value(tool.input_schema.clone())?;
}
if tools.len() < 3 {
return Err(format!("Expected at least 3 tools, got {}", tools.len()).into());
}
Ok(())
}
fn validate_json_structure(
value: &serde_json::Value,
test_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let serialized = serde_json::to_string(value)?;
let _: serde_json::Value = serde_json::from_str(&serialized)?;
if !value.is_object() {
return Err(format!("{}: Expected JSON object, got {}", test_name, value).into());
}
Ok(())
}