//! 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)] = &[ ("!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:?}"), } }