use std::path::Path; use std::collections::HashMap; use serde_json::json; use mock_server::models::Payload; use mock_server::loader::MockLoader; use mock_server::router::MockRouter; /// 加载 v1 目录的 mock 规则 fn load_v1_mocks() -> HashMap> { let v1_path = Path::new("./mocks/v1"); MockLoader::load_all_from_dir(v1_path) } // ========== 模块一:验证所有 JSON 文件正确加载 ========== #[test] fn test_v1_load_all_mocks() { let index = load_v1_mocks(); // 验证索引键存在 assert!(index.contains_key("v1"), "应包含 'v1' 索引键"); // 验证规则总数 let total: usize = index.values().map(|v| v.len()).sum(); assert!(total >= 10, "v1 目录应有至少 10 个 mock 规则"); } // ========== 模块二:JSON Payload 测试 ========== #[test] fn test_v1_json_login() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "application/json".to_string()); headers.insert("Authorization".to_string(), "eyJhbGciOiJIUzI1NiIsInR5cCI6".to_string()); headers.insert("host".to_string(), "127.0.0.1:8080".to_string()); let payload = Payload::Json(json!({ "username": "user001", "password": "password123" })); let matched = router.match_rule("POST", "/v1/auth/login", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "JSON 登录应匹配成功"); let rule = matched.unwrap(); assert_eq!(rule.name, "user_login_001"); assert_eq!(rule.response.status, 200); } #[test] fn test_v1_json_register() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "application/json".to_string()); let payload = Payload::Json(json!({ "username": "newuser", "password": "newpass123", "email": "newuser@example.com" })); let matched = router.match_rule("POST", "/v1/auth/register", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "JSON 注册应匹配成功"); let rule = matched.unwrap(); assert_eq!(rule.name, "user_register"); assert_eq!(rule.response.status, 201); } // ========== 模块三:Form Payload 测试 ========== #[test] fn test_v1_form_login() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "application/x-www-form-urlencoded".to_string()); let mut form_data = HashMap::new(); form_data.insert("username".to_string(), "formuser".to_string()); form_data.insert("password".to_string(), "formpass".to_string()); let payload = Payload::Form(form_data); let matched = router.match_rule("POST", "/v1/user/login/form", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "Form 登录应匹配成功"); assert_eq!(matched.unwrap().name, "_user_login_form"); } // ========== 模块四:Text Payload 测试 ========== #[test] fn test_v1_text_echo() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "text/plain".to_string()); let payload = Payload::Text("Hello V1 Mock Server".to_string()); let matched = router.match_rule("POST", "/v1/user/echo", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "Text 回显应匹配成功"); let rule = matched.unwrap(); assert_eq!(rule.name, "user_echo"); assert!(rule.response.body.contains("Echo from V1")); } // ========== 模块五:XML Payload 测试 ========== #[test] fn test_v1_xml_export() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "application/xml".to_string()); let xml_body = r#"10001xml"#; let payload = Payload::Xml(xml_body.to_string()); let matched = router.match_rule("POST", "/v1/data/export", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "XML 导出应匹配成功"); assert_eq!(matched.unwrap().name, "data_export"); } // ========== 模块六:Multipart Payload 测试 ========== #[test] fn test_v1_multipart_upload() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Content-Type".to_string(), "multipart/form-data".to_string()); let mut multipart_data = HashMap::new(); multipart_data.insert("avatar1".to_string(), "file_content".to_string()); multipart_data.insert("description1".to_string(), "user avatar".to_string()); let payload = Payload::Multipart(multipart_data); let matched = router.match_rule("POST", "/v1/user/avatar", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "Multipart 上传应匹配成功"); assert_eq!(matched.unwrap().name, "user_upload_avatar_001"); } // ========== 模块七:None Payload 测试 (GET 无 Body) ========== #[test] fn test_v1_health_check() { let index = load_v1_mocks(); let router = MockRouter::new(index); let payload = Payload::None; let matched = router.match_rule("GET", "/v1/health", &HashMap::new(), &HashMap::new(), &payload); assert!(matched.is_some(), "健康检查应匹配成功"); let rule = matched.unwrap(); assert_eq!(rule.name, "health_check"); assert_eq!(rule.response.status, 200); } #[test] fn test_v1_get_profile() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut headers = HashMap::new(); headers.insert("Authorization".to_string(), "Bearer v1_test_token".to_string()); let payload = Payload::None; let matched = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "获取用户信息应匹配成功"); assert_eq!(matched.unwrap().name, "user_profile"); } // ========== 模块八:Query Params 测试 ========== #[test] fn test_v1_query_params() { let index = load_v1_mocks(); let router = MockRouter::new(index); let mut query = HashMap::new(); query.insert("format".to_string(), "json".to_string()); let payload = Payload::None; let matched = router.match_rule("GET", "/v1/user/download", &query, &HashMap::new(), &payload); assert!(matched.is_some(), "带 query params 的下载应匹配成功"); let rule = matched.unwrap(); assert_eq!(rule.name, "user_download"); assert!(rule.response.body.starts_with("file://")); } // ========== 模块九:Header 匹配测试 ========== #[test] fn test_v1_header_required() { let index = load_v1_mocks(); let router = MockRouter::new(index); // 无 Authorization header 不应匹配 let payload = Payload::None; let no_match = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &HashMap::new(), &payload); assert!(no_match.is_none(), "无 Authorization 不应匹配"); // 有正确的 Authorization header 应匹配 let mut headers = HashMap::new(); headers.insert("Authorization".to_string(), "Bearer v1_test_token".to_string()); let matched = router.match_rule("GET", "/v1/user/profile", &HashMap::new(), &headers, &payload); assert!(matched.is_some(), "有 Authorization 应匹配"); }