Entry returns None ends conversation (#1270)

* Fix unresolvable promises

* added async test and description

* added test_none_on_first_message for conv_handler

* Small change in ConversationHandler docstring

* Fix test to work with new commandhandler
This commit is contained in:
Kirill Vasin 2019-02-14 14:29:58 +03:00 committed by Eldinnie
parent dda7ca18cd
commit 60f2044bbd
2 changed files with 43 additions and 3 deletions

View file

@ -64,9 +64,10 @@ class ConversationHandler(Handler):
To change the state of conversation, the callback function of a handler must return the new
state after responding to the user. If it does not return anything (returning ``None`` by
default), the state will not change. To end the conversation, the callback function must
return :attr:`END` or ``-1``. To handle the conversation timeout, use handler
:attr:`TIMEOUT` or ``-2``.
default), the state will not change. If an entry point callback function returns None,
the conversation ends immediately after the execution of this callback function.
To end the conversation, the callback function must return :attr:`END` or ``-1``. To
handle the conversation timeout, use handler :attr:`TIMEOUT` or ``-2``.
Attributes:
entry_points (List[:class:`telegram.ext.Handler`]): A list of ``Handler`` objects that can
@ -260,6 +261,8 @@ class ConversationHandler(Handler):
self.logger.exception("{}".format(exc))
res = old_state
finally:
if res is None and old_state is None:
res = self.END
self.update_state(res, key)
state = self.conversations.get(key)
else:

View file

@ -84,6 +84,9 @@ class TestConversationHandler(object):
def start_end(self, bot, update):
return self._set_state(update, self.END)
def start_none(self, bot, update):
return self._set_state(update, None)
def brew(self, bot, update):
return self._set_state(update, self.BREWING)
@ -343,6 +346,40 @@ class TestConversationHandler(object):
# Assert that the Promise has been resolved and the conversation ended.
assert len(handler.conversations) == 0
def test_none_on_first_message(self, dp, bot, user1):
handler = ConversationHandler(
entry_points=[CommandHandler('start', self.start_none)], states={}, fallbacks=[])
dp.add_handler(handler)
# User starts the state machine and a callback function returns None
message = Message(0, user1, None, self.group, text='/start', bot=bot)
dp.process_update(Update(update_id=0, message=message))
assert len(handler.conversations) == 0
def test_none_on_first_message_async(self, dp, bot, user1):
start_none_async = (lambda bot, update: dp.run_async(self.start_none, bot, update))
handler = ConversationHandler(
entry_points=[CommandHandler('start', start_none_async)], states={}, fallbacks=[])
dp.add_handler(handler)
# User starts the state machine with an async function that returns None
# Async results are resolved when the users state is queried next time.
message = Message(0, user1, None, self.group, text='/start',
entities=[MessageEntity(type=MessageEntity.BOT_COMMAND,
offset=0, length=len('/start'))],
bot=bot)
dp.update_queue.put(Update(update_id=0, message=message))
sleep(.1)
# Assert that the Promise has been accepted as the new state
assert len(handler.conversations) == 1
message.text = 'resolve promise pls'
dp.update_queue.put(Update(update_id=0, message=message))
sleep(.1)
# Assert that the Promise has been resolved and the conversation ended.
assert len(handler.conversations) == 0
def test_per_chat_message_without_chat(self, bot, user1):
handler = ConversationHandler(
entry_points=[CommandHandler('start', self.start_end)], states={},