use serde::{Deserialize, Serialize}; use std::env; use tokio::sync::Mutex; use utils::redis_cache::{Cache, RedisCache}; #[derive(Debug, Serialize, Deserialize, PartialEq)] struct TestData { id: i32, name: String, value: f64, } #[tokio::test] async fn test_redis_cache_set_get() { // Skip test if REDIS_TEST_ENABLED is not set to true if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" { println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run."); return; } let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string()); let cache = RedisCache::new(&redis_url); let key = "test_key_set_get".to_string(); let test_data = TestData { id: 1, name: "test".to_string(), value: 3.14, }; // Test setting a value let set_result = cache.set(&key, &test_data, 10).await; assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err()); // Test getting the value let get_result: Result, _> = cache.get(&key).await; assert!(get_result.is_ok(), "Failed to get value: {:?}", get_result.err()); let retrieved_data = get_result.unwrap(); assert!(retrieved_data.is_some(), "Retrieved data is None"); assert_eq!(retrieved_data.unwrap(), test_data); } #[tokio::test] async fn test_redis_cache_update() { // Skip test if REDIS_TEST_ENABLED is not set to true if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" { println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run."); return; } let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string()); let cache = RedisCache::new(&redis_url); let key = "test_key_update".to_string(); let initial_data = TestData { id: 2, name: "initial".to_string(), value: 2.71, }; let updated_data = TestData { id: 2, name: "updated".to_string(), value: 2.71, }; // Set initial value let set_result = cache.set(&key, &initial_data, 10).await; assert!(set_result.is_ok(), "Failed to set initial value: {:?}", set_result.err()); // Update the value let update_result = cache.update(&key, Some(&updated_data), Some(10)).await; assert!(update_result.is_ok(), "Failed to update value: {:?}", update_result.err()); // Get the updated value let get_result: Result, _> = cache.get(&key).await; assert!(get_result.is_ok(), "Failed to get updated value: {:?}", get_result.err()); let retrieved_data = get_result.unwrap(); assert!(retrieved_data.is_some(), "Retrieved data is None"); assert_eq!(retrieved_data.unwrap(), updated_data); } #[tokio::test] async fn test_redis_cache_delete() { // Skip test if REDIS_TEST_ENABLED is not set to true if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" { println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run."); return; } let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string()); let mut cache = RedisCache::new(&redis_url); let key = "test_key_delete".to_string(); let test_data = TestData { id: 3, name: "delete_test".to_string(), value: 1.618, }; // Set a value let set_result = cache.set(&key, &test_data, 10).await; assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err()); // Delete the value let delete_result = cache.delete(&key).await; assert!(delete_result.is_ok(), "Failed to delete value: {:?}", delete_result.err()); // Verify the value is gone let get_result: Result, _> = cache.get(&key).await; assert!(get_result.is_ok(), "Failed to get value after deletion: {:?}", get_result.err()); assert!(get_result.unwrap().is_none(), "Value still exists after deletion"); } #[tokio::test] async fn test_redis_cache_refresh() { // Skip test if REDIS_TEST_ENABLED is not set to true if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" { println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run."); return; } let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string()); let cache = RedisCache::new(&redis_url); let key = "test_key_refresh".to_string(); let test_data = TestData { id: 4, name: "refresh_test".to_string(), value: 0.577, }; // Set a value with a short TTL let set_result = cache.set(&key, &test_data, 5).await; assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err()); // Refresh the TTL let refresh_result = cache.refresh(&key, 30).await; assert!(refresh_result.is_ok(), "Failed to refresh TTL: {:?}", refresh_result.err()); // Wait for the original TTL to expire tokio::time::sleep(tokio::time::Duration::from_secs(6)).await; // Verify the value still exists due to the refresh let get_result: Result, _> = cache.get(&key).await; assert!(get_result.is_ok(), "Failed to get value after refresh: {:?}", get_result.err()); let retrieved_data = get_result.unwrap(); assert!(retrieved_data.is_some(), "Value expired despite TTL refresh"); assert_eq!(retrieved_data.unwrap(), test_data); }