use serde_json::json;
use things3_cli::mcp::test_harness::McpTestHarness;
#[tokio::test]
async fn test_tool_call_missing_arguments() {
let harness = McpTestHarness::new();
let result = harness.call_tool("get_inbox", None).await;
let has_content = result
.content
.iter()
.any(|c| matches!(c, things3_cli::mcp::Content::Text { text } if !text.is_empty()));
assert!(
!result.is_error || has_content,
"Should handle missing arguments gracefully"
);
}
#[tokio::test]
async fn test_tool_call_invalid_arguments_type() {
let harness = McpTestHarness::new();
let invalid_args = json!({
"limit": "not_a_number" });
let result = harness.call_tool("get_inbox", Some(invalid_args)).await;
assert!(
!result.content.is_empty(),
"Should return some content even with invalid args"
);
}
#[tokio::test]
async fn test_nonexistent_tool() {
let harness = McpTestHarness::new();
let result = harness
.call_tool_with_fallback("nonexistent_tool", None)
.await;
assert!(result.is_error, "Should error for non-existent tool");
assert!(!result.content.is_empty(), "Should provide error message");
}
#[tokio::test]
async fn test_tool_with_extreme_limit() {
let harness = McpTestHarness::new();
let args = json!({"limit": 999999});
let result = harness.call_tool("get_inbox", Some(args)).await;
assert!(!result.content.is_empty(), "Should return content or error");
}
#[tokio::test]
async fn test_tool_with_negative_limit() {
let harness = McpTestHarness::new();
let args = json!({"limit": -10});
let result = harness.call_tool("get_inbox", Some(args)).await;
assert!(
!result.content.is_empty(),
"Should return content or error for negative limit"
);
}
#[tokio::test]
async fn test_tool_with_zero_limit() {
let harness = McpTestHarness::new();
let args = json!({"limit": 0});
let result = harness.call_tool("get_inbox", Some(args)).await;
assert!(
!result.content.is_empty(),
"Should return content or error for zero limit"
);
}
#[tokio::test]
async fn test_tool_with_null_arguments() {
let harness = McpTestHarness::new();
let args = json!(null);
let result = harness.call_tool("get_inbox", Some(args)).await;
assert!(
!result.content.is_empty(),
"Should return content or error for null arguments"
);
}
#[tokio::test]
async fn test_tool_with_extra_arguments() {
let harness = McpTestHarness::new();
let args = json!({
"limit": 10,
"unexpected_field": "should be ignored",
"another_field": 12345
});
let result = harness.call_tool("get_inbox", Some(args)).await;
assert!(
!result.is_error,
"Should process normally with extra fields"
);
}
#[tokio::test]
async fn test_rapid_sequential_tool_calls() {
let harness = McpTestHarness::new();
for _ in 0..10 {
let result = harness
.call_tool("get_inbox", Some(json!({"limit": 1})))
.await;
assert!(!result.is_error, "Rapid calls should work without errors");
}
}
#[tokio::test]
async fn test_tool_with_very_long_string_argument() {
let harness = McpTestHarness::new();
let long_query = "a".repeat(10000);
let args = json!({"query": long_query});
let result = harness.call_tool("search_tasks", Some(args)).await;
assert!(!result.content.is_empty(), "Should handle long strings");
}
#[tokio::test]
async fn test_tool_with_deeply_nested_arguments() {
let harness = McpTestHarness::new();
let mut nested = json!({"value": "deep"});
for _ in 0..50 {
nested = json!({"nested": nested});
}
let result = harness.call_tool("get_inbox", Some(nested)).await;
assert!(
!result.content.is_empty(),
"Should handle deeply nested args"
);
}