cubenet_backend/tests/integration/audit_logger_integration.rs

248 lines
6.7 KiB
Rust

//! Integration tests for Cubenet Backend
//!
//! These tests verify the integration between components
//! and can be used as templates for new services.
use std::sync::Arc;
use audit_logger::{ActionType, AuditLogger, InMemoryAuditStore, SearchParams};
#[tokio::test]
async fn test_audit_logger_integration() {
// Setup
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
// Test: Log action
let log = logger
.log_action(
Some("user_123".to_string()),
ActionType::Create,
"users".to_string(),
"/api/users".to_string(),
)
.await
.expect("Should log action");
assert_eq!(log.user_id, Some("user_123".to_string()));
assert_eq!(log.action, ActionType::Create);
assert_eq!(log.service, "test_service");
}
#[tokio::test]
async fn test_audit_logger_detailed_logging() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
let log = logger
.log_detailed(
Some("user_456".to_string()),
ActionType::Update,
"users".to_string(),
"/api/users/456".to_string(),
Some("192.168.1.1".to_string()),
Some("Mozilla/5.0".to_string()),
Some("Updated user profile".to_string()),
)
.await
.expect("Should log detailed");
assert_eq!(log.ip_address, Some("192.168.1.1".to_string()));
assert_eq!(log.user_agent, Some("Mozilla/5.0".to_string()));
assert_eq!(log.description, Some("Updated user profile".to_string()));
}
#[tokio::test]
async fn test_audit_logger_error_logging() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
let log = logger
.log_error(
Some("user_789".to_string()),
ActionType::Delete,
"users".to_string(),
"/api/users/789".to_string(),
"User not found".to_string(),
)
.await
.expect("Should log error");
assert_eq!(log.status, audit_logger::ActionStatus::Failure);
assert_eq!(log.error_details, Some("User not found".to_string()));
}
#[tokio::test]
async fn test_audit_logger_login_logout() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "auth_service");
// Login
let login_log = logger
.log_login(
"user_login".to_string(),
Some("10.0.0.1".to_string()),
Some("Chrome".to_string()),
)
.await
.expect("Should log login");
assert_eq!(login_log.action, ActionType::Login);
assert_eq!(login_log.user_id, Some("user_login".to_string()));
// Logout
let logout_log = logger
.log_logout("user_login".to_string(), Some("10.0.0.1".to_string()))
.await
.expect("Should log logout");
assert_eq!(logout_log.action, ActionType::Logout);
}
#[tokio::test]
async fn test_audit_logger_search() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
// Log multiple actions
for i in 0..5 {
logger
.log_action(
Some(format!("user_{}", i)),
ActionType::Read,
"users".to_string(),
"/api/users".to_string(),
)
.await
.ok();
}
// Search all logs
let results = logger
.search(SearchParams::default())
.await
.expect("Should search");
assert_eq!(results.total, 5);
assert_eq!(results.logs.len(), 5);
}
#[tokio::test]
async fn test_audit_logger_search_by_user() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
// Log actions for different users
logger
.log_action(
Some("user_a".to_string()),
ActionType::Create,
"users".to_string(),
"/api/users".to_string(),
)
.await
.ok();
logger
.log_action(
Some("user_b".to_string()),
ActionType::Create,
"users".to_string(),
"/api/users".to_string(),
)
.await
.ok();
logger
.log_action(
Some("user_a".to_string()),
ActionType::Update,
"users".to_string(),
"/api/users/1".to_string(),
)
.await
.ok();
// Search for user_a logs
let logs = logger
.get_user_logs("user_a", 100)
.await
.expect("Should get user logs");
assert_eq!(logs.len(), 2);
assert!(logs.iter().all(|log| log.user_id == Some("user_a".to_string())));
}
#[tokio::test]
async fn test_audit_logger_timed_success() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
let result = logger
.log_timed(
Some("user_123".to_string()),
ActionType::Read,
"data".to_string(),
"/api/data".to_string(),
async { Ok::<_, String>(42) },
)
.await
.expect("Should log timed");
assert_eq!(result, 42);
}
#[tokio::test]
async fn test_audit_logger_timed_error() {
let store = Arc::new(InMemoryAuditStore::new());
let logger = AuditLogger::new(store, "test_service");
let result = logger
.log_timed(
Some("user_123".to_string()),
ActionType::Read,
"data".to_string(),
"/api/data".to_string(),
async { Err::<i32, _>("Operation failed".to_string()) },
)
.await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_multiple_services_separate_loggers() {
let store1 = Arc::new(InMemoryAuditStore::new());
let logger1 = AuditLogger::new(store1, "service_1");
let store2 = Arc::new(InMemoryAuditStore::new());
let logger2 = AuditLogger::new(store2, "service_2");
// Log to both services
logger1
.log_action(
Some("user".to_string()),
ActionType::Create,
"resource".to_string(),
"/endpoint1".to_string(),
)
.await
.ok();
logger2
.log_action(
Some("user".to_string()),
ActionType::Delete,
"resource".to_string(),
"/endpoint2".to_string(),
)
.await
.ok();
// Verify each logger has only its own logs
let results1 = logger1.search(SearchParams::default()).await.ok();
let results2 = logger2.search(SearchParams::default()).await.ok();
assert_eq!(results1.map(|r| r.total), Some(1));
assert_eq!(results2.map(|r| r.total), Some(1));
}