#[cfg(test)] mod tests { use crate::sessions::{Session, SessionRepository}; use sqlx::{Pool, Postgres}; use sqlx::postgres::PgPoolOptions; use std::sync::Arc; use tokio::sync::Mutex; use utils::redis_cache::RedisCache; use uuid::Uuid; // Helper function to create a test database pool async fn create_test_pool() -> Pool { let database_url = std::env::var("TEST_DATABASE_URL") .unwrap_or_else(|_| "postgres://postgres:postgres@localhost:5432/test_db".to_string()); PgPoolOptions::new() .max_connections(5) .connect(&database_url) .await .expect("Failed to create test database pool") } // Helper function to create a mock Redis cache fn create_mock_redis() -> Arc> { let redis_url = std::env::var("TEST_REDIS_URL") .unwrap_or_else(|_| "redis://localhost:6379".to_string()); Arc::new(Mutex::new(RedisCache::new(&redis_url))) } // Helper function to create a test user in the database async fn create_test_user(pool: &Pool) -> i32 { let result = sqlx::query!( r#" INSERT INTO "user" (name, email, role, "createdAt", "updatedAt") VALUES ('test_session_user', 'test_session@example.com', 'user', NOW(), NOW()) RETURNING id "# ) .fetch_one(pool) .await .expect("Failed to create test user"); result.id } // Helper function to create a test session in the database async fn create_test_session(pool: &Pool, user_id: i32) -> String { let session_id = Uuid::new_v4().to_string(); sqlx::query!( r#" INSERT INTO session (id, "userId", "createdAt", "expiresAt") VALUES ($1, $2, NOW(), NOW() + INTERVAL '1 hour') "#, session_id, user_id ) .execute(pool) .await .expect("Failed to create test session"); session_id } // Helper function to clean up test data async fn cleanup_test_data(pool: &Pool, user_id: i32, session_id: &str) { sqlx::query!(r#"DELETE FROM session WHERE id = $1"#, session_id) .execute(pool) .await .expect("Failed to delete test session"); sqlx::query!(r#"DELETE FROM "user" WHERE id = $1"#, user_id) .execute(pool) .await .expect("Failed to delete test user"); } #[tokio::test] async fn test_get_session() { // Setup let pool = create_test_pool().await; let cache = create_mock_redis(); let repo = SessionRepository::new(pool.clone(), cache); // Create test user and session let user_id = create_test_user(&pool).await; let session_id = create_test_session(&pool, user_id).await; // Test let result = repo.get_session(&session_id).await; // Assert assert!(result.is_ok()); let session = result.unwrap(); assert_eq!(session.id, session_id); assert_eq!(session.user_id, user_id.to_string()); // Cleanup cleanup_test_data(&pool, user_id, &session_id).await; } #[tokio::test] async fn test_refresh_session() { // Setup let pool = create_test_pool().await; let cache = create_mock_redis(); let repo = SessionRepository::new(pool.clone(), cache); // Create test user and session let user_id = create_test_user(&pool).await; let session_id = create_test_session(&pool, user_id).await; // Test let result = repo.refresh_session(&session_id).await; // Assert assert!(result.is_ok()); let session = result.unwrap(); assert_eq!(session.id, session_id); assert_eq!(session.user_id, user_id.to_string()); // Cleanup cleanup_test_data(&pool, user_id, &session_id).await; } #[tokio::test] async fn test_get_nonexistent_session() { // Setup let pool = create_test_pool().await; let cache = create_mock_redis(); let repo = SessionRepository::new(pool.clone(), cache); // Test let result = repo.get_session("nonexistent-session-id").await; // Assert assert!(result.is_err()); } #[tokio::test] async fn test_session_cache() { // Setup let pool = create_test_pool().await; let cache = create_mock_redis(); let repo = SessionRepository::new(pool.clone(), cache.clone()); // Create test user and session let user_id = create_test_user(&pool).await; let session_id = create_test_session(&pool, user_id).await; // First call to populate cache let _ = repo.get_session(&session_id).await.unwrap(); // Delete from database to ensure we're getting from cache sqlx::query!(r#"DELETE FROM session WHERE id = $1"#, session_id) .execute(&pool) .await .expect("Failed to delete test session"); // Test - should still work because of cache let result = repo.get_session(&session_id).await; // Assert assert!(result.is_ok()); let session = result.unwrap(); assert_eq!(session.id, session_id); assert_eq!(session.user_id, user_id.to_string()); // Cleanup sqlx::query!(r#"DELETE FROM "user" WHERE id = $1"#, user_id) .execute(&pool) .await .expect("Failed to delete test user"); } }