//! 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::("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)); }