//! SQLite 数据库存储测试 use rust_user_api::{ models::user::User, storage::{database::DatabaseUserStore, UserStore}, utils::errors::ApiError, }; use uuid::Uuid; use chrono::Utc; use tempfile::tempdir; /// 创建临时数据库用于测试 async fn create_test_database() -> Result { // 使用内存数据库避免文件系统问题 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(), 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(), 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(), 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 = 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(), 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(), 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); } }