use crate::channels::telegram::handler::{
ReplyMediaKind, format_reply_context_pruned, resolve_reply_context_pruned,
};
const NOT_STORED: &str = "The replied-to message is a photo and its file was not stored \
locally, so you cannot see it. If you need to look at it, ask the \
user to send it again.";
#[test]
fn media_kind_labels_are_the_words_the_agent_reads() {
assert_eq!(ReplyMediaKind::Photo.label(), "photo");
assert_eq!(ReplyMediaKind::Video.label(), "video");
assert_eq!(ReplyMediaKind::Animation.label(), "animation");
assert_eq!(ReplyMediaKind::VideoNote.label(), "video note");
assert_eq!(ReplyMediaKind::Document.label(), "document");
}
#[test]
fn media_kind_of_detects_each_media_field() {
let cases = [
(
r#"{"message_id":1,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"photo":[{"file_id":"p","file_unique_id":"pu","width":90,"height":90}]}"#,
Some(ReplyMediaKind::Photo),
),
(
r#"{"message_id":2,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"video":{"file_id":"v","file_unique_id":"vu","width":90,"height":90,"duration":3,
"mime_type":"video/mp4"}}"#,
Some(ReplyMediaKind::Video),
),
(
r#"{"message_id":3,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"animation":{"file_id":"a","file_unique_id":"au","width":90,"height":90,"duration":3,
"mime_type":"video/mp4"}}"#,
Some(ReplyMediaKind::Animation),
),
(
r#"{"message_id":4,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"video_note":{"file_id":"n","file_unique_id":"nu","length":90,"duration":3,
"mime_type":"video/mp4"}}"#,
Some(ReplyMediaKind::VideoNote),
),
(
r#"{"message_id":5,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"document":{"file_id":"d","file_unique_id":"du"}}"#,
Some(ReplyMediaKind::Document),
),
(
r#"{"message_id":6,"date":1700000000,"chat":{"id":7,"type":"private","first_name":"A"},
"text":"just words"}"#,
None,
),
];
for (json, expected) in cases {
let msg: teloxide::types::Message =
serde_json::from_str(json).expect("fixture must deserialize");
assert_eq!(
ReplyMediaKind::of(&msg),
expected,
"wrong media kind for {json}"
);
}
}
#[test]
fn uncaptioned_media_reply_produces_context_naming_the_file() {
let ctx = format_reply_context_pruned("Alice", "", "", false, Some(NOT_STORED))
.expect("a media reply must produce context");
assert!(ctx.contains("Replying to Alice"), "{ctx}");
assert!(ctx.contains("photo"), "{ctx}");
assert!(
ctx.contains("not stored locally"),
"the agent must be told it cannot see the file: {ctx}"
);
}
#[test]
fn captioned_media_reply_keeps_the_caption_and_names_the_file() {
let ctx = format_reply_context_pruned("Alice", "look at this", "", false, Some(NOT_STORED))
.expect("a captioned media reply must produce context");
assert!(ctx.contains("look at this"), "caption lost: {ctx}");
assert!(ctx.contains("photo"), "media kind lost: {ctx}");
}
#[test]
fn media_note_does_not_override_an_unrecoverable_note() {
let ctx = resolve_reply_context_pruned("Alice", "", "", true, false, Some(NOT_STORED))
.expect("must produce context");
assert!(ctx.contains("not stored locally"), "{ctx}");
assert!(
!ctx.contains("could not be retrieved"),
"generic unrecoverable note must not mask the media note: {ctx}"
);
}
#[test]
fn non_media_reply_is_unchanged_by_the_new_parameter() {
assert_eq!(
resolve_reply_context_pruned("Alice", "", "", false, false, None),
None
);
assert_eq!(
format_reply_context_pruned("Bob", "hello there", "", false, None).unwrap(),
"[Replying to Bob: \"hello there\"]"
);
}
#[test]
fn blank_media_note_is_ignored() {
assert_eq!(
format_reply_context_pruned("Alice", "", "", false, Some(" ")),
None
);
}