use super::*;
use crate::storage::CacheData;
use crate::test_utils::init_test_environment;
#[derive(Debug, PartialEq)]
pub struct TestError(String);
impl CacheErrorConversion<TestError> for TestError {
fn convert_storage_error(error: StorageError) -> TestError {
TestError(error.to_string())
}
}
impl TryFrom<CacheData> for String {
type Error = TestError;
fn try_from(cache_data: CacheData) -> Result<Self, Self::Error> {
Ok(cache_data.value)
}
}
impl From<String> for CacheData {
fn from(value: String) -> Self {
CacheData { value }
}
}
#[tokio::test]
async fn test_store_cache_keyed_legacy_compatibility() {
init_test_environment().await;
let test_data = "test_value".to_string();
let prefix = CachePrefix::new("data".to_string()).unwrap();
let key = CacheKey::new("test_key".to_string()).unwrap();
let result =
store_cache_keyed::<_, TestError>(prefix.clone(), key.clone(), test_data.clone(), 3600)
.await;
assert!(result.is_ok());
let retrieved = get_data::<String, TestError>(prefix, key).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), Some(test_data));
}
#[tokio::test]
async fn test_store_cache_auto_legacy_compatibility() {
init_test_environment().await;
let test_data = "test_value".to_string();
let prefix = CachePrefix::new("data".to_string()).unwrap();
let result = store_cache_auto::<_, TestError>(prefix.clone(), test_data.clone(), 3600).await;
assert!(result.is_ok());
let generated_key = result.unwrap();
let retrieved = get_data::<String, TestError>(prefix, generated_key).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), Some(test_data));
}
#[tokio::test]
async fn test_remove_data() {
init_test_environment().await;
let test_data = "test_value".to_string();
let prefix = CachePrefix::new("data".to_string()).unwrap();
let key = CacheKey::new("test_key".to_string()).unwrap();
store_cache_keyed::<_, TestError>(prefix.clone(), key.clone(), test_data.clone(), 3600)
.await
.unwrap();
let retrieved = get_data::<String, TestError>(prefix.clone(), key.clone()).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), Some(test_data));
let result = remove_data::<TestError>(prefix.clone(), key.clone()).await;
assert!(result.is_ok());
let retrieved = get_data::<String, TestError>(prefix, key).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), None);
}
#[tokio::test]
async fn test_truly_unified_cache_operations_with_validation() {
init_test_environment().await;
let prefix = CachePrefix::session();
let key = CacheKey::new("test_unified_key".to_string()).unwrap();
let data = "unified_test_data".to_string();
let store_result =
store_cache_keyed::<_, TestError>(prefix.clone(), key.clone(), data.clone(), 300).await;
assert!(store_result.is_ok());
let get_result = get_data::<String, TestError>(prefix.clone(), key.clone()).await;
assert!(get_result.is_ok());
assert_eq!(get_result.unwrap(), Some(data));
let remove_result = remove_data::<TestError>(prefix.clone(), key.clone()).await;
assert!(remove_result.is_ok());
let verify_result = get_data::<String, TestError>(prefix, key).await;
assert!(verify_result.is_ok());
assert_eq!(verify_result.unwrap(), None);
let malicious_key_result = CacheKey::new("malicious\nSET attack".to_string());
assert!(
malicious_key_result.is_err(),
"Malicious key should be rejected at construction"
);
let malicious_prefix_result = CachePrefix::new("SET attack".to_string());
assert!(
malicious_prefix_result.is_err(),
"Malicious prefix should be rejected at construction"
);
}
#[tokio::test]
async fn test_store_cache_auto_simple_api() {
init_test_environment().await;
let test_data = "auto_generated_test_data".to_string();
let prefix = CachePrefix::new("test_auto".to_string()).unwrap();
let result = store_cache_auto::<_, TestError>(prefix.clone(), test_data.clone(), 300).await;
assert!(result.is_ok());
let generated_key = result.unwrap();
let retrieved = get_data::<String, TestError>(prefix.clone(), generated_key.clone()).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), Some(test_data));
let remove_result = remove_data::<TestError>(prefix, generated_key).await;
assert!(remove_result.is_ok());
}
#[tokio::test]
async fn test_store_cache_keyed_simple_api() {
init_test_environment().await;
let test_data = "meaningful_key_test_data".to_string();
let prefix = CachePrefix::new("test_keyed".to_string()).unwrap();
let meaningful_key = CacheKey::new("aaguid_12345678".to_string()).unwrap();
let result = store_cache_keyed::<_, TestError>(
prefix.clone(),
meaningful_key.clone(),
test_data.clone(),
300,
)
.await;
assert!(result.is_ok());
let retrieved = get_data::<String, TestError>(prefix.clone(), meaningful_key.clone()).await;
assert!(retrieved.is_ok());
assert_eq!(retrieved.unwrap(), Some(test_data));
let remove_result = remove_data::<TestError>(prefix, meaningful_key).await;
assert!(remove_result.is_ok());
}
#[tokio::test]
async fn test_simplified_api_demonstration() {
init_test_environment().await;
let test_data = "api_demo_test_data".to_string();
let prefix = CachePrefix::new("api_demo".to_string()).unwrap();
let auto_result =
store_cache_auto::<_, TestError>(prefix.clone(), test_data.clone(), 300).await;
assert!(auto_result.is_ok());
let generated_key: CacheKey = auto_result.unwrap();
let meaningful_key = CacheKey::new("meaningful_identifier".to_string()).unwrap();
let keyed_result = store_cache_keyed::<_, TestError>(
prefix.clone(),
meaningful_key.clone(),
test_data.clone(),
300,
)
.await;
assert!(keyed_result.is_ok());
let auto_retrieved = get_data::<String, TestError>(prefix.clone(), generated_key).await;
let keyed_retrieved = get_data::<String, TestError>(prefix, meaningful_key).await;
assert!(auto_retrieved.is_ok());
assert!(keyed_retrieved.is_ok());
assert_eq!(auto_retrieved.unwrap(), Some(test_data.clone()));
assert_eq!(keyed_retrieved.unwrap(), Some(test_data));
}