feat: 实现文件上传功能并完善测试覆盖
- 新增 upload.rs 模块,支持 multipart/form-data 文件上传 - 文件按日期存储在 storage/YYYY-MM-DD/ 目录下 - 使用 UUID 生成唯一文件名,保留原始扩展名 - 添加 axum-extra, uuid, chrono 依赖 新增测试用例: - config_test.rs: 6 个测试 (配置结构验证) - router_test.rs: 11 个测试 (路由匹配逻辑) - handler_test.rs: 8 个测试 (请求处理) - upload_test.rs: 13 个测试 (文件上传功能) 其他改进: - 优化 handler.rs 代码注释 - 更新 .gitignore 忽略 storage/ 和 .claude/ - 添加 CLAUDE.md 项目指南文档 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
140
tests/config_test.rs
Normal file
140
tests/config_test.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use mock_server::config::{MockResponse, MockSettings};
|
||||
|
||||
#[test]
|
||||
fn test_mock_response_file_protocol() {
|
||||
// 测试 1: 文件协议识别
|
||||
let response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "file://./data/file.txt".to_string(),
|
||||
};
|
||||
assert!(response.is_file_protocol());
|
||||
|
||||
// 测试 2: 非文件协议识别
|
||||
let inline_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "{\"key\": \"value\"}".to_string(),
|
||||
};
|
||||
assert!(!inline_response.is_file_protocol());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_response_file_path_extraction() {
|
||||
// 测试 1: 提取文件路径
|
||||
let response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "file://./data/file.txt".to_string(),
|
||||
};
|
||||
assert_eq!(response.get_file_path(), Some("./data/file.txt"));
|
||||
|
||||
// 测试 2: 提取相对路径
|
||||
let response2 = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "file:///absolute/path/file.pdf".to_string(),
|
||||
};
|
||||
assert_eq!(response2.get_file_path(), Some("/absolute/path/file.pdf"));
|
||||
|
||||
// 测试 3: 非文件协议返回 None
|
||||
let inline_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "inline content".to_string(),
|
||||
};
|
||||
assert_eq!(inline_response.get_file_path(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_settings_delay() {
|
||||
// 测试 1: 有延迟设置
|
||||
let settings = MockSettings {
|
||||
delay_ms: Some(1000),
|
||||
};
|
||||
assert_eq!(settings.delay_ms, Some(1000));
|
||||
|
||||
// 测试 2: 无延迟设置
|
||||
let settings = MockSettings { delay_ms: None };
|
||||
assert_eq!(settings.delay_ms, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_response_various_body_formats() {
|
||||
// 测试 1: JSON 格式
|
||||
let json_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: r#"{"code": 0, "message": "success"}"#.to_string(),
|
||||
};
|
||||
assert_eq!(json_response.status, 200);
|
||||
assert!(!json_response.is_file_protocol());
|
||||
|
||||
// 测试 2: HTML 格式
|
||||
let html_response = MockResponse {
|
||||
status: 200,
|
||||
headers: Some(vec![("Content-Type".to_string(), "text/html".to_string())]
|
||||
.into_iter()
|
||||
.collect()),
|
||||
body: "<html><body>Hello</body></html>".to_string(),
|
||||
};
|
||||
assert_eq!(html_response.status, 200);
|
||||
|
||||
// 测试 3: 纯文本
|
||||
let text_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "Plain text response".to_string(),
|
||||
};
|
||||
assert_eq!(text_response.body, "Plain text response");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_response_with_headers() {
|
||||
let mut headers = std::collections::HashMap::new();
|
||||
headers.insert("Content-Type".to_string(), "application/json".to_string());
|
||||
headers.insert("Authorization".to_string(), "Bearer token".to_string());
|
||||
|
||||
let response = MockResponse {
|
||||
status: 200,
|
||||
headers: Some(headers),
|
||||
body: "response body".to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(response.status, 200);
|
||||
assert!(response.headers.is_some());
|
||||
let response_headers = response.headers.unwrap();
|
||||
assert_eq!(response_headers.get("Content-Type"), Some(&"application/json".to_string()));
|
||||
assert_eq!(response_headers.get("Authorization"), Some(&"Bearer token".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_response_edge_cases() {
|
||||
// 测试 1: 空文件路径
|
||||
let empty_file_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "file://".to_string(),
|
||||
};
|
||||
assert!(empty_file_response.is_file_protocol());
|
||||
assert_eq!(empty_file_response.get_file_path(), Some(""));
|
||||
|
||||
// 测试 2: 空响应体
|
||||
let empty_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "".to_string(),
|
||||
};
|
||||
assert_eq!(empty_response.body, "");
|
||||
|
||||
// 测试 3: 包含特殊字符的文件路径
|
||||
let special_path_response = MockResponse {
|
||||
status: 200,
|
||||
headers: None,
|
||||
body: "file://./data/file with spaces.txt".to_string(),
|
||||
};
|
||||
assert_eq!(
|
||||
special_path_response.get_file_path(),
|
||||
Some("./data/file with spaces.txt")
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user