use crate::channels::telegram::markdown::markdown_to_telegram_html;
use crate::channels::telegram::rich::detect::{
contains_details, has_rich_structure, is_details_open, prefers_rich_render,
};
fn result_card() -> String {
"<details>\n<summary><sub>✅ `build` 🕒 1s</sub></summary>\n\n\
```\ntest result: FAILED. 0 passed; 5 failed\n```\n\n</details>"
.to_string()
}
#[test]
fn details_opener_matches_bare_and_attributed_forms() {
assert!(is_details_open("<details>"));
assert!(is_details_open("<details open>"));
assert!(is_details_open("<details><summary>inline</summary>"));
assert!(!is_details_open("</details>"));
assert!(!is_details_open("details about the failure"));
}
#[test]
fn contains_details_finds_an_indented_opener() {
assert!(contains_details(&result_card()));
assert!(contains_details("intro\n <details open>\nbody"));
assert!(!contains_details("no collapse here\njust prose"));
}
#[test]
fn rich_gate_and_fallback_renderer_agree_on_details() {
let card = result_card();
assert!(
has_rich_structure(&card),
"collapse must qualify for the native rich send"
);
assert!(
prefers_rich_render(&card),
"the HTML fallback must render the same collapse through the rich AST"
);
}
#[test]
fn details_fallback_emits_no_literal_collapse_markup() {
let html = markdown_to_telegram_html(&result_card());
for leaked in [
"<details>",
"<summary>",
"<sub>",
"</details>",
] {
assert!(
!html.contains(leaked),
"escaped collapse markup leaked into the delivered message: {leaked} in {html}"
);
}
assert!(
html.contains('▸'),
"collapse summary should survive as a flat header: {html}"
);
assert!(
html.contains("build"),
"summary text should survive the downgrade: {html}"
);
}
#[test]
fn plain_prose_still_uses_the_line_renderer() {
assert!(!prefers_rich_render("just a sentence with **bold** in it"));
}
#[test]
fn lone_sub_opener_in_prose_is_still_escaped() {
let html = markdown_to_telegram_html(
"<details>\n<summary>x</summary>\n\nuse <sub> here\n\n</details>",
);
assert!(
html.contains("<sub>"),
"an unmatched tag is prose, not markup: {html}"
);
}