use code_mesh_core::auth::*;
use proptest::prelude::*;
use rstest::*;
use std::sync::Arc;
use tempfile::TempDir;
use tokio::fs;
mod common;
use common::{mocks::*, *};
#[tokio::test]
async fn test_auth_storage_file_operations() {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
let token = "test-auth-token-123";
auth_storage.save_token(token.to_string()).await.unwrap();
let loaded_token = auth_storage.load_token().await.unwrap();
assert_eq!(loaded_token, Some(token.to_string()));
auth_storage.delete_token().await.unwrap();
let deleted_token = auth_storage.load_token().await.unwrap();
assert_eq!(deleted_token, None);
}
#[tokio::test]
async fn test_auth_storage_nonexistent_token() {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
let token = auth_storage.load_token().await.unwrap();
assert_eq!(token, None);
}
#[tokio::test]
async fn test_auth_storage_overwrite_token() {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
auth_storage.save_token("token1".to_string()).await.unwrap();
let token1 = auth_storage.load_token().await.unwrap();
assert_eq!(token1, Some("token1".to_string()));
auth_storage.save_token("token2".to_string()).await.unwrap();
let token2 = auth_storage.load_token().await.unwrap();
assert_eq!(token2, Some("token2".to_string()));
}
#[tokio::test]
async fn test_auth_storage_concurrent_access() {
let temp_dir = temp_dir();
let auth_storage = Arc::new(AuthStorage::new(temp_dir.path().to_path_buf()));
let handles: Vec<_> = (0..10)
.map(|i| {
let storage = Arc::clone(&auth_storage);
tokio::spawn(async move {
storage.save_token(format!("token-{}", i)).await
})
})
.collect();
for handle in handles {
handle.await.unwrap().unwrap();
}
let final_token = auth_storage.load_token().await.unwrap();
assert!(final_token.is_some());
assert!(final_token.unwrap().starts_with("token-"));
}
#[test]
fn test_auth_provider_anthropic_config() {
let provider = AuthProvider::Anthropic {
api_key: "test-key".to_string(),
base_url: None,
};
match provider {
AuthProvider::Anthropic { api_key, base_url } => {
assert_eq!(api_key, "test-key");
assert_eq!(base_url, None);
}
_ => panic!("Expected Anthropic provider"),
}
}
#[test]
fn test_auth_provider_openai_config() {
let provider = AuthProvider::OpenAI {
api_key: "test-key".to_string(),
base_url: Some("https://api.openai.com/v1".to_string()),
organization: Some("org-123".to_string()),
};
match provider {
AuthProvider::OpenAI { api_key, base_url, organization } => {
assert_eq!(api_key, "test-key");
assert_eq!(base_url, Some("https://api.openai.com/v1".to_string()));
assert_eq!(organization, Some("org-123".to_string()));
}
_ => panic!("Expected OpenAI provider"),
}
}
#[rstest]
#[case("sk-ant-1234567890", true)]
#[case("", false)]
#[case("invalid", false)]
#[case("sk-ant-", false)]
fn test_validate_anthropic_key(#[case] key: &str, #[case] expected_valid: bool) {
let provider = AuthProvider::Anthropic {
api_key: key.to_string(),
base_url: None,
};
let result = provider.validate();
assert_eq!(result.is_ok(), expected_valid);
}
#[rstest]
#[case("sk-1234567890", true)]
#[case("", false)]
#[case("invalid", false)]
fn test_validate_openai_key(#[case] key: &str, #[case] expected_valid: bool) {
let provider = AuthProvider::OpenAI {
api_key: key.to_string(),
base_url: None,
organization: None,
};
let result = provider.validate();
assert_eq!(result.is_ok(), expected_valid);
}
proptest! {
#[test]
fn test_auth_storage_property_based(
token in r"[a-zA-Z0-9\-_]{10,100}"
) {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
auth_storage.save_token(token.clone()).await.unwrap();
let loaded = auth_storage.load_token().await.unwrap();
prop_assert_eq!(loaded, Some(token));
});
}
#[test]
fn test_auth_provider_serialization(
api_key in r"[a-zA-Z0-9\-_]{10,50}",
base_url in option::of(r"https?://[a-zA-Z0-9\.\-/]+")
) {
let provider = AuthProvider::Anthropic {
api_key: api_key.clone(),
base_url: base_url.clone(),
};
let serialized = serde_json::to_string(&provider).unwrap();
let deserialized: AuthProvider = serde_json::from_str(&serialized).unwrap();
match deserialized {
AuthProvider::Anthropic { api_key: deserialized_key, base_url: deserialized_url } => {
prop_assert_eq!(deserialized_key, api_key);
prop_assert_eq!(deserialized_url, base_url);
}
_ => prop_assert!(false, "Deserialized to wrong variant"),
}
}
}
#[tokio::test]
async fn test_auth_storage_permissions() {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
auth_storage.save_token("secret-token".to_string()).await.unwrap();
let token_file = temp_dir.path().join("auth_token");
let metadata = fs::metadata(token_file).await.unwrap();
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mode = metadata.permissions().mode();
assert_eq!(mode & 0o777, 0o600);
}
}
#[tokio::test]
async fn test_auth_storage_invalid_directory() {
let invalid_path = std::path::PathBuf::from("/nonexistent/path");
let auth_storage = AuthStorage::new(invalid_path);
let result = auth_storage.save_token("test".to_string()).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_auth_storage_corrupted_file() {
let temp_dir = temp_dir();
let token_file = temp_dir.path().join("auth_token");
fs::write(&token_file, b"\xFF\xFE\xFF\xFE").await.unwrap();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
let result = auth_storage.load_token().await;
assert!(result.is_err() || result.unwrap().is_none());
}
#[test]
fn test_auth_provider_display() {
let anthropic = AuthProvider::Anthropic {
api_key: "sk-ant-test".to_string(),
base_url: None,
};
let openai = AuthProvider::OpenAI {
api_key: "sk-test".to_string(),
base_url: None,
organization: None,
};
let anthropic_display = format!("{}", anthropic);
let openai_display = format!("{}", openai);
assert!(!anthropic_display.contains("sk-ant-test"));
assert!(!openai_display.contains("sk-test"));
assert!(anthropic_display.contains("Anthropic"));
assert!(openai_display.contains("OpenAI"));
}
#[test]
fn test_auth_provider_debug() {
let provider = AuthProvider::Anthropic {
api_key: "sk-ant-test".to_string(),
base_url: None,
};
let debug_output = format!("{:?}", provider);
assert!(!debug_output.contains("sk-ant-test"));
assert!(debug_output.contains("[REDACTED]") || debug_output.contains("***"));
}
#[tokio::test]
async fn test_auth_with_mock_storage() {
let mut mock_storage = MockAuthStorage::new();
mock_storage
.expect_save_token()
.with(eq("test-token".to_string()))
.times(1)
.returning(|_| Ok(()));
mock_storage
.expect_load_token()
.times(1)
.returning(|| Ok(Some("test-token".to_string())));
mock_storage.save_token("test-token".to_string()).await.unwrap();
let token = mock_storage.load_token().await.unwrap();
assert_eq!(token, Some("test-token".to_string()));
}
#[cfg(feature = "bench")]
mod benchmarks {
use super::*;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn bench_auth_storage_save_load(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
c.bench_function("auth_storage_save_load", |b| {
b.to_async(&rt).iter(|| async {
let temp_dir = temp_dir();
let auth_storage = AuthStorage::new(temp_dir.path().to_path_buf());
auth_storage.save_token(black_box("benchmark-token".to_string())).await.unwrap();
let _token = auth_storage.load_token().await.unwrap();
});
});
}
criterion_group!(benches, bench_auth_storage_save_load);
criterion_main!(benches);
}