use crate::app::ports::driven::{ ForFormattingMessage, ForMonitoringSystem, ForSendingNotification, }; pub struct AlertService { notifier: Box, monitor: Box, formatter: Box, } pub fn new( notifier: Box, monitor: Box, formatter: Box, ) -> AlertService { AlertService { notifier, monitor, formatter, } } impl AlertService { /// Check for threshold violations and send alerts pub fn alert_on_threshold_violation(&self) -> Result<(), Box> { let violations = self.monitor.check_thresholds(); for violation in violations { let message = self.formatter.format_violation(violation); self.notifier.send_notification(&message)?; } Ok(()) } } #[cfg(test)] mod tests { use std::collections::HashMap; use crate::app::ports::driven::{MockForFormattingMessage, MockForMonitoringSystem, MockForSendingNotification}; use super::*; #[test] fn test_alert_on_threshold_violation() { let mut notifier = MockForSendingNotification::new(); let mut monitor = MockForMonitoringSystem::new(); let mut formatter = MockForFormattingMessage::new(); notifier.expect_send_notification().returning(|_| Ok(())); monitor.expect_check_thresholds().returning(|| vec![]); monitor.expect_get_metrics().returning(|| HashMap::new()); formatter.expect_format_violation().returning(|_| "".to_string()); formatter.expect_format_summary().returning(|_| "".to_string()); let service = new( Box::new(notifier), Box::new(monitor), Box::new(formatter), ); assert!(service.alert_on_threshold_violation().is_ok()); } #[test] fn test_alert_on_threshold_violation_handles_send_error() { let mut notifier = MockForSendingNotification::new(); let mut monitor = MockForMonitoringSystem::new(); let mut formatter = MockForFormattingMessage::new(); monitor.expect_check_thresholds().returning(|| { vec![Box::new(crate::app::ports::driven::MockForGettingViolationData::new())] }); formatter.expect_format_violation().returning(|_| "Test violation".to_string()); notifier.expect_send_notification() .returning(|_| Err("Network error".into())); let service = new( Box::new(notifier), Box::new(monitor), Box::new(formatter), ); assert!(service.alert_on_threshold_violation().is_err()); } }