Files
rust-user-api/tests/database_tests.rs
enoch bb9d7a869d
Some checks failed
Deploy to Production / Run Tests (push) Failing after 16m35s
Deploy to Production / Security Scan (push) Has been skipped
Deploy to Production / Build Docker Image (push) Has been skipped
Deploy to Production / Deploy to Staging (push) Has been skipped
Deploy to Production / Deploy to Production (push) Has been skipped
Deploy to Production / Notify Results (push) Successful in 31s
feat: 完成Rust User API完整开发
 新功能:
- SQLite数据库集成和持久化存储
- 数据库迁移系统和版本管理
- API分页功能和高效查询
- 用户搜索和过滤机制
- 完整的RBAC角色权限系统
- 结构化日志记录和系统监控
- API限流和多层安全防护
- Docker容器化和生产部署配置

🔒 安全特性:
- JWT认证和授权
- 限流和防暴力破解
- 安全头和CORS配置
- 输入验证和XSS防护
- 审计日志和安全监控

📊 监控和运维:
- Prometheus指标收集
- 健康检查和系统监控
- 自动化备份和恢复
- 完整的运维文档和脚本
- CI/CD流水线配置

🚀 部署支持:
- 多环境Docker配置
- 生产环境部署指南
- 性能优化和安全加固
- 故障排除和应急响应
- 自动化运维脚本

📚 文档完善:
- API使用文档
- 部署检查清单
- 运维操作手册
- 性能和安全指南
- 故障排除指南
2025-08-07 16:03:32 +08:00

280 lines
9.6 KiB
Rust

