test(app): add unit tests for app

This commit is contained in:
2025-08-09 22:43:02 +02:00
parent 12cf26d8a6
commit e7b35953ca
4 changed files with 188 additions and 0 deletions

77
Cargo.lock generated
View File

@@ -17,6 +17,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "atomic-waker"
version = "1.1.2"
@@ -119,6 +125,12 @@ version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "downcast"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
[[package]]
name = "encoding_rs"
version = "0.8.35"
@@ -180,6 +192,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fragile"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
[[package]]
name = "futures-channel"
version = "0.3.31"
@@ -618,6 +636,32 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "mockall"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"
dependencies = [
"cfg-if",
"downcast",
"fragile",
"mockall_derive",
"predicates",
"predicates-tree",
]
[[package]]
name = "mockall_derive"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"
dependencies = [
"cfg-if",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "native-tls"
version = "0.2.14"
@@ -641,6 +685,7 @@ version = "0.1.0"
dependencies = [
"discord_client",
"dotenvy",
"mockall",
"system_monitor",
]
@@ -764,6 +809,32 @@ dependencies = [
"zerovec",
]
[[package]]
name = "predicates"
version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
dependencies = [
"anstyle",
"predicates-core",
]
[[package]]
name = "predicates-core"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
[[package]]
name = "predicates-tree"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
dependencies = [
"predicates-core",
"termtree",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
@@ -1110,6 +1181,12 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "termtree"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
[[package]]
name = "tinystr"
version = "0.8.1"

View File

@@ -8,3 +8,6 @@ dotenvy = "0.15.7"
discord_client = { path = "lib/actors/discord_client" }
system_monitor = { path = "lib/actors/system_monitor" }
[dev-dependencies]
mockall = "0.13.1"

View File

@@ -1,19 +1,26 @@
use std::collections::HashMap;
#[cfg(test)]
use mockall::automock;
#[cfg_attr(test, automock)]
pub trait ForSendingNotification {
fn send_notification(&self, message: &str) -> Result<(), Box<dyn std::error::Error>>;
}
#[cfg_attr(test, automock)]
pub trait ForMonitoringSystem {
fn check_thresholds(&self) -> Vec<Box<dyn ForGettingViolationData>>;
fn get_metrics(&self) -> HashMap<String, f32>;
}
#[cfg_attr(test, automock)]
pub trait ForFormattingMessage {
fn format_violation(&self, violation: Box<dyn ForGettingViolationData>) -> String;
fn format_summary(&self, metrics: &HashMap<String, f32>) -> String;
}
#[cfg_attr(test, automock)]
pub trait ForGettingViolationData {
fn is_critical(&self) -> bool;
fn get_metric_name(&self) -> String;

View File

@@ -40,3 +40,104 @@ impl Service {
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();
// Set up expectations for the mocks
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_send_all_metrics_notification() {
let mut notifier = MockForSendingNotification::new();
let mut monitor = MockForMonitoringSystem::new();
let mut formatter = MockForFormattingMessage::new();
// Set up expectations for the mocks
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.send_all_metrics_notification().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();
// Mock a single violation to trigger notification
monitor.expect_check_thresholds().returning(|| {
vec![Box::new(crate::app::ports::driven::MockForGettingViolationData::new())]
});
formatter.expect_format_violation().returning(|_| "Test violation".to_string());
// Mock notification failure
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());
}
#[test]
fn test_send_all_metrics_notification_handles_send_error() {
let mut notifier = MockForSendingNotification::new();
let mut monitor = MockForMonitoringSystem::new();
let mut formatter = MockForFormattingMessage::new();
monitor.expect_get_metrics().returning(|| HashMap::new());
formatter.expect_format_summary().returning(|_| "Test summary".to_string());
// Mock notification failure
notifier.expect_send_notification()
.returning(|_| Err("Network error".into()));
let service = new(
Box::new(notifier),
Box::new(monitor),
Box::new(formatter),
);
assert!(service.send_all_metrics_notification().is_err());
}
}