//! 搜索API端点测试 use reqwest; use serde_json::{json, Value}; 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) } /// 测试辅助函数:创建测试用户 async fn create_test_user(client: &reqwest::Client, username: &str, email: &str) -> Result> { let user_data = json!({ "username": username, "email": email, "password": "password123" }); let response = client .post(&format!("{}/api/users", BASE_URL)) .json(&user_data) .send() .await?; if response.status().is_success() { parse_json_response(response).await } else { Err(format!("Failed to create user: {}", response.status()).into()) } } #[tokio::test] async fn test_search_api_basic() { let client = create_client(); // 创建一些测试用户 let test_users = vec![ ("search_admin_1", "admin1@company.com"), ("search_user_1", "user1@example.com"), ("search_admin_2", "admin2@company.com"), ("search_manager", "manager@company.com"), ]; for (username, email) in test_users { let _ = create_test_user(&client, username, email).await; } // 测试基本搜索功能 let response = client .get(&format!("{}/api/users/search?q=admin", BASE_URL)) .send() .await .expect("Failed to search users"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); // 验证搜索响应结构 assert!(json["data"].is_array(), "Response should have data array"); assert!(json["pagination"].is_object(), "Response should have pagination object"); assert!(json["search_params"].is_object(), "Response should have search_params object"); assert!(json["total_filtered"].is_number(), "Response should have total_filtered"); let data = json["data"].as_array().unwrap(); let search_params = &json["search_params"]; // 验证搜索参数被正确返回 assert_eq!(search_params["q"], "admin"); // 验证搜索结果 for user in data { let username = user["username"].as_str().unwrap(); let email = user["email"].as_str().unwrap(); assert!( username.contains("admin") || email.contains("admin"), "Search result should contain 'admin' keyword" ); } } #[tokio::test] async fn test_search_api_with_filters() { let client = create_client(); // 创建测试用户 let test_users = vec![ ("filter_test_1", "test1@example.com"), ("filter_test_2", "test2@company.com"), ("other_user", "other@example.com"), ]; for (username, email) in test_users { let _ = create_test_user(&client, username, email).await; } // 测试用户名过滤 let response = client .get(&format!("{}/api/users/search?username=filter_test", BASE_URL)) .send() .await .expect("Failed to search users by username"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let search_params = &json["search_params"]; // 验证搜索参数 assert_eq!(search_params["username"], "filter_test"); // 验证结果 for user in data { let username = user["username"].as_str().unwrap(); assert!(username.contains("filter_test"), "Username should contain filter_test"); } // 测试邮箱过滤 let response = client .get(&format!("{}/api/users/search?email=company.com", BASE_URL)) .send() .await .expect("Failed to search users by email"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let search_params = &json["search_params"]; // 验证搜索参数 assert_eq!(search_params["email"], "company.com"); // 验证结果 for user in data { let email = user["email"].as_str().unwrap(); assert!(email.contains("company.com"), "Email should contain company.com"); } } #[tokio::test] async fn test_search_api_with_sorting() { let client = create_client(); // 创建测试用户 let test_users = vec![ ("sort_zebra", "zebra@test.com"), ("sort_alpha", "alpha@test.com"), ("sort_beta", "beta@test.com"), ]; for (username, email) in test_users { let _ = create_test_user(&client, username, email).await; } // 测试按用户名升序排序 let response = client .get(&format!("{}/api/users/search?username=sort_&sort_by=username&sort_order=asc", BASE_URL)) .send() .await .expect("Failed to search users with sorting"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let search_params = &json["search_params"]; // 验证搜索参数 assert_eq!(search_params["sort_by"], "username"); assert_eq!(search_params["sort_order"], "asc"); // 验证排序结果 if data.len() > 1 { for i in 0..data.len() - 1 { let current_username = data[i]["username"].as_str().unwrap(); let next_username = data[i + 1]["username"].as_str().unwrap(); assert!( current_username <= next_username, "Results should be sorted by username in ascending order" ); } } } #[tokio::test] async fn test_search_api_with_pagination() { let client = create_client(); // 创建多个测试用户 for i in 1..=5 { let username = format!("page_test_{}", i); let email = format!("page{}@test.com", i); let _ = create_test_user(&client, &username, &email).await; } // 测试第一页 let response = client .get(&format!("{}/api/users/search?username=page_test&page=1&limit=2", BASE_URL)) .send() .await .expect("Failed to search users with pagination"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let pagination = &json["pagination"]; assert_eq!(data.len(), 2, "First page should have 2 users"); assert_eq!(pagination["current_page"], 1); assert_eq!(pagination["per_page"], 2); assert!(!pagination["has_prev"].as_bool().unwrap(), "First page should not have previous"); // 测试第二页 let response = client .get(&format!("{}/api/users/search?username=page_test&page=2&limit=2", BASE_URL)) .send() .await .expect("Failed to search users page 2"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let pagination = &json["pagination"]; assert_eq!(data.len(), 2, "Second page should have 2 users"); assert_eq!(pagination["current_page"], 2); assert!(pagination["has_prev"].as_bool().unwrap(), "Second page should have previous"); } #[tokio::test] async fn test_search_api_validation_errors() { let client = create_client(); // 测试无效的排序字段 let response = client .get(&format!("{}/api/users/search?sort_by=invalid_field", BASE_URL)) .send() .await .expect("Failed to send request with invalid sort field"); assert_eq!(response.status(), 400); let json = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(json["error"].as_str().unwrap().contains("无效的排序字段")); // 测试无效的排序方向 let response = client .get(&format!("{}/api/users/search?sort_order=invalid_order", BASE_URL)) .send() .await .expect("Failed to send request with invalid sort order"); assert_eq!(response.status(), 400); let json = parse_json_response(response).await.expect("Failed to parse JSON"); assert!(json["error"].as_str().unwrap().contains("无效的排序方向")); } #[tokio::test] async fn test_search_api_empty_results() { let client = create_client(); // 搜索不存在的关键词 let response = client .get(&format!("{}/api/users/search?q=nonexistent_keyword_12345", BASE_URL)) .send() .await .expect("Failed to search for nonexistent keyword"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let total_filtered = json["total_filtered"].as_i64().unwrap(); assert_eq!(data.len(), 0, "Should return empty results"); assert_eq!(total_filtered, 0, "Total filtered should be 0"); } #[tokio::test] async fn test_search_api_complex_query() { let client = create_client(); // 创建测试用户 let test_users = vec![ ("complex_admin", "admin@company.com"), ("complex_user", "user@company.com"), ("simple_admin", "admin@example.com"), ]; for (username, email) in test_users { let _ = create_test_user(&client, username, email).await; } // 复合搜索:用户名包含admin且邮箱包含company let response = client .get(&format!("{}/api/users/search?username=admin&email=company&sort_by=username&sort_order=asc", BASE_URL)) .send() .await .expect("Failed to perform complex search"); assert_eq!(response.status(), 200); let json = parse_json_response(response).await.expect("Failed to parse JSON"); let data = json["data"].as_array().unwrap(); let search_params = &json["search_params"]; // 验证搜索参数 assert_eq!(search_params["username"], "admin"); assert_eq!(search_params["email"], "company"); assert_eq!(search_params["sort_by"], "username"); assert_eq!(search_params["sort_order"], "asc"); // 验证结果同时满足两个条件 for user in data { let username = user["username"].as_str().unwrap(); let email = user["email"].as_str().unwrap(); assert!(username.contains("admin"), "Username should contain admin"); assert!(email.contains("company"), "Email should contain company"); } }