//! SQLite 数据库存储测试
use rust_user_api::{
models::{user::User, role::UserRole},
storage::{database::DatabaseUserStore, UserStore},
utils::errors::ApiError,
};
use uuid::Uuid;
use chrono::Utc;
use tempfile::tempdir;
/// 创建临时数据库用于测试
async fn create_test_database() -> Result<DatabaseUserStore, ApiError> {
// 使用内存数据库避免文件系统问题
let database_url = "sqlite::memory:";
DatabaseUserStore::from_url(database_url).await
}
/// 创建测试用户
fn create_test_user() -> User {
User {
id: Uuid::new_v4(),
username: "testuser".to_string(),
email: "test@example.com".to_string(),
password_hash: "hashed_password".to_string(),
role: UserRole::User,
created_at: Utc::now(),
updated_at: Utc::now(),
}
}
#[tokio::test]
async fn test_database_connection_and_initialization() {
let store = create_test_database().await;
assert!(store.is_ok(), "Failed to create database store");
}
#[tokio::test]
async fn test_database_create_user() {
let store = create_test_database().await.unwrap();
let user = create_test_user();
let result = store.create_user(user.clone()).await;
assert!(result.is_ok(), "Failed to create user: {:?}", result.err());
let created_user = result.unwrap();
assert_eq!(created_user.username, user.username);
assert_eq!(created_user.email, user.email);
assert_eq!(created_user.id, user.id);
}
#[tokio::test]
async fn test_database_get_user_by_id() {
let store = create_test_database().await.unwrap();
let user = create_test_user();
let user_id = user.id;
// 先创建用户
store.create_user(user.clone()).await.unwrap();
// 然后获取用户
let result = store.get_user(&user_id).await;
assert!(result.is_ok(), "Failed to get user: {:?}", result.err());
let retrieved_user = result.unwrap();
assert!(retrieved_user.is_some(), "User not found");
let retrieved_user = retrieved_user.unwrap();
assert_eq!(retrieved_user.id, user_id);
assert_eq!(retrieved_user.username, user.username);
assert_eq!(retrieved_user.email, user.email);
}
#[tokio::test]
async fn test_database_get_user_by_username() {
let store = create_test_database().await.unwrap();
let user = create_test_user();
let username = user.username.clone();
// 先创建用户
store.create_user(user.clone()).await.unwrap();
// 然后按用户名获取用户
let result = store.get_user_by_username(&username).await;
assert!(result.is_ok(), "Failed to get user by username: {:?}", result.err());
let retrieved_user = result.unwrap();
assert!(retrieved_user.is_some(), "User not found by username");
let retrieved_user = retrieved_user.unwrap();
assert_eq!(retrieved_user.username, username);
assert_eq!(retrieved_user.id, user.id);
}
#[tokio::test]
async fn test_database_list_users() {
let store = create_test_database().await.unwrap();
// 创建多个用户
let user1 = User {
id: Uuid::new_v4(),
username: "user1".to_string(),
email: "user1@example.com".to_string(),
password_hash: "hashed_password1".to_string(),
role: UserRole::User,
created_at: Utc::now(),
updated_at: Utc::now(),
};
let user2 = User {
id: Uuid::new_v4(),
username: "user2".to_string(),
email: "user2@example.com".to_string(),
password_hash: "hashed_password2".to_string(),
role: UserRole::User,
created_at: Utc::now(),
updated_at: Utc::now(),
};
store.create_user(user1.clone()).await.unwrap();
store.create_user(user2.clone()).await.unwrap();
// 获取所有用户
let result = store.list_users().await;
assert!(result.is_ok(), "Failed to list users: {:?}", result.err());
let users = result.unwrap();
assert_eq!(users.len(), 2, "Expected 2 users, got {}", users.len());
// 验证用户存在
let usernames: Vec<String> = users.iter().map(|u| u.username.clone()).collect();
assert!(usernames.contains(&"user1".to_string()));
assert!(usernames.contains(&"user2".to_string()));
}
#[tokio::test]
async fn test_database_update_user() {
let store = create_test_database().await.unwrap();
let mut user = create_test_user();
let user_id = user.id;
// 先创建用户
store.create_user(user.clone()).await.unwrap();
// 更新用户信息
user.username = "updated_user".to_string();
user.email = "updated@example.com".to_string();
user.updated_at = Utc::now();
let result = store.update_user(&user_id, user.clone()).await;
assert!(result.is_ok(), "Failed to update user: {:?}", result.err());
let updated_user = result.unwrap();
assert!(updated_user.is_some(), "Updated user not returned");
let updated_user = updated_user.unwrap();
assert_eq!(updated_user.username, "updated_user");
assert_eq!(updated_user.email, "updated@example.com");
// 验证数据库中的用户确实被更新了
let retrieved_user = store.get_user(&user_id).await.unwrap().unwrap();
assert_eq!(retrieved_user.username, "updated_user");
assert_eq!(retrieved_user.email, "updated@example.com");
}
#[tokio::test]
async fn test_database_delete_user() {
let store = create_test_database().await.unwrap();
let user = create_test_user();
let user_id = user.id;
// 先创建用户
store.create_user(user.clone()).await.unwrap();
// 验证用户存在
let user_exists = store.get_user(&user_id).await.unwrap();
assert!(user_exists.is_some(), "User should exist before deletion");
// 删除用户
let result = store.delete_user(&user_id).await;
assert!(result.is_ok(), "Failed to delete user: {:?}", result.err());
assert!(result.unwrap(), "Delete operation should return true");
// 验证用户已被删除
let user_after_delete = store.get_user(&user_id).await.unwrap();
assert!(user_after_delete.is_none(), "User should not exist after deletion");
}
#[tokio::test]
async fn test_database_duplicate_username_constraint() {
let store = create_test_database().await.unwrap();
let user1 = User {
id: Uuid::new_v4(),
username: "duplicate_test".to_string(),
email: "test1@example.com".to_string(),
password_hash: "hashed_password1".to_string(),
role: UserRole::User,
created_at: Utc::now(),
updated_at: Utc::now(),
};
let user2 = User {
id: Uuid::new_v4(),
username: "duplicate_test".to_string(), // 相同用户名
email: "test2@example.com".to_string(),
password_hash: "hashed_password2".to_string(),
role: UserRole::User,
created_at: Utc::now(),
updated_at: Utc::now(),
};
// 创建第一个用户应该成功
let result1 = store.create_user(user1).await;
assert!(result1.is_ok(), "First user creation should succeed");
// 创建第二个用户应该失败(用户名重复)
let result2 = store.create_user(user2).await;
assert!(result2.is_err(), "Second user creation should fail due to duplicate username");
if let Err(ApiError::Conflict(msg)) = result2 {
assert!(msg.contains("用户名已存在"), "Error message should mention duplicate username");
} else {
panic!("Expected Conflict error for duplicate username, got: {:?}", result2);
}
}
#[tokio::test]
async fn test_database_nonexistent_user_operations() {
let store = create_test_database().await.unwrap();
let nonexistent_id = Uuid::new_v4();
// 获取不存在的用户
let result = store.get_user(&nonexistent_id).await;
assert!(result.is_ok(), "Getting nonexistent user should not error");
assert!(result.unwrap().is_none(), "Nonexistent user should return None");
// 按用户名获取不存在的用户
let result = store.get_user_by_username("nonexistent_user").await;
assert!(result.is_ok(), "Getting nonexistent user by username should not error");
assert!(result.unwrap().is_none(), "Nonexistent user should return None");
// 更新不存在的用户
let fake_user = create_test_user();
let result = store.update_user(&nonexistent_id, fake_user).await;
assert!(result.is_ok(), "Updating nonexistent user should not error");
assert!(result.unwrap().is_none(), "Updating nonexistent user should return None");
// 删除不存在的用户
let result = store.delete_user(&nonexistent_id).await;
assert!(result.is_ok(), "Deleting nonexistent user should not error");
assert!(!result.unwrap(), "Deleting nonexistent user should return false");
}
#[tokio::test]
async fn test_database_data_persistence() {
let temp_dir = tempdir().expect("Failed to create temp directory");
let db_path = temp_dir.path().join("persistence_test.db");
let database_url = format!("sqlite://{}?mode=rwc", db_path.display());
let user = create_test_user();
let user_id = user.id;
// 第一次连接:创建用户
{
let store = DatabaseUserStore::from_url(&database_url).await.unwrap();
store.create_user(user.clone()).await.unwrap();
}
// 第二次连接:验证用户仍然存在
{
let store = DatabaseUserStore::from_url(&database_url).await.unwrap();
let retrieved_user = store.get_user(&user_id).await.unwrap();
assert!(retrieved_user.is_some(), "User should persist across connections");
let retrieved_user = retrieved_user.unwrap();
assert_eq!(retrieved_user.username, user.username);
assert_eq!(retrieved_user.email, user.email);
}
}