use axum::body::Body;
use axum::http::{Method, Request, StatusCode};
use http_body_util::BodyExt;
use sz_rust_examples::build_router;
use tower::ServiceExt;
async fn body_to_string(body: Body) -> String {
let bytes = body.collect().await.unwrap().to_bytes();
String::from_utf8(bytes.to_vec()).unwrap()
}
#[tokio::test]
async fn test_hello_endpoint() {
let router = build_router();
let request = Request::builder()
.method(Method::GET)
.uri("/")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let body = body_to_string(response.into_body()).await;
let json: serde_json::Value = serde_json::from_str(&body).unwrap();
assert_eq!(json["code"], 1);
assert_eq!(json["msg"], "hello");
assert_eq!(json["data"], serde_json::json!({}));
}
#[tokio::test]
async fn test_health_endpoint() {
let router = build_router();
let request = Request::builder()
.method(Method::GET)
.uri("/health")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let body = body_to_string(response.into_body()).await;
let json: serde_json::Value = serde_json::from_str(&body).unwrap();
assert_eq!(json["code"], 1);
assert_eq!(json["msg"], "ok");
assert_eq!(json["data"]["status"], "healthy");
assert!(json["data"]["version"].is_string());
}
#[tokio::test]
async fn test_not_found_endpoint() {
let router = build_router();
let request = Request::builder()
.method(Method::GET)
.uri("/nonexistent")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::NOT_FOUND);
}
#[tokio::test]
async fn test_content_type_is_json() {
let router = build_router();
let request = Request::builder()
.method(Method::GET)
.uri("/")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
let content_type = response
.headers()
.get("content-type")
.map(|v| v.to_str().unwrap())
.unwrap_or("");
assert!(
content_type.contains("application/json"),
"Content-Type 应为 application/json,实际: {}",
content_type
);
}
#[tokio::test]
async fn test_response_body_exact_match() {
let router = build_router();
let request = Request::builder()
.method(Method::GET)
.uri("/")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
let body = body_to_string(response.into_body()).await;
assert!(body.contains("\"code\":1"));
assert!(body.contains("\"msg\":\"hello\""));
assert!(body.contains("\"data\":{}"));
}
#[tokio::test]
async fn test_post_method_not_allowed() {
let router = build_router();
let request = Request::builder()
.method(Method::POST)
.uri("/")
.body(Body::empty())
.unwrap();
let response = router.oneshot(request).await.unwrap();
assert_eq!(response.status(), StatusCode::METHOD_NOT_ALLOWED);
}