use mcprs::agent::{AIAgent, MCPError, MCPMessage};
use mcprs::agent_deepseek::DeepSeekAgent;
use mcprs::testing::MockHttpClient;
use mockall::predicate;
use serde_json::json;
fn create_mock_response(body: serde_json::Value) -> reqwest::Response {
reqwest::Response::from(
http::Response::builder()
.status(200)
.body(body.to_string())
.unwrap(),
)
}
#[tokio::test]
async fn test_deepseek_agent_successful_request() {
let mut mock_client = MockHttpClient::new();
mock_client
.expect_post()
.with(
predicate::function(|url: &String| url.contains("chat/completions")),
predicate::always(),
predicate::always(),
)
.times(1)
.return_once(move |_, _, _| {
Ok(create_mock_response(json!({
"id": "resp-1234567890",
"choices": [{
"message": {
"role": "assistant",
"content": "Esta é uma resposta de teste do DeepSeek"
},
"finish_reason": "stop"
}]
})))
});
let agent = DeepSeekAgent::new(
"test-api-key".to_string(),
"https://api.deepseek.ai".to_string(),
"deepseek-chat".to_string(),
Box::new(mock_client),
);
let message = MCPMessage::new(
"deepseek:chat",
json!({ "user_prompt": "Teste da API DeepSeek" }),
);
let result = agent.process_request(message).await.unwrap();
assert_eq!(result.command, "deepseek_response");
assert_eq!(
result.payload["answer"],
"Esta é uma resposta de teste do DeepSeek"
);
assert_eq!(result.payload["id"], "resp-1234567890");
assert_eq!(result.payload["finish_reason"], "stop");
}
#[tokio::test]
async fn test_deepseek_agent_missing_prompt() {
let mock_client = MockHttpClient::new();
let agent = DeepSeekAgent::new(
"test-api-key".to_string(),
"https://api.deepseek.ai".to_string(),
"deepseek-chat".to_string(),
Box::new(mock_client),
);
let message = MCPMessage::new(
"deepseek:chat",
json!({ "wrong_field": "Não tem user_prompt" }),
);
let result = agent.process_request(message).await;
assert!(matches!(result, Err(MCPError::InternalAgentError(_))));
}
#[tokio::test]
async fn test_deepseek_agent_with_parameters() {
let mut mock_client = MockHttpClient::new();
mock_client
.expect_post()
.withf(|_, body, _| {
if let Ok(parsed) = serde_json::from_slice::<serde_json::Value>(body) {
return parsed["temperature"].as_f64().unwrap_or(0.0) == 0.7
&& parsed["max_tokens"].as_u64().unwrap_or(0) == 100;
}
false
})
.return_once(|_, _, _| {
Ok(create_mock_response(json!({
"id": "ds-params-test",
"choices": [{
"message": {
"role": "assistant",
"content": "Resposta com parâmetros customizados"
},
"finish_reason": "stop"
}]
})))
});
let agent = DeepSeekAgent::new(
"test-api-key".to_string(),
"https://api.deepseek.ai".to_string(),
"deepseek-chat".to_string(),
Box::new(mock_client),
);
let message = MCPMessage::new(
"deepseek:chat",
json!({
"user_prompt": "Teste com parâmetros",
"temperature": 0.7,
"max_tokens": 100
}),
);
let result = agent.process_request(message).await.unwrap();
assert_eq!(
result.payload["answer"],
"Resposta com parâmetros customizados"
);
}
#[tokio::test]
async fn test_deepseek_agent_api_error() {
let mut mock_client = MockHttpClient::new();
mock_client.expect_post().return_once(|_, _, _| {
Ok(reqwest::Response::from(
http::Response::builder()
.status(401)
.body("Unauthorized")
.unwrap(),
))
});
let agent = DeepSeekAgent::new(
"invalid-key".to_string(),
"https://api.deepseek.ai".to_string(),
"deepseek-chat".to_string(),
Box::new(mock_client),
);
let message = MCPMessage::new("deepseek:chat", json!({ "user_prompt": "Teste com erro" }));
let result = agent.process_request(message).await;
assert!(matches!(result, Err(MCPError::InternalAgentError(e)) if e.contains("status 401")));
}
#[tokio::test]
async fn test_deepseek_agent_environment_vars() {
std::env::set_var("DEEPSEEK_API_KEY", "env-test-key");
std::env::set_var("DEEPSEEK_ENDPOINT", "https://custom.deepseek.test");
std::env::set_var("DEEPSEEK_MODEL", "deepseek-chat-plus");
let mut mock_client = MockHttpClient::new();
mock_client
.expect_post()
.withf(|url, body, headers| {
let correct_url = url.starts_with("https://custom.deepseek.test");
let model_ok = if let Ok(parsed) = serde_json::from_slice::<serde_json::Value>(body) {
parsed["model"] == "deepseek-chat-plus"
} else {
false
};
let key_ok = headers
.iter()
.any(|(k, v)| k == "Authorization" && v == "Bearer env-test-key");
correct_url && model_ok && key_ok
})
.return_once(|_, _, _| {
Ok(create_mock_response(json!({
"id": "env-test-response",
"choices": [{
"message": {
"role": "assistant",
"content": "Resposta das variáveis de ambiente"
},
"finish_reason": "stop"
}]
})))
});
let agent = mcprs::agent_deepseek::create_deepseek_agent(Some(Box::new(mock_client)));
let message = MCPMessage::new(
"deepseek:chat",
json!({ "user_prompt": "Teste de variáveis de ambiente" }),
);
let result = agent.process_request(message).await.unwrap();
assert_eq!(
result.payload["answer"],
"Resposta das variáveis de ambiente"
);
std::env::remove_var("DEEPSEEK_API_KEY");
std::env::remove_var("DEEPSEEK_ENDPOINT");
std::env::remove_var("DEEPSEEK_MODEL");
}