Files
boxmaker/docs/plans/M4b/files/crates/gatewayd/tests/approvals_asked.rs
T
kyleandClaude Opus 5.5 f6dd7f1741 M4b review, and follow-up tasks 16 to 18
The review of tasks 01 to 15 goes in the implementer log, with the
device check against the owner's Mattermost. Three follow-ups:

- 16: the refusal without a runner says why.
- 17: the texts that say who asked.
- 18: approvals from non-approvers in direct or group messages go to
  an approver.

Task 14's given serve_approvals.rs becomes serve_approvals.rs-task14,
since task 18 hands over a new version. Tip T31 is added.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 11:35:24 -07:00

87 lines
2.6 KiB
Rust

//! The posts that tell an approver who asked for a redirected approval and what, and the line left
//! in the asking thread (M4b spec, section 6, after the review). Do not edit.
use gatewayd::approvals::text::{
Asked, PROMPT_SHOWN, asked_post, sent_to_approver, unfollowed_post,
};
/// The escape for one code point, built here so this file holds no such character itself.
fn esc(code: u32) -> String {
format!("{}u{code:04x}", char::from(92))
}
fn asked(prompt: &str, channel_type: &str) -> Asked {
Asked {
by: "@alex".to_string(),
channel_type: channel_type.to_string(),
prompt: prompt.to_string(),
}
}
#[test]
fn who_where_and_what_they_asked() {
assert_eq!(
asked_post(
3,
&asked("Read the file /srv/notes/q3.txt and summarise it.", "D")
),
"**Approval 3** was asked by @alex in a direct message with the bot. Their message:\n```\nRead the file /srv/notes/q3.txt and summarise it.\n```"
);
let group = asked_post(4, &asked("first\n\nsecond", "G"));
assert_eq!(
group,
"**Approval 4** was asked by @alex in a group message with the bot. Their message:\n```\nfirst\n\nsecond\n```",
"a burst keeps its lines"
);
}
#[test]
fn the_message_is_escaped_and_fenced() {
let hostile = format!(
"see ``` and @channel{}{}",
char::from_u32(0x202e).unwrap(),
char::from(7)
);
let post = asked_post(5, &asked(&hostile, "D"));
assert!(
post.contains(&format!(
"\n````\nsee ``` and @channel{}{}\n````",
esc(0x202e),
esc(7)
)),
"{post}"
);
assert!(!post.contains(char::from_u32(0x202e).unwrap()) && !post.contains(char::from(7)));
}
#[test]
fn a_long_message_is_cut_and_says_how_much() {
let long = "é".repeat(PROMPT_SHOWN + 25);
let post = asked_post(6, &asked(&long, "D"));
assert!(
post.ends_with(&format!(
"\n```\n{}\n```\n(… 25 more characters)",
"é".repeat(PROMPT_SHOWN)
)),
"{}",
&post[post.len() - 80..]
);
let exact = asked_post(6, &asked(&"x".repeat(PROMPT_SHOWN), "D"));
assert!(
!exact.contains("more characters"),
"nothing cut, nothing said"
);
}
#[test]
fn an_unfollowed_session_and_the_note() {
assert_eq!(
unfollowed_post(9, "chat-1789700000-1"),
"**Approval 9** was asked in session `chat-1789700000-1`, which gatewayd does not follow now (a restart, or a session from outside Mattermost)."
);
assert_eq!(
sent_to_approver(3),
"waiting for approval 3: it was sent to an approver"
);
}