#![allow(clippy::unwrap_used)]
#![allow(clippy::indexing_slicing)]
use std::fs;
use std::time::{SystemTime, UNIX_EPOCH};
use tempfile::TempDir;
fn create_mock_cache(dir: &TempDir, filename: &str, age_seconds: u64, auth_failed: bool) -> String {
let cache_path = dir.path().join(filename);
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let timestamp = now - age_seconds;
let status = if auth_failed { "1" } else { "0" };
fs::write(&cache_path, format!("{timestamp}:{status}")).unwrap();
cache_path.to_str().unwrap().to_string()
}
#[test]
fn test_auth_cache_file_creation() {
let dir = TempDir::new().unwrap();
let cache_path = create_mock_cache(&dir, "auth_test", 0, true);
assert!(fs::metadata(&cache_path).is_ok());
let content = fs::read_to_string(&cache_path).unwrap();
assert!(content.ends_with(":1"));
}
#[test]
fn test_auth_cache_parsing_success() {
let dir = TempDir::new().unwrap();
let cache_path = create_mock_cache(&dir, "auth_test", 0, false);
let content = fs::read_to_string(&cache_path).unwrap();
let parts: Vec<&str> = content.split(':').collect();
assert_eq!(parts.len(), 2);
assert_eq!(parts[1], "0"); }
#[test]
fn test_auth_cache_parsing_failure() {
let dir = TempDir::new().unwrap();
let cache_path = create_mock_cache(&dir, "auth_test", 0, true);
let content = fs::read_to_string(&cache_path).unwrap();
let parts: Vec<&str> = content.split(':').collect();
assert_eq!(parts.len(), 2);
assert_eq!(parts[1], "1"); }
#[test]
fn test_auth_cache_fresh() {
let dir = TempDir::new().unwrap();
let _cache_path = create_mock_cache(&dir, "auth_test", 0, true);
let content = fs::read_to_string(dir.path().join("auth_test")).unwrap();
let (ts_str, _) = content.split_once(':').unwrap();
let cached_time: u64 = ts_str.parse().unwrap();
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
assert!(now - cached_time < 300); }
#[test]
fn test_auth_cache_expired() {
let dir = TempDir::new().unwrap();
let _cache_path = create_mock_cache(&dir, "auth_test", 301, true);
let content = fs::read_to_string(dir.path().join("auth_test")).unwrap();
let (ts_str, _) = content.split_once(':').unwrap();
let cached_time: u64 = ts_str.parse().unwrap();
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
assert!(now - cached_time >= 300); }
#[test]
fn test_auth_cache_exactly_5_minutes() {
let dir = TempDir::new().unwrap();
let _cache_path = create_mock_cache(&dir, "auth_test", 300, true);
let content = fs::read_to_string(dir.path().join("auth_test")).unwrap();
let (ts_str, _) = content.split_once(':').unwrap();
let cached_time: u64 = ts_str.parse().unwrap();
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
let age = now - cached_time;
assert!((299..=301).contains(&age));
}
#[test]
fn test_auth_cache_missing_file() {
let dir = TempDir::new().unwrap();
let cache_path = dir.path().join("nonexistent");
assert!(fs::read_to_string(&cache_path).is_err());
}
#[test]
fn test_auth_cache_invalid_format() {
let dir = TempDir::new().unwrap();
let cache_path = dir.path().join("invalid_cache");
fs::write(&cache_path, "invalid_content").unwrap();
let content = fs::read_to_string(&cache_path).unwrap();
assert!(content.split_once(':').is_none());
}
#[test]
fn test_auth_cache_invalid_timestamp() {
let dir = TempDir::new().unwrap();
let cache_path = dir.path().join("invalid_timestamp");
fs::write(&cache_path, "not_a_number:1").unwrap();
let content = fs::read_to_string(&cache_path).unwrap();
let (ts_str, _) = content.split_once(':').unwrap();
assert!(ts_str.parse::<u64>().is_err());
}
#[test]
fn test_auth_cache_multiple_writes() {
let dir = TempDir::new().unwrap();
let cache_path = dir.path().join("auth_test");
create_mock_cache(&dir, "auth_test", 0, true);
let content1 = fs::read_to_string(&cache_path).unwrap();
assert!(content1.ends_with(":1"));
create_mock_cache(&dir, "auth_test", 0, false);
let content2 = fs::read_to_string(&cache_path).unwrap();
assert!(content2.ends_with(":0"));
}
#[test]
fn test_auth_cache_path_generation() {
let hash1 = "/home/user/repo1/.git".bytes().fold(0u64, |acc, b| {
acc.wrapping_mul(31).wrapping_add(u64::from(b))
});
let hash2 = "/home/user/repo2/.git".bytes().fold(0u64, |acc, b| {
acc.wrapping_mul(31).wrapping_add(u64::from(b))
});
assert_ne!(hash1, hash2);
}
#[test]
fn test_auth_cache_whitespace_in_status() {
let dir = TempDir::new().unwrap();
let cache_path = dir.path().join("auth_test");
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs();
fs::write(&cache_path, format!("{now}:1\n")).unwrap();
let content = fs::read_to_string(&cache_path).unwrap();
let (_, status) = content.split_once(':').unwrap();
assert_eq!(status.trim(), "1");
}