From 008d31b9bda1f260f9015466afefcf73f090e5af Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Thu, 24 Sep 2026 20:56:05 +0800 Subject: [PATCH] test: cover inline answer edge cases --- crates/xmedia-bot/src/handlers/inline.rs | 48 +++++++++++++++++++----- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/crates/xmedia-bot/src/handlers/inline.rs b/crates/xmedia-bot/src/handlers/inline.rs index 16b0eba..af1d605 100644 --- a/crates/xmedia-bot/src/handlers/inline.rs +++ b/crates/xmedia-bot/src/handlers/inline.rs @@ -331,7 +331,6 @@ fn cached_inline_results(cached: &CachedPost, caption: &str) -> Vec Vec Vec, + mut results: Vec, ) -> Result<(), RequestError> { + results.truncate(50); if results.is_empty() { log::debug!("inline: nothing Telegram can serve for the query; answering empty"); } @@ -493,8 +489,21 @@ mod tests { ); } - #[test] - fn inline_results_are_capped_at_telegram_limit() { + #[tokio::test] + async fn unsupported_inline_query_answers_empty() { + let sender = MockSender::scripted(vec![], || api_error("boom")); + let stores = TestStores::new(); + let ctx = stores.ctx(&sender); + let answered = answer_inline_query(&ctx, inline_query("not a supported post")) + .await + .unwrap(); + assert!(answered); + assert_eq!(sender.inline_answers(), vec![Vec::::new()]); + } + + #[tokio::test] + async fn answer_caps_cached_results_at_telegram_limit() { + let sender = MockSender::scripted(vec![], || api_error("boom")); let mut entry = cached_photo(); entry.media = (0..51) .map(|i| CachedMedia { @@ -503,7 +512,16 @@ mod tests { url: format!("https://p/{i}.jpg"), }) .collect(); - assert_eq!(cached_inline_results(&entry, "caption").len(), 50); + let results = cached_inline_results(&entry, "caption"); + assert!(results.len() > 50, "the builder itself may keep all items"); + super::answer( + &sender, + inline_query("https://x.com/u/status/1").id, + results, + ) + .await + .unwrap(); + assert_eq!(sender.inline_answers()[0].len(), 50); } #[test] @@ -546,6 +564,18 @@ mod tests { assert!(states.note(1, URL_A).0); } + #[test] + fn stale_same_query_generation_cannot_claim_after_a_b_a() { + let mut states = DebounceStates::default(); + assert!(states.note(1, URL_A).0); + assert!(states.note(1, URL_B).0); + let (_, stale_generation) = states.note(1, URL_A); + let (_, current_generation) = states.note(1, URL_A); + assert_ne!(stale_generation, current_generation); + assert!(!states.claim(1, URL_A, stale_generation)); + assert!(states.claim(1, URL_A, current_generation)); + } + #[test] fn newer_query_supersedes_and_failed_answer_is_released() { let mut states = DebounceStates::default();