mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-09-26 23:52:05 +00:00
fix(handlers): honour the TTL when a caption-edit reply arrives
A button press on an edit-before-forward prompt already dropped records past EDIT_MESSAGE_TTL lazily (before the 300 s sweep clears them); a text reply to the same prompt did not — it rewrote the caption from a record the sweep was about to treat as dead, so the two paths disagreed about what 'expired' means. The reply path now applies the same rule: drop the stale record, return false, and let the message flow on as if no prompt existed. The test seeds a prompt90000 s old (past the TTL under any config a parallel test can hold) and pins all three effects: no edit consumed, no API call, record gone.
This commit is contained in:
@@ -141,6 +141,17 @@ async fn edit_message_handler(
|
||||
let Some(edit) = chat_data.edit_message.get(&reply_to_message_id) else {
|
||||
return false;
|
||||
};
|
||||
// Lazy expiry, the same rule a button press gets: a record past the TTL
|
||||
// (not yet swept) is dropped and the reply falls through to the normal
|
||||
// message flow instead of rewriting a caption from a dead prompt.
|
||||
if edit.created_at + ctx.config.edit_message_ttl.as_secs() as i64 <= crate::db::unix_now() {
|
||||
ctx.chat_store
|
||||
.update(chat_id, |data| {
|
||||
data.edit_message.remove(&reply_to_message_id);
|
||||
})
|
||||
.await;
|
||||
return false;
|
||||
}
|
||||
let Some(first_forward_id) = edit.forward_message_ids.first() else {
|
||||
return false;
|
||||
};
|
||||
@@ -317,6 +328,27 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn a_reply_to_an_expired_prompt_is_not_edited() {
|
||||
// 90 000 s ago: past the TTL under any config a test can hold.
|
||||
let sender = MockSender::scripted(vec![], || api_error(API_ERROR));
|
||||
let stores = TestStores::new();
|
||||
let ctx = stores.ctx(&sender);
|
||||
seed_prompt(&ctx, "tpl", crate::db::unix_now() - 90_000).await;
|
||||
|
||||
let consumed = edit_message_handler(&ctx, 1, PROMPT_ID, "new caption").await;
|
||||
|
||||
assert!(!consumed, "an expired prompt must not consume the reply");
|
||||
assert!(
|
||||
sender.captions().is_empty(),
|
||||
"no caption edit may reach a dead prompt"
|
||||
);
|
||||
assert!(
|
||||
stores.chat_store().get(1).await.edit_message.is_empty(),
|
||||
"the stale record must be dropped for good"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn reply_to_a_prompt_swaps_the_caption_through_its_template() {
|
||||
let sender = MockSender::scripted(vec![Outcome::EditOk], || api_error(API_ERROR));
|
||||
|
||||
Reference in New Issue
Block a user