#![cfg(any(feature = "discord", feature = "slack"))]
#[cfg(feature = "discord")]
use crate::cron::scheduler::discord_chunks_for_delivery;
#[cfg(feature = "slack")]
use crate::cron::scheduler::slack_chunks_for_delivery;
#[cfg(feature = "discord")]
const REPORT: &str = "\
## AdGuard daily stats
| Metrik | Nilai |
|---|---|
| Total queries | 11.370 |
| Blocked | 2.950 (25,95%) |
| Allowed | 8.420 (74,05%) |
| Avg response time | 5,62 ms |
Top clients:
| Client | Queries |
|---|---|
| 192.168.1.10 | 4.201 |
| 192.168.1.24 | 2.118 |";
#[cfg(feature = "slack")]
const SLACK_REPORT: &str = "\
## Container state
| Metric | Before | After |
|---|---|---|
| RestartCount | 272 | 0 |
| Uptime | 30 min | 1h 44m |";
#[cfg(feature = "discord")]
#[test]
fn a_cron_report_reaches_discord_with_its_tables_converted() {
let chunks = discord_chunks_for_delivery(REPORT);
let joined = chunks.join("\n");
assert!(
!joined.contains("| Metrik |"),
"the raw table row survived delivery: {joined}"
);
assert!(
!joined.contains("|---|---|"),
"the raw separator row survived delivery: {joined}"
);
assert!(
!joined.contains("| Client |"),
"the second table survived delivery: {joined}"
);
assert!(
chunks.iter().any(|c| c.contains("```text")),
"no grid fence in any chunk: {joined}"
);
for row in ["Total queries", "Avg response time", "192.168.1.24"] {
assert!(joined.contains(row), "row '{row}' was dropped: {joined}");
}
}
#[cfg(feature = "discord")]
#[test]
fn a_grid_straddling_the_chunk_boundary_leaves_no_fence_open() {
let mut table = String::from("| Host | Metric | Value |\n|---|---|---|\n");
for i in 0..24 {
table.push_str(&format!("| node-{i:02} | cpu.load | {} |\n", i * 137));
}
for pad in 1800..2150 {
let report = format!("{}\n{table}", "x".repeat(pad));
let chunks = discord_chunks_for_delivery(&report);
for (i, chunk) in chunks.iter().enumerate() {
let fences = chunk.matches("```").count();
assert_eq!(
fences % 2,
0,
"chunk {i} of a {pad}-byte report leaves a fence open \
({fences} fence markers): {chunk}"
);
}
assert!(
chunks.join("\n").contains("node-23"),
"the last grid row was lost at padding {pad}"
);
}
}
#[cfg(feature = "discord")]
#[test]
fn a_report_without_tables_is_delivered_unchanged() {
let plain = "AdGuard daily stats\n\nAll clear today, nothing to convert.";
assert_eq!(discord_chunks_for_delivery(plain), vec![plain.to_string()]);
}
#[cfg(feature = "slack")]
#[test]
fn a_cron_report_reaches_slack_with_its_table_and_heading_converted() {
let chunks = slack_chunks_for_delivery(SLACK_REPORT);
let joined = chunks.join("\n");
assert!(
!joined.contains('|'),
"the raw table survived delivery: {joined}"
);
assert!(
!joined.contains("##"),
"the raw heading survived delivery: {joined}"
);
assert!(
joined.contains("*CONTAINER STATE*"),
"heading was not converted: {joined}"
);
assert!(
joined.contains("*RestartCount*"),
"row label missing: {joined}"
);
assert!(
joined.contains("└ Before: 272") && joined.contains("└ After: 0"),
"continuations missing: {joined}"
);
assert!(
joined.contains("└ Before: 30 min") && joined.contains("└ After: 1h 44m"),
"second row lost: {joined}"
);
}
#[cfg(feature = "slack")]
#[test]
fn a_slack_report_without_tables_is_delivered_unchanged() {
let plain = "AdGuard daily stats\n\nAll clear today, nothing to convert.";
assert_eq!(slack_chunks_for_delivery(plain), vec![plain.to_string()]);
}