Skip to content

Commit

Permalink
Entry returns None ends conversation (#1270)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
vasinkd authored and Eldinnie committed Feb 14, 2019
1 parent dda7ca1 commit 60f2044
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
9 changes: 6 additions & 3 deletions telegram/ext/conversationhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -260,6 +261,8 @@ def check_update(self, update):
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:
Expand Down
37 changes: 37 additions & 0 deletions tests/test_conversationhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ def end(self, bot, update):
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)

Expand Down Expand Up @@ -343,6 +346,40 @@ def test_end_on_first_message_async(self, dp, bot, user1):
# 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={},
Expand Down

0 comments on commit 60f2044

Please sign in to comment.