ConversationHandler: Fix wrong signature call for timeout handlers

Fixes #1652

Co-authored-by: Eldinnie <Eldinnie@users.noreply.github.com>
This commit is contained in:
tobiaswicker 2020-01-11 19:51:31 +01:00 committed by Noam Meltzer
parent a582515766
commit 940b42e048
2 changed files with 75 additions and 8 deletions

View file

@ -393,8 +393,10 @@ class ConversationHandler(Handler):
self.logger.debug('conversation timeout was triggered!')
# Backward compatibility with bots that do not use CallbackContext
callback_context = None
if isinstance(context, CallbackContext):
job = context.job
callback_context = context
context = job.context
@ -409,5 +411,5 @@ class ConversationHandler(Handler):
for handler in handlers:
check = handler.check_update(context.update)
if check is not None and check is not False:
handler.handle_update(context.update, context.dispatcher, check)
handler.handle_update(context.update, context.dispatcher, check, callback_context)
self.update_state(self.END, context.conversation_key)

View file

@ -24,7 +24,7 @@ import pytest
from telegram import (CallbackQuery, Chat, ChosenInlineResult, InlineQuery, Message,
PreCheckoutQuery, ShippingQuery, Update, User, MessageEntity)
from telegram.ext import (ConversationHandler, CommandHandler, CallbackQueryHandler,
MessageHandler, Filters, InlineQueryHandler)
MessageHandler, Filters, InlineQueryHandler, CallbackContext)
@pytest.fixture(scope='class')
@ -117,7 +117,10 @@ class TestConversationHandler(object):
# Actions
def start(self, bot, update):
if isinstance(update, Update):
return self._set_state(update, self.THIRSTY)
else:
return self._set_state(bot, self.THIRSTY)
def end(self, bot, update):
return self._set_state(update, self.END)
@ -129,7 +132,10 @@ class TestConversationHandler(object):
return self._set_state(update, None)
def brew(self, bot, update):
if isinstance(update, Update):
return self._set_state(update, self.BREWING)
else:
return self._set_state(bot, self.BREWING)
def drink(self, bot, update):
return self._set_state(update, self.DRINKING)
@ -139,9 +145,20 @@ class TestConversationHandler(object):
def passout(self, bot, update):
assert update.message.text == '/brew'
assert isinstance(update, Update)
self.is_timeout = True
def passout2(self, bot, update):
assert isinstance(update, Update)
self.is_timeout = True
def passout_context(self, update, context):
assert update.message.text == '/brew'
assert isinstance(context, CallbackContext)
self.is_timeout = True
def passout2_context(self, update, context):
assert isinstance(context, CallbackContext)
self.is_timeout = True
# Drinking actions (nested)
@ -613,6 +630,54 @@ class TestConversationHandler(object):
assert handler.conversations.get((self.group.id, user1.id)) is None
assert not self.is_timeout
def test_conversation_handler_timeout_state_context(self, cdp, bot, user1):
states = self.states
states.update({ConversationHandler.TIMEOUT: [
CommandHandler('brew', self.passout_context),
MessageHandler(~Filters.regex('oding'), self.passout2_context)
]})
handler = ConversationHandler(entry_points=self.entry_points, states=states,
fallbacks=self.fallbacks, conversation_timeout=0.5)
cdp.add_handler(handler)
# CommandHandler timeout
message = Message(0, user1, None, self.group, text='/start',
entities=[MessageEntity(type=MessageEntity.BOT_COMMAND, offset=0,
length=len('/start'))],
bot=bot)
cdp.process_update(Update(update_id=0, message=message))
message.text = '/brew'
message.entities[0].length = len('/brew')
cdp.process_update(Update(update_id=0, message=message))
sleep(0.5)
cdp.job_queue.tick()
assert handler.conversations.get((self.group.id, user1.id)) is None
assert self.is_timeout
# MessageHandler timeout
self.is_timeout = False
message.text = '/start'
message.entities[0].length = len('/start')
cdp.process_update(Update(update_id=1, message=message))
sleep(0.5)
cdp.job_queue.tick()
assert handler.conversations.get((self.group.id, user1.id)) is None
assert self.is_timeout
# Timeout but no valid handler
self.is_timeout = False
cdp.process_update(Update(update_id=0, message=message))
message.text = '/brew'
message.entities[0].length = len('/brew')
cdp.process_update(Update(update_id=0, message=message))
message.text = '/startCoding'
message.entities[0].length = len('/startCoding')
cdp.process_update(Update(update_id=0, message=message))
sleep(0.5)
cdp.job_queue.tick()
assert handler.conversations.get((self.group.id, user1.id)) is None
assert not self.is_timeout
def test_conversation_timeout_cancel_conflict(self, dp, bot, user1):
# Start state machine, wait half the timeout,
# then call a callback that takes more than the timeout