//! Integration tests //! Run with: cargo test --test lib mod integration { use std::sync::Arc; use audit_logger::{ActionType, AuditLogger, InMemoryAuditStore, SearchParams}; #[tokio::test] async fn test_audit_logger_complete_workflow() { // Setup let store = Arc::new(InMemoryAuditStore::new()); let logger = AuditLogger::new(store, "test_service"); // Log multiple actions for i in 0..3 { logger .log_action( Some(format!("user_{}", i)), ActionType::Create, "users".to_string(), "/api/users".to_string(), ) .await .expect("Should log"); } // Search and verify let results = logger .search(SearchParams::default()) .await .expect("Should search"); assert_eq!(results.total, 3); assert_eq!(results.logs.len(), 3); } #[tokio::test] async fn test_audit_logger_error_handling() { let store = Arc::new(InMemoryAuditStore::new()); let logger = AuditLogger::new(store, "test"); let log = logger .log_error( Some("user".to_string()), ActionType::Delete, "resource".to_string(), "/api/resource".to_string(), "Not found".to_string(), ) .await .expect("Should log error"); assert_eq!(log.status, audit_logger::ActionStatus::Failure); assert!(log.error_details.is_some()); } #[tokio::test] async fn test_multiple_services_isolation() { 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"); logger1 .log_action( Some("user".to_string()), ActionType::Read, "data".to_string(), "/endpoint1".to_string(), ) .await .ok(); logger2 .log_action( Some("user".to_string()), ActionType::Write, "data".to_string(), "/endpoint2".to_string(), ) .await .ok(); let r1 = logger1.search(SearchParams::default()).await.ok(); let r2 = logger2.search(SearchParams::default()).await.ok(); assert_eq!(r1.map(|r| r.total), Some(1)); assert_eq!(r2.map(|r| r.total), Some(1)); } }