use std::time::Duration;
use tokio::time::sleep;
#[tokio::test]
async fn test_json_value_return_integration() -> anyhow::Result<()> {
use potato::HttpServer;
#[potato::http_get("/json-value")]
async fn handler_json_value() -> serde_json::Value {
serde_json::json!({
"message": "Hello from JSON Value",
"status": "success",
"data": {
"count": 42,
"active": true
}
})
}
#[potato::http_get("/result-json-value-success")]
async fn handler_result_json_value_success() -> anyhow::Result<serde_json::Value> {
Ok(serde_json::json!({
"message": "Success result",
"code": 200
}))
}
#[potato::http_get("/result-json-value-error")]
async fn handler_result_json_value_error(fail: bool) -> anyhow::Result<serde_json::Value> {
if fail {
Err(anyhow::anyhow!("Operation failed"))
} else {
Ok(serde_json::json!({
"status": "success"
}))
}
}
#[potato::http_post("/json-value-with-params")]
async fn handler_json_value_with_params(name: String, age: u32) -> serde_json::Value {
serde_json::json!({
"name": name,
"age": age,
"message": "User created"
})
}
let server_addr = "127.0.0.1:18090";
let mut server = HttpServer::new(server_addr);
let server_handle = tokio::spawn(async move {
let _ = server.serve_http().await;
});
sleep(Duration::from_millis(300)).await;
let url = format!("http://{}/json-value", server_addr);
let res = potato::get(&url, vec![]).await?;
assert_eq!(res.http_code, 200);
let body = match &res.body {
potato::HttpResponseBody::Data(data) => String::from_utf8(data.clone())?,
_ => panic!("Expected data body"),
};
println!("Test 1 - JSON Value response: {}", body);
let json: serde_json::Value = serde_json::from_str(&body)?;
assert_eq!(json["message"], "Hello from JSON Value");
assert_eq!(json["status"], "success");
assert_eq!(json["data"]["count"], 42);
assert_eq!(json["data"]["active"], true);
let url = format!("http://{}/result-json-value-success", server_addr);
let res = potato::get(&url, vec![]).await?;
assert_eq!(res.http_code, 200);
let body = match &res.body {
potato::HttpResponseBody::Data(data) => String::from_utf8(data.clone())?,
_ => panic!("Expected data body"),
};
println!("Test 2 - Result JSON Value success: {}", body);
let json: serde_json::Value = serde_json::from_str(&body)?;
assert_eq!(json["message"], "Success result");
assert_eq!(json["code"], 200);
let url = format!("http://{}/result-json-value-error", server_addr);
let res = potato::get(&url, vec![]).await?;
assert_eq!(res.http_code, 500);
println!("Test 3 - Result JSON Value error: HTTP {}", res.http_code);
server_handle.abort();
println!("All JSON Value return integration tests passed!");
Ok(())
}
#[tokio::test]
async fn test_json_value_content_type() -> anyhow::Result<()> {
use potato::HttpServer;
#[potato::http_get("/json-content-type-test")]
async fn handler_json_content_type() -> serde_json::Value {
serde_json::json!({
"test": "content type"
})
}
let server_addr = "127.0.0.1:18091";
let mut server = HttpServer::new(server_addr);
let server_handle = tokio::spawn(async move {
let _ = server.serve_http().await;
});
sleep(Duration::from_millis(300)).await;
let url = format!("http://{}/json-content-type-test", server_addr);
let res = potato::get(&url, vec![]).await?;
assert_eq!(res.http_code, 200);
let content_type = res.headers.get("Content-Type");
assert!(
content_type.is_some(),
"Content-Type header should be present"
);
println!("Content-Type: {:?}", content_type);
assert!(
content_type.unwrap().contains("application/json"),
"Content-Type should be application/json, got: {}",
content_type.unwrap()
);
let body = match &res.body {
potato::HttpResponseBody::Data(data) => String::from_utf8(data.clone())?,
_ => panic!("Expected data body"),
};
let json: serde_json::Value = serde_json::from_str(&body)?;
assert_eq!(json["test"], "content type");
server_handle.abort();
println!("Content-Type test passed!");
Ok(())
}