//! 分页功能专项测试 use rust_user_api::{ models::{ user::User, pagination::{PaginationParams, PaginatedResponse}, search::UserSearchParams, role::UserRole, }, storage::{database::DatabaseUserStore, memory::MemoryUserStore, UserStore}, utils::errors::ApiError, }; use uuid::Uuid; use chrono::Utc; use std::sync::Arc; /// 创建测试用户 fn create_test_user(username: &str, email: &str) -> User { User { id: Uuid::new_v4(), username: username.to_string(), email: email.to_string(), password_hash: "hashed_password".to_string(), role: UserRole::User, created_at: Utc::now(), updated_at: Utc::now(), } } /// 创建多个测试用户 async fn create_multiple_users(store: &dyn UserStore, count: usize) -> Vec { let mut users = Vec::new(); for i in 0..count { let user = create_test_user( &format!("user{:02}", i + 1), &format!("user{}@example.com", i + 1), ); let created_user = store.create_user(user).await.unwrap(); users.push(created_user); // 添加小延迟确保创建时间不同 tokio::time::sleep(tokio::time::Duration::from_millis(1)).await; } users } /// 测试内存存储的分页功能 #[tokio::test] async fn test_memory_store_pagination() { let store = MemoryUserStore::new(); // 创建15个用户 let users = create_multiple_users(&store, 15).await; // 测试第一页(每页5个) let params = PaginationParams { page: Some(1), limit: Some(5), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 15, "总用户数应该是15"); assert_eq!(paginated_users.len(), 5, "第一页应该有5个用户"); // 测试第二页 let params = PaginationParams { page: Some(2), limit: Some(5), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 15, "总用户数应该是15"); assert_eq!(paginated_users.len(), 5, "第二页应该有5个用户"); // 测试第三页 let params = PaginationParams { page: Some(3), limit: Some(5), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 15, "总用户数应该是15"); assert_eq!(paginated_users.len(), 5, "第三页应该有5个用户"); // 测试第四页(超出范围) let params = PaginationParams { page: Some(4), limit: Some(5), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 15, "总用户数应该是15"); assert_eq!(paginated_users.len(), 0, "第四页应该没有用户"); } /// 测试数据库存储的分页功能 #[tokio::test] async fn test_database_store_pagination() { let database_url = "sqlite::memory:"; let store = DatabaseUserStore::from_url(database_url).await.unwrap(); // 创建12个用户 let users = create_multiple_users(&store, 12).await; // 测试第一页(每页4个) let params = PaginationParams { page: Some(1), limit: Some(4), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 12, "总用户数应该是12"); assert_eq!(paginated_users.len(), 4, "第一页应该有4个用户"); // 验证排序(应该按创建时间倒序) for i in 0..paginated_users.len() - 1 { assert!( paginated_users[i].created_at >= paginated_users[i + 1].created_at, "用户应该按创建时间倒序排列" ); } // 测试最后一页 let params = PaginationParams { page: Some(3), limit: Some(4), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 12, "总用户数应该是12"); assert_eq!(paginated_users.len(), 4, "第三页应该有4个用户"); } /// 测试分页参数的默认值和边界情况 #[tokio::test] async fn test_pagination_params_edge_cases() { let store = MemoryUserStore::new(); // 创建8个用户 create_multiple_users(&store, 8).await; // 测试默认参数 let params = PaginationParams { page: None, limit: None, }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 8, "总用户数应该是8"); assert_eq!(paginated_users.len(), 8, "默认应该返回所有用户(限制为10)"); // 测试页码为0(应该被修正为1) let params = PaginationParams { page: Some(0), limit: Some(3), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 8, "总用户数应该是8"); assert_eq!(paginated_users.len(), 3, "页码0应该被修正为1,返回3个用户"); // 测试超大限制(应该被限制为100) let params = PaginationParams { page: Some(1), limit: Some(200), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 8, "总用户数应该是8"); assert_eq!(paginated_users.len(), 8, "应该返回所有8个用户(限制为100)"); // 测试限制为0(应该被修正为1) let params = PaginationParams { page: Some(1), limit: Some(0), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 8, "总用户数应该是8"); assert_eq!(paginated_users.len(), 1, "限制0应该被修正为1"); } /// 测试空数据库的分页 #[tokio::test] async fn test_pagination_empty_database() { let store = MemoryUserStore::new(); let params = PaginationParams { page: Some(1), limit: Some(10), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); assert_eq!(total_count, 0, "空数据库总用户数应该是0"); assert_eq!(paginated_users.len(), 0, "空数据库应该返回空列表"); } /// 测试搜索功能的分页 #[tokio::test] async fn test_search_pagination() { let store = MemoryUserStore::new(); // 创建用户,其中一些包含"admin" let users = vec![ create_test_user("admin1", "admin1@example.com"), create_test_user("user1", "user1@example.com"), create_test_user("admin2", "admin2@example.com"), create_test_user("user2", "user2@example.com"), create_test_user("admin3", "admin3@example.com"), create_test_user("user3", "user3@example.com"), ]; for user in users { store.create_user(user).await.unwrap(); } // 搜索包含"admin"的用户,第一页 let search_params = UserSearchParams { q: Some("admin".to_string()), ..Default::default() }; let pagination_params = PaginationParams { page: Some(1), limit: Some(2), }; let (search_results, total_count) = store.search_users(&search_params, &pagination_params).await.unwrap(); assert_eq!(total_count, 3, "应该找到3个admin用户"); assert_eq!(search_results.len(), 2, "第一页应该返回2个用户"); // 验证搜索结果 for user in &search_results { assert!( user.username.contains("admin") || user.email.contains("admin"), "搜索结果应该包含admin关键词" ); } // 搜索第二页 let pagination_params = PaginationParams { page: Some(2), limit: Some(2), }; let (search_results, total_count) = store.search_users(&search_params, &pagination_params).await.unwrap(); assert_eq!(total_count, 3, "总数应该仍然是3"); assert_eq!(search_results.len(), 1, "第二页应该返回1个用户"); } /// 测试PaginatedResponse结构 #[tokio::test] async fn test_paginated_response_structure() { let store = MemoryUserStore::new(); // 创建7个用户 create_multiple_users(&store, 7).await; let params = PaginationParams { page: Some(2), limit: Some(3), }; let (users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); let response = PaginatedResponse::new( users.into_iter().map(|u| u.username).collect(), ¶ms, total_count ); // 验证分页信息 assert_eq!(response.pagination.current_page, 2); assert_eq!(response.pagination.per_page, 3); assert_eq!(response.pagination.total_pages, 3); // 7个用户,每页3个,共3页 assert_eq!(response.pagination.total_items, 7); assert!(response.pagination.has_prev, "第二页应该有上一页"); assert!(response.pagination.has_next, "第二页应该有下一页"); // 测试第一页 let params = PaginationParams { page: Some(1), limit: Some(3), }; let (users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); let response = PaginatedResponse::new( users.into_iter().map(|u| u.username).collect(), ¶ms, total_count ); assert!(!response.pagination.has_prev, "第一页不应该有上一页"); assert!(response.pagination.has_next, "第一页应该有下一页"); // 测试最后一页 let params = PaginationParams { page: Some(3), limit: Some(3), }; let (users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); let response = PaginatedResponse::new( users.into_iter().map(|u| u.username).collect(), ¶ms, total_count ); assert!(response.pagination.has_prev, "最后一页应该有上一页"); assert!(!response.pagination.has_next, "最后一页不应该有下一页"); assert_eq!(response.data.len(), 1, "最后一页应该有1个用户"); } /// 测试分页功能的性能(大数据量) #[tokio::test] async fn test_pagination_performance() { let store = MemoryUserStore::new(); // 创建100个用户 create_multiple_users(&store, 100).await; let start = std::time::Instant::now(); // 测试获取中间页面的性能 let params = PaginationParams { page: Some(50), limit: Some(2), }; let (paginated_users, total_count) = store.list_users_paginated(¶ms).await.unwrap(); let duration = start.elapsed(); assert_eq!(total_count, 100, "总用户数应该是100"); assert_eq!(paginated_users.len(), 2, "应该返回2个用户"); // 性能检查:应该在合理时间内完成(这里设置为100ms,实际应该更快) assert!(duration.as_millis() < 100, "分页查询应该在100ms内完成,实际用时: {:?}", duration); }