use hwhkit::{WebServerBuilder, Router, get, Json, Serialize};
use hwhkit::config::ArchitectureType;
use serde_json::json;
use std::time::Duration;
#[derive(Serialize)]
struct TestResponse {
message: String,
status: String,
}
async fn test_handler() -> Json<TestResponse> {
Json(TestResponse {
message: "Hello from test!".to_string(),
status: "ok".to_string(),
})
}
async fn health_handler() -> Json<serde_json::Value> {
Json(json!({
"status": "healthy",
"timestamp": chrono::Utc::now().to_rfc3339()
}))
}
#[tokio::test]
async fn test_api_server_creation() {
let app = Router::new()
.route("/test", get(test_handler))
.route("/health", get(health_handler));
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 8000) .architecture(ArchitectureType::Api)
.routes(app)
.build()
.await;
assert!(server_result.is_ok(), "API 服务器创建失败: {:?}", server_result.err());
}
#[tokio::test]
async fn test_full_server_creation() {
let app = Router::new()
.route("/", get(test_handler));
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 8001)
.architecture(ArchitectureType::Full)
.routes(app)
.build()
.await;
assert!(server_result.is_ok(), "全栈服务器创建失败: {:?}", server_result.err());
}
#[tokio::test]
async fn test_builder_with_cors() {
let app = Router::new()
.route("/test", get(test_handler));
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 8002)
.cors(vec!["http://localhost:3000".to_string()])
.routes(app)
.build()
.await;
assert!(server_result.is_ok(), "带 CORS 的服务器创建失败: {:?}", server_result.err());
}
#[tokio::test]
async fn test_builder_with_jwt() {
let app = Router::new()
.route("/protected", get(test_handler));
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 8003)
.jwt_auth("test-secret", 3600)
.routes(app)
.build()
.await;
assert!(server_result.is_ok(), "带 JWT 的服务器创建失败: {:?}", server_result.err());
}
#[tokio::test]
async fn test_config_validation() {
use hwhkit::Config;
use hwhkit::config::{ServerConfig, MiddlewareConfig, ArchitectureType};
let mut config = Config::default();
assert!(config.validate().is_ok(), "默认配置应该是有效的");
config.server.port = 0;
assert!(config.validate().is_err(), "端口为 0 应该是无效的");
config.server.port = 3000;
assert!(config.validate().is_ok(), "恢复后的配置应该是有效的");
}
#[tokio::test]
async fn test_server_address_formatting() {
use hwhkit::Config;
let mut config = Config::default();
config.server.host = "127.0.0.1".to_string();
config.server.port = 8080;
assert_eq!(config.server_address(), "127.0.0.1:8080");
}
#[tokio::test]
async fn test_cors_middleware() {
use hwhkit::middleware::cors::create_cors_layer;
use hwhkit::config::CorsConfig;
let cors_config = CorsConfig {
enabled: true,
origins: vec!["http://localhost:3000".to_string()],
methods: vec!["GET".to_string(), "POST".to_string()],
headers: vec!["Content-Type".to_string()],
};
let cors_layer_result = create_cors_layer(&cors_config);
assert!(cors_layer_result.is_ok(), "CORS 中间件创建失败");
}
#[tokio::test]
async fn test_jwt_auth_creation() {
use hwhkit::middleware::jwt::JwtAuth;
use hwhkit::config::JwtConfig;
let jwt_config = JwtConfig {
enabled: true,
secret: "test-secret-key".to_string(),
expires_in: 3600,
};
let jwt_auth = JwtAuth::new(&jwt_config);
assert_eq!(jwt_auth.secret, "test-secret-key");
assert_eq!(jwt_auth.expires_in, 3600);
#[cfg(feature = "jwt")]
{
let token_result = jwt_auth.generate_token("test-user");
assert!(token_result.is_ok(), "Token 生成失败");
if let Ok(token) = token_result {
let claims_result = jwt_auth.verify_token(&token);
assert!(claims_result.is_ok(), "Token 验证失败");
if let Ok(claims) = claims_result {
assert_eq!(claims.sub, "test-user");
}
}
}
}
#[tokio::test]
async fn test_server_startup_time() {
let app = Router::new()
.route("/", get(test_handler));
let start_time = std::time::Instant::now();
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 8004)
.routes(app)
.build()
.await;
let build_time = start_time.elapsed();
assert!(server_result.is_ok(), "服务器构建失败");
assert!(build_time < Duration::from_millis(1000), "服务器构建时间过长: {:?}", build_time);
}
#[tokio::test]
async fn test_invalid_static_directory() {
let app = Router::new()
.route("/", get(test_handler));
let server_result = WebServerBuilder::new()
.listen("127.0.0.1", 0)
.static_files("/nonexistent/directory", "/static")
.routes(app)
.build()
.await;
println!("Static directory test result: {:?}", server_result);
}
#[tokio::test]
async fn test_config_file_loading() {
use hwhkit::Config;
use std::fs;
use tempfile::NamedTempFile;
let config_content = r#"
[server]
host = "127.0.0.1"
port = 9999
architecture = "api"
[middleware.cors]
enabled = true
origins = ["http://test.example.com"]
methods = ["GET", "POST"]
headers = ["Content-Type"]
[middleware.jwt]
enabled = false
secret = "test-secret"
expires_in = 3600
[middleware.static_files]
enabled = false
dir = "static"
prefix = "/static"
[middleware.templates]
enabled = false
dir = "templates"
extension = "html"
[middleware.logging]
level = "debug"
requests = true
[middleware.custom]
[database]
enabled = false
db_type = "sqlite"
url = "sqlite::memory:"
max_connections = 5
min_connections = 1
connect_timeout = 30
auto_migrate = false
[qdrant]
enabled = false
url = "http://localhost:6334"
api_key = ""
timeout = 30
default_collection = "default"
"#;
let temp_file = NamedTempFile::new().expect("创建临时文件失败");
fs::write(temp_file.path(), config_content).expect("写入配置文件失败");
let config_result = Config::from_file(temp_file.path());
assert!(config_result.is_ok(), "配置文件加载失败: {:?}", config_result.err());
if let Ok(config) = config_result {
assert_eq!(config.server.host, "127.0.0.1");
assert_eq!(config.server.port, 9999);
assert_eq!(config.server.architecture, ArchitectureType::Api);
assert!(config.middleware.cors.enabled);
assert_eq!(config.middleware.logging.level, "debug");
}
}
#[cfg(feature = "templates")]
#[tokio::test]
async fn test_template_engine() {
use hwhkit::templates::TemplateEngine;
use hwhkit::config::TemplateConfig;
use tempfile::TempDir;
use std::fs;
let temp_dir = TempDir::new().expect("创建临时目录失败");
let template_content = r#"
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body><h1>Hello, {{ name }}!</h1></body>
</html>
"#;
let template_file = temp_dir.path().join("test.html");
fs::write(&template_file, template_content).expect("写入模板文件失败");
let template_config = TemplateConfig {
enabled: true,
dir: temp_dir.path().to_string_lossy().to_string(),
extension: "html".to_string(),
};
let engine_result = TemplateEngine::new(&template_config);
assert!(engine_result.is_ok(), "模板引擎创建失败: {:?}", engine_result.err());
if let Ok(engine) = engine_result {
let context = serde_json::json!({
"title": "Test Page",
"name": "World"
});
let render_result = engine.render("test.html", &context);
assert!(render_result.is_ok(), "模板渲染失败: {:?}", render_result.err());
if let Ok(html) = render_result {
assert!(html.contains("Test Page"));
assert!(html.contains("Hello, World!"));
}
}
}