mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-10-08 01:42:05 +00:00
test: drive a real Bot against a stand-in API
Every test went through `MockSender`, so `media_sender`'s `Bot` implementation — the URL it builds, the multipart it sends, the per-chat limiter and the bot-wide budget it charges — was never exercised, and neither was any handler reached from a real update. The two things that made that hard are gone: - `media_sender::test_support::fake_api::FakeApi` is a stand-in for `api.telegram.org`: a `tokio` TCP listener that reads one HTTP/1.1 request (JSON or multipart), records it and answers the smallest result the method needs. No new dependency, and `Bot::new(token).set_api_url(api.url())` points a real `Bot` at it. Note for future tests: teloxide keys methods by payload type, so the path is `SendMediaGroup`, not `sendMediaGroup`. - `message_handler` built its own `AppContext::from_statics` internally, so no test could reach its branches; its body is now `handle_message(ctx, bot, message)` with `message_handler` as the thin `dptree` entry. Tests: a media group through the real `Bot` (asserting the multipart fields — chat, media URL, caption — and that the send charged the chat's limiter), the forward button through the real callback path (`CopyMessages`, `DeleteMessage`, `AnswerCallbackQuery` with the prompt's ids and the toast text), and `handle_message` twice (a prompt reply becoming an `EditMessageCaption`, and a supported link in a group producing the one explanatory `SendMessage`). Also closes the redirect-hop gap left open by the download guard: the live `a_redirect_into_the_hosts_network_is_refused` follows a public redirector to `169.254.169.254` and asserts the policy refuses the hop (verified against httpbin.org here, and by mutation — disabling the hop check fails it). Docs: AGENTS.md's testing conventions and untested-modules list (the Bot implementation and the handler branches are covered now; `main.rs`'s startup/shutdown and its `dptree` tree still are not). `cargo fmt`, `cargo clippy --workspace --all-targets --locked -- -D warnings`, `cargo test --workspace --locked` (201 passed, 16 ignored) clean.
This commit is contained in:
@@ -216,7 +216,7 @@ async fn handle_callback(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ctx::test_support::{PROMPT_ID, TestStores, api_error, seed_prompt};
|
||||
use crate::ctx::test_support::{FORWARDED_ID, PROMPT_ID, TestStores, api_error, seed_prompt};
|
||||
use crate::media_sender::test_support::{MockSender, Outcome};
|
||||
|
||||
/// The Telegram wording the mocks answer with: a chat the bot cannot reach.
|
||||
@@ -315,6 +315,33 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// The whole callback path against a stand-in API through a real `Bot`:
|
||||
/// copy, delete, toast, carrying the ids the prompt held. The scripted
|
||||
/// mock records that a call happened; this records what the API received.
|
||||
#[tokio::test]
|
||||
async fn the_forward_button_talks_to_the_api_through_a_real_bot() {
|
||||
use crate::media_sender::test_support::fake_api::FakeApi;
|
||||
use teloxide::Bot;
|
||||
|
||||
let api = FakeApi::start().await;
|
||||
let bot = Bot::new("42:TEST").set_api_url(api.url());
|
||||
let stores = TestStores::new();
|
||||
let ctx = stores.ctx(&bot);
|
||||
seed_prompt(&ctx, "", crate::db::unix_now()).await;
|
||||
|
||||
handle_callback(&ctx, callback_id(), 1, PROMPT_ID, "forward").await;
|
||||
|
||||
assert_eq!(
|
||||
api.methods(),
|
||||
vec!["CopyMessages", "DeleteMessage", "AnswerCallbackQuery"]
|
||||
);
|
||||
let copy = api.body("CopyMessages");
|
||||
assert_eq!(copy["chat_id"], 2, "the prompt's channel");
|
||||
assert_eq!(copy["from_chat_id"], 1);
|
||||
assert_eq!(copy["message_ids"], serde_json::json!([FORWARDED_ID]));
|
||||
assert_eq!(api.body("AnswerCallbackQuery")["text"], "✅ Forwarded");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn forward_without_a_channel_is_reported() {
|
||||
let sender = MockSender::scripted(vec![], || api_error(API_ERROR));
|
||||
|
||||
Reference in New Issue
Block a user