use crate::channels::slack::tool_group::{
DetachedEvent, DetachedRender, GroupEntry, detached_render,
};
fn started<'a>(task_id: &'a str, label: &'a str) -> DetachedEvent<'a> {
DetachedEvent::Started { task_id, label }
}
fn finished<'a>(task_id: &'a str, success: bool) -> DetachedEvent<'a> {
DetachedEvent::Finished { task_id, success }
}
#[test]
fn detached_finish_edits_the_same_ts_the_start_created() {
let mut entries: Vec<GroupEntry> = Vec::new();
let start = detached_render(&mut entries, None, started("t-1", "cargo test"));
assert_eq!(start, DetachedRender::Post);
let group_ts = "1712345678.000100";
let finish = detached_render(&mut entries, Some(group_ts), finished("t-1", true));
assert_eq!(
finish,
DetachedRender::Edit(group_ts.to_string()),
"the finish must rewrite the group the start created, never post"
);
assert_eq!(entries.len(), 1, "one task, one row, one message");
let GroupEntry::Tool { status, .. } = &entries[0] else {
panic!("a detached task is a tool row");
};
assert_eq!(*status, Some(true), "the row settled in place");
assert_eq!(
entries[0].display_name(),
"detached task finished: cargo test",
"the same row now reads finished"
);
}
#[test]
fn a_start_on_an_existing_group_edits_it_instead_of_posting() {
let mut entries: Vec<GroupEntry> = Vec::new();
let action = detached_render(
&mut entries,
Some("1712345678.000200"),
started("t-2", "npm build"),
);
assert_eq!(
action,
DetachedRender::Edit("1712345678.000200".to_string()),
"a group that already exists must be edited, not replaced"
);
assert_eq!(entries.len(), 1);
assert_eq!(
entries[0].display_name(),
"detached task running: npm build"
);
}
#[test]
fn two_detached_tasks_settle_by_their_own_id_not_their_label() {
let mut entries: Vec<GroupEntry> = Vec::new();
let ts = "1712345678.000300";
detached_render(&mut entries, Some(ts), started("t-1", "cargo test"));
detached_render(&mut entries, Some(ts), started("t-2", "cargo test"));
detached_render(&mut entries, Some(ts), finished("t-1", true));
let GroupEntry::Tool { status: first, .. } = &entries[0] else {
panic!("row 0 is a tool row");
};
let GroupEntry::Tool { status: second, .. } = &entries[1] else {
panic!("row 1 is a tool row");
};
assert_eq!(*first, Some(true), "the finished task settled");
assert_eq!(*second, None, "the still-running task must not settle");
assert_eq!(
entries[1].display_name(),
"detached task running: cargo test",
"the second task keeps its running label"
);
}
#[test]
fn an_orphan_finish_renders_nothing_and_invents_no_row() {
let mut entries: Vec<GroupEntry> = Vec::new();
let action = detached_render(
&mut entries,
Some("1712345678.000400"),
finished("never-started-here", true),
);
assert_eq!(action, DetachedRender::Skip, "no row to settle, no edit");
assert!(entries.is_empty(), "an orphan finish must not create a row");
}
#[test]
fn a_finish_never_posts_even_when_the_row_exists_but_the_block_does_not() {
let mut entries: Vec<GroupEntry> = Vec::new();
detached_render(&mut entries, None, started("t-3", "cargo build"));
assert_eq!(entries.len(), 1);
let action = detached_render(&mut entries, None, finished("t-3", false));
assert_eq!(
action,
DetachedRender::Skip,
"a finish with no block must not post one"
);
let GroupEntry::Tool { status, .. } = &entries[0] else {
panic!("a detached task is a tool row");
};
assert_eq!(*status, Some(false), "the row still records the failure");
assert_eq!(
entries[0].display_name(),
"detached task failed: cargo build",
"the label reports the failure even when the message is gone"
);
}
#[test]
fn an_ordinary_tool_row_is_unaffected_by_the_label() {
let plain = GroupEntry::Tool {
name: "bash".to_string(),
context: " cargo test".to_string(),
status: Some(true),
task_id: None,
};
assert_eq!(plain.display_name(), "bash");
}