Files

143 lines
4.5 KiB
Rust

//! A leading mention of this bot is stripped before anything reads a message, and approval
//! commands are recognised exactly (M4b spec, section 7). Do not edit.
use gatewayd::mm::Post;
use gatewayd::sessions::{
ApprovalCommand, MAX_REASON, Route, Router, approval_command, strip_mention,
};
const ME: &str = "boxmaker0";
const BOT: &str = "b0000000000000000000000000";
const KYLE: &str = "k0000000000000000000000000";
const SHARED: &str = "c0000000000000000000000000";
const ROOT: &str = "r0000000000000000000000000";
#[test]
fn a_leading_mention_is_stripped() {
assert_eq!(
strip_mention("@boxmaker0 summarise the log", ME),
"summarise the log"
);
assert_eq!(strip_mention("@BoxMaker0 !approve 42", ME), "!approve 42");
assert_eq!(
strip_mention("@boxmaker0 @hermes compare notes", ME),
"@hermes compare notes"
);
assert_eq!(strip_mention("@boxmaker0, look", ME), ", look");
assert_eq!(
strip_mention("@boxmaker0\nsecond line", ME),
"\nsecond line",
"only spaces go with it"
);
}
#[test]
fn anything_else_is_kept() {
for message in [
"@boxmaker0",
"@boxmaker0 ",
"@boxmaker0x hello",
"@hermes @boxmaker0 hello",
"hello @boxmaker0",
" @boxmaker0 hello",
"@ boxmaker0 hello",
"@@boxmaker0 hello",
"",
] {
assert_eq!(strip_mention(message, ME), message, "{message:?}");
}
assert_eq!(
strip_mention("@boxmaker0. hi", ME),
". hi",
"the trailing dot is not part of the name"
);
}
#[test]
fn approval_commands_exactly() {
use ApprovalCommand::{Approve, Deny, Malformed};
let cases: &[(&str, Option<ApprovalCommand>)] = &[
("!approve 42", Some(Approve(42))),
("!approve 0", Some(Approve(0))),
("!approve 18446744073709551615", Some(Approve(u64::MAX))),
("!deny 42", Some(Deny(42, None))),
(
"!deny 42 not on a Friday",
Some(Deny(42, Some("not on a Friday".to_string()))),
),
(
"!deny 42 two spaces",
Some(Deny(42, Some(" two spaces".to_string()))),
),
("!approve", Some(Malformed)),
("!approve 42", Some(Malformed)),
("!approve 42 ", Some(Malformed)),
("!approve 42 now", Some(Malformed)),
("!approve +42", Some(Malformed)),
("!approve 4x2", Some(Malformed)),
("!approve 18446744073709551616", Some(Malformed)),
("!deny", Some(Malformed)),
("!deny 42 ", Some(Malformed)),
("!deny x reason", Some(Malformed)),
("!approved 42", None),
("!denied 42", None),
("!help", None),
("approve 42", None),
("!Approve 42", None),
];
for (text, want) in cases {
assert_eq!(&approval_command(text), want, "{text:?}");
}
let long = format!("!deny 42 {}", "é".repeat(MAX_REASON));
assert!(
matches!(approval_command(&long), Some(Deny(42, Some(_)))),
"characters, not bytes"
);
let over = format!("!deny 42 {}", "x".repeat(MAX_REASON + 1));
assert_eq!(approval_command(&over), Some(Malformed));
}
fn post(message: &str, root: &str) -> Post {
Post {
id: "p0000000000000000000000001".to_string(),
user_id: KYLE.to_string(),
channel_id: SHARED.to_string(),
root_id: root.to_string(),
message: message.to_string(),
create_at: 9,
delete_at: 0,
kind: String::new(),
}
}
#[test]
fn in_a_shared_thread_the_mention_picks_the_bot() {
let me = Router::new(BOT, ME, &[KYLE.to_string()], &[SHARED.to_string()]);
let ours = |root: &str| root == ROOT;
let addressed = me.route(&post("@boxmaker0 !approve 42", ROOT), "O", &ours);
assert!(
matches!(
addressed,
Route::Approval {
command: ApprovalCommand::Approve(42),
..
}
),
"{addressed:?}"
);
let other = me.route(&post("@boxmaker1 !approve 42", ROOT), "O", &ours);
assert!(
matches!(other, Route::Ignore(_)),
"addressed to another bot: {other:?}"
);
let bare = me.route(&post("!approve 42", ROOT), "O", &ours);
assert!(
matches!(bare, Route::Approval { .. }),
"a bare command in our thread is ours too: {bare:?}"
);
match me.route(&post("@boxmaker0 hello there", ""), "O", &ours) {
Route::Queue(m) => assert_eq!(m.text, "hello there"),
other => panic!("{other:?}"),
}
}