//! 集成测试 use reqwest; use serde_json::{json, Value}; use std::collections::HashMap; use tokio; const BASE_URL: &str = "http://127.0.0.1:3000"; /// 测试辅助函数:创建 HTTP 客户端 fn create_client() -> reqwest::Client { reqwest::Client::new() } /// 测试辅助函数:解析 JSON 响应 async fn parse_json_response(response: reqwest::Response) -> Result> { let text = response.text().await?; let json: Value = serde_json::from_str(&text)?; Ok(json) } #[tokio::test] async fn test_health_check() { let client = create_client(); let response = client .get(&format!("{}/health", BASE_URL)) .send() .await .expect("Failed to send request"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); assert_eq!(json["status"], "healthy"); assert!(json["timestamp"].is_string()); } #[tokio::test] async fn test_root_endpoint() { let client = create_client(); let response = client .get(&format!("{}/", BASE_URL)) .send() .await .expect("Failed to send request"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); assert_eq!(json["message"], "欢迎使用 Rust User API"); assert_eq!(json["version"], "0.1.0"); } #[tokio::test] async fn test_user_lifecycle() { let client = create_client(); // 1. 获取初始用户列表(应该为空) let response = client .get(&format!("{}/api/users", BASE_URL)) .send() .await .expect("Failed to get users"); assert_eq!(response.status(), 200); let users_response = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(users_response["data"].is_array()); assert!(users_response["pagination"].is_object()); // 2. 创建新用户 let user_data = json!({ "username": "testuser_integration", "email": "integration@example.com", "password": "password123" }); let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&user_data) .send() .await .expect("Failed to create user"); assert_eq!(response.status(), 201); let created_user = parse_json_response(response).await.expect("Failed to parse JSON"); assert_eq!(created_user["username"], "testuser_integration"); assert_eq!(created_user["email"], "integration@example.com"); assert!(created_user["id"].is_string()); assert!(created_user["created_at"].is_string()); let user_id = created_user["id"].as_str().unwrap(); // 3. 获取创建的用户 let response = client .get(&format!("{}/api/users/{}", BASE_URL, user_id)) .send() .await .expect("Failed to get user"); assert_eq!(response.status(), 200); let fetched_user = parse_json_response(response).await.expect("Failed to parse JSON"); assert_eq!(fetched_user["id"], user_id); assert_eq!(fetched_user["username"], "testuser_integration"); // 4. 更新用户 let update_data = json!({ "username": "updated_testuser", "email": "updated@example.com" }); let response = client .put(&format!("{}/api/users/{}", BASE_URL, user_id)) .json(&update_data) .send() .await .expect("Failed to update user"); assert_eq!(response.status(), 200); let updated_user = parse_json_response(response).await.expect("Failed to parse JSON"); assert_eq!(updated_user["username"], "updated_testuser"); assert_eq!(updated_user["email"], "updated@example.com"); // 5. 删除用户 let response = client .delete(&format!("{}/api/users/{}", BASE_URL, user_id)) .send() .await .expect("Failed to delete user"); assert_eq!(response.status(), 204); // 6. 验证用户已被删除 let response = client .get(&format!("{}/api/users/{}", BASE_URL, user_id)) .send() .await .expect("Failed to get deleted user"); assert_eq!(response.status(), 404); } #[tokio::test] async fn test_user_validation() { let client = create_client(); // 测试无效的用户数据 let invalid_user_data = json!({ "username": "ab", // 太短 "email": "invalid-email", // 无效邮箱 "password": "123" // 太短 }); let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&invalid_user_data) .send() .await .expect("Failed to send request"); assert_eq!(response.status(), 400); let error_response = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(error_response["error"].is_string()); assert_eq!(error_response["status"], 400); } #[tokio::test] async fn test_duplicate_username() { let client = create_client(); let user_data = json!({ "username": "duplicate_test", "email": "duplicate1@example.com", "password": "password123" }); // 创建第一个用户 let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&user_data) .send() .await .expect("Failed to create first user"); assert_eq!(response.status(), 201); // 尝试创建相同用户名的用户 let duplicate_user_data = json!({ "username": "duplicate_test", // 相同用户名 "email": "duplicate2@example.com", "password": "password123" }); let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&duplicate_user_data) .send() .await .expect("Failed to send duplicate request"); assert_eq!(response.status(), 409); let error_response = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(error_response["error"].as_str().unwrap().contains("用户名已存在")); } #[tokio::test] async fn test_login_flow() { let client = create_client(); // 1. 创建测试用户 let user_data = json!({ "username": "login_test", "email": "login@example.com", "password": "password123" }); let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&user_data) .send() .await .expect("Failed to create user"); assert_eq!(response.status(), 201); // 2. 测试正确的登录凭据 let login_data = json!({ "username": "login_test", "password": "password123" }); let response = client .post(&format!("{}/api/auth/login", BASE_URL)) .json(&login_data) .send() .await .expect("Failed to login"); assert_eq!(response.status(), 200); let login_response = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(login_response["token"].is_string()); assert!(login_response["user"]["id"].is_string()); assert_eq!(login_response["user"]["username"], "login_test"); // 3. 测试错误的密码 let wrong_login_data = json!({ "username": "login_test", "password": "wrongpassword" }); let response = client .post(&format!("{}/api/auth/login", BASE_URL)) .json(&wrong_login_data) .send() .await .expect("Failed to send wrong login"); assert_eq!(response.status(), 401); // 4. 测试不存在的用户 let nonexistent_login_data = json!({ "username": "nonexistent_user", "password": "password123" }); let response = client .post(&format!("{}/api/auth/login", BASE_URL)) .json(&nonexistent_login_data) .send() .await .expect("Failed to send nonexistent login"); assert_eq!(response.status(), 404); } #[tokio::test] async fn test_not_found_endpoints() { let client = create_client(); // 测试不存在的用户 ID let response = client .get(&format!("{}/api/users/00000000-0000-0000-0000-000000000000", BASE_URL)) .send() .await .expect("Failed to send request"); assert_eq!(response.status(), 404); // 测试不存在的端点 let response = client .get(&format!("{}/api/nonexistent", BASE_URL)) .send() .await .expect("Failed to send request"); assert_eq!(response.status(), 404); }