Exemplo n.º 1
0
    def test_webhook_no_ssl(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        self.updater.start_webhook(ip, port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(),
                          Chat(1, 'group', title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        self._send_webhook_msg(ip, port, update.to_json())
        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test 2')
    def test_drop_callback_data_exception(self, bot, app):
        non_ext_bot = Bot(bot.token)
        update = Update(0,
                        message=Message(0,
                                        None,
                                        Chat(1, "chat"),
                                        from_user=User(1, "user", False)))

        callback_context = CallbackContext.from_update(update, app)

        with pytest.raises(RuntimeError,
                           match="This telegram.ext.ExtBot instance does not"):
            callback_context.drop_callback_data(None)

        try:
            app.bot = non_ext_bot
            with pytest.raises(RuntimeError,
                               match="telegram.Bot does not allow for"):
                callback_context.drop_callback_data(None)
        finally:
            app.bot = bot
    def test_webhook(self, monkeypatch, updater):
        q = Queue()
        monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True)
        monkeypatch.setattr(updater.bot, 'delete_webhook', lambda *args, **kwargs: True)
        monkeypatch.setattr('telegram.ext.Dispatcher.process_update', lambda _, u: q.put(u))

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port
        updater.start_webhook(ip, port, url_path='TOKEN')
        sleep(0.2)
        try:
            # Now, we send an update to the server via urlopen
            update = Update(
                1,
                message=Message(
                    1, None, Chat(1, ''), from_user=User(1, '', False), text='Webhook'
                ),
            )
            self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN')
            sleep(0.2)
            assert q.get(False) == update

            # Returns 404 if path is incorrect
            with pytest.raises(HTTPError) as excinfo:
                self._send_webhook_msg(ip, port, None, 'webookhandler.py')
            assert excinfo.value.code == 404

            with pytest.raises(HTTPError) as excinfo:
                self._send_webhook_msg(
                    ip, port, None, 'webookhandler.py', get_method=lambda: 'HEAD'
                )
            assert excinfo.value.code == 404

            # Test multiple shutdown() calls
            updater.httpd.shutdown()
        finally:
            updater.httpd.shutdown()
            sleep(0.2)
            assert not updater.httpd.is_running
            updater.stop()
    def test_deepcopy_telegram_obj(self, bot):
        chat = Chat(2, Chat.PRIVATE)
        user = User(3, "first_name", False)
        date = datetime.datetime.now()
        photo = PhotoSize("file_id", "unique", 21, 21, bot=bot)
        msg = Message(1,
                      date,
                      chat,
                      from_user=user,
                      text="foobar",
                      bot=bot,
                      photo=[photo])

        new_msg = deepcopy(msg)

        # The same bot should be present when deepcopying.
        assert new_msg.get_bot() == bot and new_msg.get_bot() is bot

        assert new_msg.date == date and new_msg.date is not date
        assert new_msg.chat == chat and new_msg.chat is not chat
        assert new_msg.from_user == user and new_msg.from_user is not user
        assert new_msg.photo[0] == photo and new_msg.photo[0] is not photo
Exemplo n.º 5
0
    def test_addRemoveTelegramCommandHandler(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        handler = CommandHandler('test', self.telegramHandlerTest)
        self.updater.dispatcher.add_handler(handler)
        user = User(first_name="singelton", id=404)
        bot = self.updater.bot
        queue = self.updater.start_polling(0.01)

        # regular use
        message = Message(0, user, None, None, text="/test", bot=bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        self.assertEqual(self.received_message, '/test')

        # assigned use
        message = Message(0, user, None, None, text="/test@MockBot", bot=bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        self.assertEqual(self.received_message, '/test@MockBot')

        # directed at other bot
        self.reset()
        message = Message(0, user, None, None, text="/test@OtherBot", bot=bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        self.assertTrue(None is self.received_message)

        # Remove handler
        d.removeHandler(handler)
        handler = CommandHandler('test',
                                 self.telegramHandlerEditedTest,
                                 allow_edited=False)
        d.addHandler(handler)
        self.reset()

        self.updater.bot.send_messages = 1
        sleep(.1)
        self.assertTrue(None is self.received_message)
class CMDefaults:
    user = User(1, "First name", False)
    custom_title: str = "PTB"
    is_anonymous: bool = True
    until_date: datetime.datetime = to_timestamp(datetime.datetime.utcnow())
    can_be_edited: bool = False
    can_change_info: bool = True
    can_post_messages: bool = True
    can_edit_messages: bool = True
    can_delete_messages: bool = True
    can_invite_users: bool = True
    can_restrict_members: bool = True
    can_pin_messages: bool = True
    can_promote_members: bool = True
    can_send_messages: bool = True
    can_send_media_messages: bool = True
    can_send_polls: bool = True
    can_send_other_messages: bool = True
    can_add_web_page_previews: bool = True
    is_member: bool = True
    can_manage_chat: bool = True
    can_manage_video_chats: bool = True
    def test_endOnFirstMessage(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        user = User(first_name="Misses Test", id=123)

        handler = ConversationHandler(
            entry_points=[CommandHandler('start', self.start_end)],
            states={},
            fallbacks=[])
        d.add_handler(handler)
        queue = self.updater.start_polling(0.01)

        # User starts the state machine and immediately ends it.
        message = Message(0,
                          user,
                          None,
                          self.group,
                          text="/start",
                          bot=self.bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        self.assertEquals(len(handler.conversations), 0)
Exemplo n.º 8
0
class TestGameHighScore:
    position = 12
    user = User(2, 'test user', False)
    score = 42

    def test_de_json(self, bot):
        json_dict = {'position': self.position,
                     'user': self.user.to_dict(),
                     'score': self.score}
        highscore = GameHighScore.de_json(json_dict, bot)

        assert highscore.position == self.position
        assert highscore.user == self.user
        assert highscore.score == self.score

    def test_to_dict(self, game_highscore):
        game_highscore_dict = game_highscore.to_dict()

        assert isinstance(game_highscore_dict, dict)
        assert game_highscore_dict['position'] == game_highscore.position
        assert game_highscore_dict['user'] == game_highscore.user.to_dict()
        assert game_highscore_dict['score'] == game_highscore.score
Exemplo n.º 9
0
    def test_drop_callback_data(self, cdp, monkeypatch, chat_id):
        monkeypatch.setattr(cdp.bot, 'arbitrary_callback_data', True)

        update = Update(0,
                        message=Message(0,
                                        None,
                                        Chat(1, 'chat'),
                                        from_user=User(1, 'user', False)))

        callback_context = CallbackContext.from_update(update, cdp)
        cdp.bot.send_message(
            chat_id=chat_id,
            text='test',
            reply_markup=InlineKeyboardMarkup.from_button(
                InlineKeyboardButton('test', callback_data='callback_data')),
        )
        keyboard_uuid = cdp.bot.callback_data_cache.persistence_data[0][0][0]
        button_uuid = list(
            cdp.bot.callback_data_cache.persistence_data[0][0][2])[0]
        callback_data = keyboard_uuid + button_uuid
        callback_query = CallbackQuery(
            id='1',
            from_user=None,
            chat_instance=None,
            data=callback_data,
        )
        cdp.bot.callback_data_cache.process_callback_query(callback_query)

        try:
            assert len(cdp.bot.callback_data_cache.persistence_data[0]) == 1
            assert list(
                cdp.bot.callback_data_cache.persistence_data[1]) == ['1']

            callback_context.drop_callback_data(callback_query)
            assert cdp.bot.callback_data_cache.persistence_data == ([], {})
        finally:
            cdp.bot.callback_data_cache.clear_callback_data()
            cdp.bot.callback_data_cache.clear_callback_queries()
    def test_endOnFirstMessageAsync(self):
        self._setup_updater('', messages=0)
        d = self.updater.dispatcher
        user = User(first_name="Misses Test", id=123)

        start_end_async = (
            lambda bot, update: d.run_async(self.start_end, bot, update))

        handler = ConversationHandler(
            entry_points=[CommandHandler('start', start_end_async)],
            states={},
            fallbacks=[])
        d.add_handler(handler)
        queue = self.updater.start_polling(0.01)

        # User starts the state machine with an async function that immediately ends the
        # conversation. Async results are resolved when the users state is queried next time.
        message = Message(0,
                          user,
                          None,
                          self.group,
                          text="/start",
                          bot=self.bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        # Assert that the Promise has been accepted as the new state
        self.assertEquals(len(handler.conversations), 1)

        message = Message(0,
                          user,
                          None,
                          self.group,
                          text="resolve promise pls",
                          bot=self.bot)
        queue.put(Update(update_id=0, message=message))
        sleep(.1)
        # Assert that the Promise has been resolved and the conversation ended.
        self.assertEquals(len(handler.conversations), 0)
Exemplo n.º 11
0
    def test_webhook_default_quote(self, monkeypatch, updater):
        updater._default_quote = True
        q = Queue()
        monkeypatch.setattr(updater.bot, 'set_webhook', lambda *args, **kwargs: True)
        monkeypatch.setattr(updater.bot, 'delete_webhook', lambda *args, **kwargs: True)
        monkeypatch.setattr('telegram.ext.Dispatcher.process_update', lambda _, u: q.put(u))

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port
        updater.start_webhook(
            ip,
            port,
            url_path='TOKEN')
        sleep(.2)

        # Now, we send an update to the server via urlopen
        update = Update(1, message=Message(1, User(1, '', False), None, Chat(1, ''),
                                           text='Webhook'))
        self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN')
        sleep(.2)
        # assert q.get(False) == update
        assert q.get(False).message.default_quote is True
        updater.stop()
 def test_process_message_wrong_sender(self, pass_from_user, pass_via_bot,
                                       callback_data_cache):
     reply_markup = InlineKeyboardMarkup.from_button(
         InlineKeyboardButton('test', callback_data='callback_data'))
     user = User(1, 'first', False)
     message = Message(
         1,
         None,
         None,
         from_user=user if pass_from_user else None,
         via_bot=user if pass_via_bot else None,
         reply_markup=reply_markup,
     )
     callback_data_cache.process_message(message)
     if pass_from_user or pass_via_bot:
         # Here we can determine that the message is not from our bot, so no replacing
         assert message.reply_markup.inline_keyboard[0][
             0].callback_data == 'callback_data'
     else:
         # Here we have no chance to know, so InvalidCallbackData
         assert isinstance(
             message.reply_markup.inline_keyboard[0][0].callback_data,
             InvalidCallbackData)
Exemplo n.º 13
0
    def test_init(self, bot, populated_orchestra, empty_member):
        orchestra = populated_orchestra
        orchestra.register_member(empty_member)
        questioner = Questioner(
            user_id=empty_member.user_id,
            orchestra=orchestra,
            hint_attributes=[],
            question_attributes=[],
            number_of_questions=42,
            bot=bot,
            multiple_choice=True,
        )

        assert questioner.member == empty_member
        assert questioner.orchestra is orchestra
        assert questioner.bot is bot
        assert questioner.multiple_choice is True
        assert questioner.score.answers == 0
        assert not questioner.current_question
        assert not questioner.check_update(Update(123))
        assert not questioner.check_update(
            Update(123, poll_answer=PollAnswer(123, User(123, '', False), [1]))
        )
Exemplo n.º 14
0
    def test_webhook_no_ssl(self):
        print('Testing Webhook without SSL')
        bot = MockBot('', messages=0)
        self.updater.bot = bot
        d = self.updater.dispatcher
        d.addTelegramMessageHandler(self.telegramHandlerTest)

        # Select random port for travis
        port = randrange(1024, 49152)
        self.updater.start_webhook('127.0.0.1', port)
        sleep(0.5)

        # Now, we send an update to the server via urlopen
        message = Message(1, User(1, "Tester 2"), datetime.now(),
                          Chat(1, 'group', title="Test Group 2"))

        message.text = "Webhook Test 2"
        update = Update(1)
        update.message = message

        try:
            payload = bytes(update.to_json(), encoding='utf-8')
        except TypeError:
            payload = bytes(update.to_json())

        header = {
            'content-type': 'application/json',
            'content-length': str(len(payload))
        }

        r = Request('http://127.0.0.1:%d/' % port,
                    data=payload,
                    headers=header)

        urlopen(r)
        sleep(1)
        self.assertEqual(self.received_message, 'Webhook Test 2')
Exemplo n.º 15
0
    def test_deprecation_warnings_start_webhook(self, recwarn, updater,
                                                monkeypatch):
        monkeypatch.setattr(updater.bot, 'set_webhook',
                            lambda *args, **kwargs: True)
        monkeypatch.setattr(updater.bot, 'delete_webhook',
                            lambda *args, **kwargs: True)
        # prevent api calls from @info decorator when updater.bot.id is used in thread names
        monkeypatch.setattr(updater.bot, '_bot',
                            User(id=123, first_name='bot', is_bot=True))
        monkeypatch.setattr(updater.bot, '_commands', [])

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port
        updater.start_webhook(ip, port, clean=True, force_event_loop=False)
        updater.stop()

        for warning in recwarn.list:
            print(warning.message)

        assert len(recwarn) == 3
        assert str(recwarn[0].message).startswith('Old Handler API')
        assert str(recwarn[1].message).startswith('The argument `clean` of')
        assert str(recwarn[2].message).startswith(
            'The argument `force_event_loop` of')
Exemplo n.º 16
0
 def _fetch_updates(self, bot):
     chat = Chat(id=626525644,
                 type='private',
                 first_name='Wallace',
                 last_name='Reis')
     user = User(id=626525644,
                 first_name='Wallace',
                 last_name='Reis',
                 is_bot=False,
                 language_code='pt-br')
     return [
         Update(update_id=704571537,
                message=Message(
                    message_id=22,
                    date=None,
                    chat=chat,
                    text='/hello',
                    delete_chat_photo=False,
                    group_chat_created=False,
                    supergroup_chat_created=False,
                    channel_chat_created=False,
                    from_user=user,
                    bot=bot,
                )),
         Update(
             update_id=704571545,
             message=Message(
                 message_id=7,
                 date=None,
                 chat=chat,
                 new_chat_members=[user],
                 from_user=user,
                 bot=bot,
             ),
         ),
     ]
Exemplo n.º 17
0
class TestPollAnswer(object):
    poll_id = 'id'
    user = User(1, '', False)
    option_ids = [2]

    def test_de_json(self):
        json_dict = {
            'poll_id': self.poll_id,
            'user': self.user.to_dict(),
            'option_ids': self.option_ids
        }
        poll_answer = PollAnswer.de_json(json_dict, None)

        assert poll_answer.poll_id == self.poll_id
        assert poll_answer.user == self.user
        assert poll_answer.option_ids == self.option_ids

    def test_to_dict(self, poll_answer):
        poll_answer_dict = poll_answer.to_dict()

        assert isinstance(poll_answer_dict, dict)
        assert poll_answer_dict['poll_id'] == poll_answer.poll_id
        assert poll_answer_dict['user'] == poll_answer.user.to_dict()
        assert poll_answer_dict['option_ids'] == poll_answer.option_ids
Exemplo n.º 18
0
    def test_webhook_no_ssl(self, monkeypatch, updater):
        q = Queue()
        monkeypatch.setattr('telegram.Bot.set_webhook',
                            lambda *args, **kwargs: True)
        monkeypatch.setattr('telegram.Bot.delete_webhook',
                            lambda *args, **kwargs: True)
        monkeypatch.setattr('telegram.ext.Dispatcher.process_update',
                            lambda _, u: q.put(u))

        ip = '127.0.0.1'
        port = randrange(1024, 49152)  # Select random port for travis
        updater.start_webhook(ip, port, webhook_url=None)
        sleep(.2)

        # Now, we send an update to the server via urlopen
        update = Update(1,
                        message=Message(1,
                                        User(1, '', False),
                                        None,
                                        Chat(1, ''),
                                        text='Webhook 2'))
        self._send_webhook_msg(ip, port, update.to_json())
        sleep(.2)
        assert q.get(False) == update
Exemplo n.º 19
0
def get_false_update_fixture_decorator_params():
    message = Message(1,
                      DATE,
                      Chat(1, ''),
                      from_user=User(1, '', False),
                      text='test')
    params = [
        {
            'callback_query':
            CallbackQuery(1, User(1, '', False), 'chat', message=message)
        },
        {
            'channel_post': message
        },
        {
            'edited_channel_post': message
        },
        {
            'inline_query': InlineQuery(1, User(1, '', False), '', '')
        },
        {
            'chosen_inline_result':
            ChosenInlineResult('id', User(1, '', False), '')
        },
        {
            'shipping_query': ShippingQuery('id', User(1, '', False), '', None)
        },
        {
            'pre_checkout_query':
            PreCheckoutQuery('id', User(1, '', False), '', 0, '')
        },
        {
            'callback_query': CallbackQuery(1, User(1, '', False), 'chat')
        },
    ]
    ids = tuple(key for kwargs in params for key in kwargs)
    return {'params': params, 'ids': ids}
def get_false_update_fixture_decorator_params():
    message = Message(1,
                      DATE,
                      Chat(1, ""),
                      from_user=User(1, "", False),
                      text="test")
    params = [
        {
            "callback_query":
            CallbackQuery(1, User(1, "", False), "chat", message=message)
        },
        {
            "channel_post": message
        },
        {
            "edited_channel_post": message
        },
        {
            "inline_query": InlineQuery(1, User(1, "", False), "", "")
        },
        {
            "chosen_inline_result":
            ChosenInlineResult("id", User(1, "", False), "")
        },
        {
            "shipping_query": ShippingQuery("id", User(1, "", False), "", None)
        },
        {
            "pre_checkout_query":
            PreCheckoutQuery("id", User(1, "", False), "", 0, "")
        },
        {
            "callback_query": CallbackQuery(1, User(1, "", False), "chat")
        },
    ]
    ids = tuple(key for kwargs in params for key in kwargs)
    return {"params": params, "ids": ids}
    def test_equality(self):
        a = ChatInviteLink("link", User(1, '', False), True, True)
        b = ChatInviteLink("link", User(1, '', False), True, True)
        d = ChatInviteLink("link", User(2, '', False), False, True)
        d2 = ChatInviteLink("notalink", User(1, '', False), False, True)
        d3 = ChatInviteLink("notalink", User(1, '', False), True, True)
        e = User(1, '', False)

        assert a == b
        assert hash(a) == hash(b)
        assert a is not b

        assert a != d
        assert hash(a) != hash(d)

        assert a != d2
        assert hash(a) != hash(d2)

        assert d2 != d3
        assert hash(d2) != hash(d3)

        assert a != e
        assert hash(a) != hash(e)
Exemplo n.º 22
0
    def test_persisting_no_user_no_chat(self, cdp):
        class OwnPersistence(BasePersistence):
            def __init__(self):
                super(OwnPersistence, self).__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True
                self.test_flag_bot_data = False
                self.test_flag_chat_data = False
                self.test_flag_user_data = False

            def update_bot_data(self, data):
                self.test_flag_bot_data = True

            def update_chat_data(self, chat_id, data):
                self.test_flag_chat_data = True

            def update_user_data(self, user_id, data):
                self.test_flag_user_data = True

            def update_conversation(self, name, key, new_state):
                pass

            def get_conversations(self, name):
                pass

            def get_user_data(self):
                pass

            def get_bot_data(self):
                pass

            def get_chat_data(self):
                pass

        def callback(update, context):
            pass

        handler = MessageHandler(Filters.all, callback)
        cdp.add_handler(handler)
        cdp.persistence = OwnPersistence()

        update = Update(1,
                        message=Message(1,
                                        None,
                                        None,
                                        from_user=User(1, '', False),
                                        text='Text'))
        cdp.process_update(update)
        assert cdp.persistence.test_flag_bot_data
        assert cdp.persistence.test_flag_user_data
        assert not cdp.persistence.test_flag_chat_data

        cdp.persistence.test_flag_bot_data = False
        cdp.persistence.test_flag_user_data = False
        cdp.persistence.test_flag_chat_data = False
        update = Update(1,
                        message=Message(1,
                                        None,
                                        Chat(1, ''),
                                        from_user=None,
                                        text='Text'))
        cdp.process_update(update)
        assert cdp.persistence.test_flag_bot_data
        assert not cdp.persistence.test_flag_user_data
        assert cdp.persistence.test_flag_chat_data
Exemplo n.º 23
0
    def test_error_while_persisting(self, cdp, monkeypatch):
        class OwnPersistence(BasePersistence):
            def __init__(self):
                super(OwnPersistence, self).__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True

            def update(self, data):
                raise Exception('PersistenceError')

            def update_bot_data(self, data):
                self.update(data)

            def update_chat_data(self, chat_id, data):
                self.update(data)

            def update_user_data(self, user_id, data):
                self.update(data)

            def get_chat_data(self):
                pass

            def get_bot_data(self):
                pass

            def get_user_data(self):
                pass

            def get_conversations(self, name):
                pass

            def update_conversation(self, name, key, new_state):
                pass

        def callback(update, context):
            pass

        test_flag = False

        def error(update, context):
            nonlocal test_flag
            test_flag = str(context.error) == 'PersistenceError'
            raise Exception('ErrorHandlingError')

        def logger(message):
            assert 'uncaught error was raised while handling' in message

        update = Update(1,
                        message=Message(1,
                                        None,
                                        Chat(1, ''),
                                        from_user=User(1, '', False),
                                        text='Text'))
        handler = MessageHandler(Filters.all, callback)
        cdp.add_handler(handler)
        cdp.add_error_handler(error)
        monkeypatch.setattr(cdp.logger, 'exception', logger)

        cdp.persistence = OwnPersistence()
        cdp.process_update(update)
        assert test_flag
Exemplo n.º 24
0
    def test_error_while_saving_chat_data(self, bot):
        increment = []

        class OwnPersistence(BasePersistence):
            def __init__(self):
                super().__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True

            def get_bot_data(self):
                return dict()

            def update_bot_data(self, data):
                raise Exception

            def get_chat_data(self):
                return defaultdict(dict)

            def update_chat_data(self, chat_id, data):
                raise Exception

            def get_user_data(self):
                return defaultdict(dict)

            def update_user_data(self, user_id, data):
                raise Exception

            def get_conversations(self, name):
                pass

            def update_conversation(self, name, key, new_state):
                pass

        def start1(b, u):
            pass

        def error(b, u, e):
            increment.append("error")

        # If updating a user_data or chat_data from a persistence object throws an error,
        # the error handler should catch it

        update = Update(
            1,
            message=Message(
                1,
                None,
                Chat(1, "lala"),
                from_user=User(1, "Test", False),
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )
        my_persistence = OwnPersistence()
        dp = Dispatcher(bot,
                        None,
                        persistence=my_persistence,
                        use_context=False)
        dp.add_handler(CommandHandler('start', start1))
        dp.add_error_handler(error)
        dp.process_update(update)
        assert increment == ["error", "error", "error"]
Exemplo n.º 25
0
class TestDispatcher:
    message_update = Update(1,
                            message=Message(1,
                                            None,
                                            Chat(1, ''),
                                            from_user=User(1, '', False),
                                            text='Text'))
    received = None
    count = 0

    @pytest.fixture(autouse=True, name='reset')
    def reset_fixture(self):
        self.reset()

    def reset(self):
        self.received = None
        self.count = 0

    def error_handler(self, bot, update, error):
        self.received = error.message

    def error_handler_context(self, update, context):
        self.received = context.error.message

    def error_handler_raise_error(self, bot, update, error):
        raise Exception('Failing bigly')

    def callback_increase_count(self, bot, update):
        self.count += 1

    def callback_set_count(self, count):
        def callback(bot, update):
            self.count = count

        return callback

    def callback_raise_error(self, bot, update):
        if isinstance(bot, Bot):
            raise TelegramError(update.message.text)
        raise TelegramError(bot.message.text)

    def callback_if_not_update_queue(self, bot, update, update_queue=None):
        if update_queue is not None:
            self.received = update.message

    def callback_context(self, update, context):
        if (isinstance(context, CallbackContext)
                and isinstance(context.bot, Bot)
                and isinstance(context.update_queue, Queue)
                and isinstance(context.job_queue, JobQueue)
                and isinstance(context.error, TelegramError)):
            self.received = context.error.message

    def test_one_context_per_update(self, cdp):
        def one(update, context):
            if update.message.text == 'test':
                context.my_flag = True

        def two(update, context):
            if update.message.text == 'test':
                if not hasattr(context, 'my_flag'):
                    pytest.fail()
            else:
                if hasattr(context, 'my_flag'):
                    pytest.fail()

        cdp.add_handler(MessageHandler(Filters.regex('test'), one), group=1)
        cdp.add_handler(MessageHandler(None, two), group=2)
        u = Update(1, Message(1, None, None, None, text='test'))
        cdp.process_update(u)
        u.message.text = 'something'
        cdp.process_update(u)

    def test_error_handler(self, dp):
        dp.add_error_handler(self.error_handler)
        error = TelegramError('Unauthorized.')
        dp.update_queue.put(error)
        sleep(0.1)
        assert self.received == 'Unauthorized.'

        # Remove handler
        dp.remove_error_handler(self.error_handler)
        self.reset()

        dp.update_queue.put(error)
        sleep(0.1)
        assert self.received is None

    def test_double_add_error_handler(self, dp, caplog):
        dp.add_error_handler(self.error_handler)
        with caplog.at_level(logging.DEBUG):
            dp.add_error_handler(self.error_handler)
            assert len(caplog.records) == 1
            assert caplog.records[-1].getMessage().startswith(
                'The callback is already registered')

    def test_construction_with_bad_persistence(self, caplog, bot):
        class my_per:
            def __init__(self):
                self.store_user_data = False
                self.store_chat_data = False
                self.store_bot_data = False

        with pytest.raises(
                TypeError,
                match=
                'persistence must be based on telegram.ext.BasePersistence'):
            Dispatcher(bot, None, persistence=my_per())

    def test_error_handler_that_raises_errors(self, dp):
        """
        Make sure that errors raised in error handlers don't break the main loop of the dispatcher
        """
        handler_raise_error = MessageHandler(Filters.all,
                                             self.callback_raise_error)
        handler_increase_count = MessageHandler(Filters.all,
                                                self.callback_increase_count)
        error = TelegramError('Unauthorized.')

        dp.add_error_handler(self.error_handler_raise_error)

        # From errors caused by handlers
        dp.add_handler(handler_raise_error)
        dp.update_queue.put(self.message_update)
        sleep(0.1)

        # From errors in the update_queue
        dp.remove_handler(handler_raise_error)
        dp.add_handler(handler_increase_count)
        dp.update_queue.put(error)
        dp.update_queue.put(self.message_update)
        sleep(0.1)

        assert self.count == 1

    @pytest.mark.parametrize(['run_async', 'expected_output'], [(True, 5),
                                                                (False, 0)])
    def test_default_run_async_error_handler(self, dp, monkeypatch, run_async,
                                             expected_output):
        def mock_async_err_handler(*args, **kwargs):
            self.count = 5

        # set defaults value to dp.bot
        dp.bot.defaults = Defaults(run_async=run_async)
        try:
            dp.add_handler(
                MessageHandler(Filters.all, self.callback_raise_error))
            dp.add_error_handler(self.error_handler)

            monkeypatch.setattr(dp, 'run_async', mock_async_err_handler)
            dp.process_update(self.message_update)

            assert self.count == expected_output

        finally:
            # reset dp.bot.defaults values
            dp.bot.defaults = None

    @pytest.mark.parametrize(['run_async', 'expected_output'],
                             [(True, 'running async'), (False, None)])
    def test_default_run_async(self, monkeypatch, dp, run_async,
                               expected_output):
        def mock_run_async(*args, **kwargs):
            self.received = 'running async'

        # set defaults value to dp.bot
        dp.bot.defaults = Defaults(run_async=run_async)
        try:
            dp.add_handler(MessageHandler(Filters.all, lambda u, c: None))
            monkeypatch.setattr(dp, 'run_async', mock_run_async)
            dp.process_update(self.message_update)
            assert self.received == expected_output

        finally:
            # reset defaults value
            dp.bot.defaults = None

    def test_run_async_multiple(self, bot, dp, dp2):
        def get_dispatcher_name(q):
            q.put(current_thread().name)

        q1 = Queue()
        q2 = Queue()

        dp.run_async(get_dispatcher_name, q1)
        dp2.run_async(get_dispatcher_name, q2)

        sleep(0.1)

        name1 = q1.get()
        name2 = q2.get()

        assert name1 != name2

    def test_multiple_run_async_decorator(self, dp, dp2):
        # Make sure we got two dispatchers and that they are not the same
        assert isinstance(dp, Dispatcher)
        assert isinstance(dp2, Dispatcher)
        assert dp is not dp2

        @run_async
        def must_raise_runtime_error():
            pass

        with pytest.raises(RuntimeError):
            must_raise_runtime_error()

    def test_run_async_with_args(self, dp):
        dp.add_handler(
            MessageHandler(Filters.all,
                           run_async(self.callback_if_not_update_queue),
                           pass_update_queue=True))

        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.received == self.message_update.message

    def test_multiple_run_async_deprecation(self, dp):
        assert isinstance(dp, Dispatcher)

        @run_async
        def callback(update, context):
            pass

        dp.add_handler(MessageHandler(Filters.all, callback))

        with pytest.warns(TelegramDeprecationWarning,
                          match='@run_async decorator'):
            dp.process_update(self.message_update)

    def test_async_raises_dispatcher_handler_stop(self, dp, caplog):
        @run_async
        def callback(update, context):
            raise DispatcherHandlerStop()

        dp.add_handler(MessageHandler(Filters.all, callback))

        with caplog.at_level(logging.WARNING):
            dp.update_queue.put(self.message_update)
            sleep(0.1)
            assert len(caplog.records) == 1
            assert (caplog.records[-1].getMessage().startswith(
                'DispatcherHandlerStop is not supported '
                'with async functions'))

    def test_async_raises_exception(self, dp, caplog):
        @run_async
        def callback(update, context):
            raise RuntimeError('async raising exception')

        dp.add_handler(MessageHandler(Filters.all, callback))

        with caplog.at_level(logging.WARNING):
            dp.update_queue.put(self.message_update)
            sleep(0.1)
            assert len(caplog.records) == 1
            assert (caplog.records[-1].getMessage().startswith(
                'A promise with deactivated error handling'))

    def test_add_async_handler(self, dp):
        dp.add_handler(
            MessageHandler(
                Filters.all,
                self.callback_if_not_update_queue,
                pass_update_queue=True,
                run_async=True,
            ))

        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.received == self.message_update.message

    def test_run_async_no_error_handler(self, dp, caplog):
        def func():
            raise RuntimeError('Async Error')

        with caplog.at_level(logging.ERROR):
            dp.run_async(func)
            sleep(0.1)
            assert len(caplog.records) == 1
            assert caplog.records[-1].getMessage().startswith(
                'No error handlers are registered')

    def test_async_handler_error_handler(self, dp):
        dp.add_handler(
            MessageHandler(Filters.all,
                           self.callback_raise_error,
                           run_async=True))
        dp.add_error_handler(self.error_handler)

        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.received == self.message_update.message.text

    def test_async_handler_async_error_handler_context(self, cdp):
        cdp.add_handler(
            MessageHandler(Filters.all,
                           self.callback_raise_error,
                           run_async=True))
        cdp.add_error_handler(self.error_handler_context, run_async=True)

        cdp.update_queue.put(self.message_update)
        sleep(2)
        assert self.received == self.message_update.message.text

    def test_async_handler_error_handler_that_raises_error(self, dp, caplog):
        handler = MessageHandler(Filters.all,
                                 self.callback_raise_error,
                                 run_async=True)
        dp.add_handler(handler)
        dp.add_error_handler(self.error_handler_raise_error, run_async=False)

        with caplog.at_level(logging.ERROR):
            dp.update_queue.put(self.message_update)
            sleep(0.1)
            assert len(caplog.records) == 1
            assert caplog.records[-1].getMessage().startswith(
                'An uncaught error was raised')

        # Make sure that the main loop still runs
        dp.remove_handler(handler)
        dp.add_handler(
            MessageHandler(Filters.all,
                           self.callback_increase_count,
                           run_async=True))
        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.count == 1

    def test_async_handler_async_error_handler_that_raises_error(
            self, dp, caplog):
        handler = MessageHandler(Filters.all,
                                 self.callback_raise_error,
                                 run_async=True)
        dp.add_handler(handler)
        dp.add_error_handler(self.error_handler_raise_error, run_async=True)

        with caplog.at_level(logging.ERROR):
            dp.update_queue.put(self.message_update)
            sleep(0.1)
            assert len(caplog.records) == 1
            assert caplog.records[-1].getMessage().startswith(
                'An uncaught error was raised')

        # Make sure that the main loop still runs
        dp.remove_handler(handler)
        dp.add_handler(
            MessageHandler(Filters.all,
                           self.callback_increase_count,
                           run_async=True))
        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.count == 1

    def test_error_in_handler(self, dp):
        dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error))
        dp.add_error_handler(self.error_handler)

        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.received == self.message_update.message.text

    def test_add_remove_handler(self, dp):
        handler = MessageHandler(Filters.all, self.callback_increase_count)
        dp.add_handler(handler)
        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.count == 1
        dp.remove_handler(handler)
        dp.update_queue.put(self.message_update)
        assert self.count == 1

    def test_add_remove_handler_non_default_group(self, dp):
        handler = MessageHandler(Filters.all, self.callback_increase_count)
        dp.add_handler(handler, group=2)
        with pytest.raises(KeyError):
            dp.remove_handler(handler)
        dp.remove_handler(handler, group=2)

    def test_error_start_twice(self, dp):
        assert dp.running
        dp.start()

    def test_handler_order_in_group(self, dp):
        dp.add_handler(
            MessageHandler(Filters.photo, self.callback_set_count(1)))
        dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2)))
        dp.add_handler(MessageHandler(Filters.text,
                                      self.callback_set_count(3)))
        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.count == 2

    def test_groups(self, dp):
        dp.add_handler(
            MessageHandler(Filters.all, self.callback_increase_count))
        dp.add_handler(MessageHandler(Filters.all,
                                      self.callback_increase_count),
                       group=2)
        dp.add_handler(MessageHandler(Filters.all,
                                      self.callback_increase_count),
                       group=-1)

        dp.update_queue.put(self.message_update)
        sleep(0.1)
        assert self.count == 3

    def test_add_handler_errors(self, dp):
        handler = 'not a handler'
        with pytest.raises(TypeError, match='handler is not an instance of'):
            dp.add_handler(handler)

        handler = MessageHandler(Filters.photo, self.callback_set_count(1))
        with pytest.raises(TypeError, match='group is not int'):
            dp.add_handler(handler, 'one')

    def test_flow_stop(self, dp, bot):
        passed = []

        def start1(b, u):
            passed.append('start1')
            raise DispatcherHandlerStop

        def start2(b, u):
            passed.append('start2')

        def start3(b, u):
            passed.append('start3')

        def error(b, u, e):
            passed.append('error')
            passed.append(e)

        update = Update(
            1,
            message=Message(
                1,
                None,
                None,
                None,
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )

        # If Stop raised handlers in other groups should not be called.
        passed = []
        dp.add_handler(CommandHandler('start', start1), 1)
        dp.add_handler(CommandHandler('start', start3), 1)
        dp.add_handler(CommandHandler('start', start2), 2)
        dp.process_update(update)
        assert passed == ['start1']

    def test_exception_in_handler(self, dp, bot):
        passed = []
        err = Exception('General exception')

        def start1(b, u):
            passed.append('start1')
            raise err

        def start2(b, u):
            passed.append('start2')

        def start3(b, u):
            passed.append('start3')

        def error(b, u, e):
            passed.append('error')
            passed.append(e)

        update = Update(
            1,
            message=Message(
                1,
                None,
                None,
                None,
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )

        # If an unhandled exception was caught, no further handlers from the same group should be
        # called. Also, the error handler should be called and receive the exception
        passed = []
        dp.add_handler(CommandHandler('start', start1), 1)
        dp.add_handler(CommandHandler('start', start2), 1)
        dp.add_handler(CommandHandler('start', start3), 2)
        dp.add_error_handler(error)
        dp.process_update(update)
        assert passed == ['start1', 'error', err, 'start3']

    def test_telegram_error_in_handler(self, dp, bot):
        passed = []
        err = TelegramError('Telegram error')

        def start1(b, u):
            passed.append('start1')
            raise err

        def start2(b, u):
            passed.append('start2')

        def start3(b, u):
            passed.append('start3')

        def error(b, u, e):
            passed.append('error')
            passed.append(e)

        update = Update(
            1,
            message=Message(
                1,
                None,
                None,
                None,
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )

        # If a TelegramException was caught, an error handler should be called and no further
        # handlers from the same group should be called.
        dp.add_handler(CommandHandler('start', start1), 1)
        dp.add_handler(CommandHandler('start', start2), 1)
        dp.add_handler(CommandHandler('start', start3), 2)
        dp.add_error_handler(error)
        dp.process_update(update)
        assert passed == ['start1', 'error', err, 'start3']
        assert passed[2] is err

    def test_error_while_saving_chat_data(self, bot):
        increment = []

        class OwnPersistence(BasePersistence):
            def __init__(self):
                super().__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True

            def get_bot_data(self):
                return dict()

            def update_bot_data(self, data):
                raise Exception

            def get_chat_data(self):
                return defaultdict(dict)

            def update_chat_data(self, chat_id, data):
                raise Exception

            def get_user_data(self):
                return defaultdict(dict)

            def update_user_data(self, user_id, data):
                raise Exception

            def get_conversations(self, name):
                pass

            def update_conversation(self, name, key, new_state):
                pass

        def start1(b, u):
            pass

        def error(b, u, e):
            increment.append("error")

        # If updating a user_data or chat_data from a persistence object throws an error,
        # the error handler should catch it

        update = Update(
            1,
            message=Message(
                1,
                None,
                Chat(1, "lala"),
                from_user=User(1, "Test", False),
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )
        my_persistence = OwnPersistence()
        dp = Dispatcher(bot,
                        None,
                        persistence=my_persistence,
                        use_context=False)
        dp.add_handler(CommandHandler('start', start1))
        dp.add_error_handler(error)
        dp.process_update(update)
        assert increment == ["error", "error", "error"]

    def test_flow_stop_in_error_handler(self, dp, bot):
        passed = []
        err = TelegramError('Telegram error')

        def start1(b, u):
            passed.append('start1')
            raise err

        def start2(b, u):
            passed.append('start2')

        def start3(b, u):
            passed.append('start3')

        def error(b, u, e):
            passed.append('error')
            passed.append(e)
            raise DispatcherHandlerStop

        update = Update(
            1,
            message=Message(
                1,
                None,
                None,
                None,
                text='/start',
                entities=[
                    MessageEntity(type=MessageEntity.BOT_COMMAND,
                                  offset=0,
                                  length=len('/start'))
                ],
                bot=bot,
            ),
        )

        # If a TelegramException was caught, an error handler should be called and no further
        # handlers from the same group should be called.
        dp.add_handler(CommandHandler('start', start1), 1)
        dp.add_handler(CommandHandler('start', start2), 1)
        dp.add_handler(CommandHandler('start', start3), 2)
        dp.add_error_handler(error)
        dp.process_update(update)
        assert passed == ['start1', 'error', err]
        assert passed[2] is err

    def test_error_handler_context(self, cdp):
        cdp.add_error_handler(self.callback_context)

        error = TelegramError('Unauthorized.')
        cdp.update_queue.put(error)
        sleep(0.1)
        assert self.received == 'Unauthorized.'

    def test_sensible_worker_thread_names(self, dp2):
        thread_names = [
            thread.name
            for thread in getattr(dp2, '_Dispatcher__async_threads')
        ]
        print(thread_names)
        for thread_name in thread_names:
            assert thread_name.startswith("Bot:{}:worker:".format(dp2.bot.id))

    def test_non_context_deprecation(self, dp):
        with pytest.warns(TelegramDeprecationWarning):
            Dispatcher(dp.bot,
                       dp.update_queue,
                       job_queue=dp.job_queue,
                       workers=0,
                       use_context=False)

    def test_error_while_persisting(self, cdp, monkeypatch):
        class OwnPersistence(BasePersistence):
            def __init__(self):
                super(OwnPersistence, self).__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True

            def update(self, data):
                raise Exception('PersistenceError')

            def update_bot_data(self, data):
                self.update(data)

            def update_chat_data(self, chat_id, data):
                self.update(data)

            def update_user_data(self, user_id, data):
                self.update(data)

            def get_chat_data(self):
                pass

            def get_bot_data(self):
                pass

            def get_user_data(self):
                pass

            def get_conversations(self, name):
                pass

            def update_conversation(self, name, key, new_state):
                pass

        def callback(update, context):
            pass

        test_flag = False

        def error(update, context):
            nonlocal test_flag
            test_flag = str(context.error) == 'PersistenceError'
            raise Exception('ErrorHandlingError')

        def logger(message):
            assert 'uncaught error was raised while handling' in message

        update = Update(1,
                        message=Message(1,
                                        None,
                                        Chat(1, ''),
                                        from_user=User(1, '', False),
                                        text='Text'))
        handler = MessageHandler(Filters.all, callback)
        cdp.add_handler(handler)
        cdp.add_error_handler(error)
        monkeypatch.setattr(cdp.logger, 'exception', logger)

        cdp.persistence = OwnPersistence()
        cdp.process_update(update)
        assert test_flag

    def test_persisting_no_user_no_chat(self, cdp):
        class OwnPersistence(BasePersistence):
            def __init__(self):
                super(OwnPersistence, self).__init__()
                self.store_user_data = True
                self.store_chat_data = True
                self.store_bot_data = True
                self.test_flag_bot_data = False
                self.test_flag_chat_data = False
                self.test_flag_user_data = False

            def update_bot_data(self, data):
                self.test_flag_bot_data = True

            def update_chat_data(self, chat_id, data):
                self.test_flag_chat_data = True

            def update_user_data(self, user_id, data):
                self.test_flag_user_data = True

            def update_conversation(self, name, key, new_state):
                pass

            def get_conversations(self, name):
                pass

            def get_user_data(self):
                pass

            def get_bot_data(self):
                pass

            def get_chat_data(self):
                pass

        def callback(update, context):
            pass

        handler = MessageHandler(Filters.all, callback)
        cdp.add_handler(handler)
        cdp.persistence = OwnPersistence()

        update = Update(1,
                        message=Message(1,
                                        None,
                                        None,
                                        from_user=User(1, '', False),
                                        text='Text'))
        cdp.process_update(update)
        assert cdp.persistence.test_flag_bot_data
        assert cdp.persistence.test_flag_user_data
        assert not cdp.persistence.test_flag_chat_data

        cdp.persistence.test_flag_bot_data = False
        cdp.persistence.test_flag_user_data = False
        cdp.persistence.test_flag_chat_data = False
        update = Update(1,
                        message=Message(1,
                                        None,
                                        Chat(1, ''),
                                        from_user=None,
                                        text='Text'))
        cdp.process_update(update)
        assert cdp.persistence.test_flag_bot_data
        assert not cdp.persistence.test_flag_user_data
        assert cdp.persistence.test_flag_chat_data
Exemplo n.º 26
0
def user2():
    return User(first_name='Mister Test', id=124)
Exemplo n.º 27
0
def user1():
    return User(first_name='Misses Test', id=123)
Exemplo n.º 28
0
class TestMessage:
    id_ = 1
    from_user = User(2, 'testuser', False)
    date = datetime.utcnow()
    chat = Chat(3, 'private')
    test_entities = [
        {
            'length': 4,
            'offset': 10,
            'type': 'bold'
        },
        {
            'length': 3,
            'offset': 16,
            'type': 'italic'
        },
        {
            'length': 3,
            'offset': 20,
            'type': 'italic'
        },
        {
            'length': 4,
            'offset': 25,
            'type': 'code'
        },
        {
            'length': 5,
            'offset': 31,
            'type': 'text_link',
            'url': 'http://github.com/ab_'
        },
        {
            'length': 12,
            'offset': 38,
            'type': 'text_mention',
            'user': User(123456789, 'mentioned user', False),
        },
        {
            'length': 3,
            'offset': 55,
            'type': 'pre',
            'language': 'python'
        },
        {
            'length': 21,
            'offset': 60,
            'type': 'url'
        },
    ]
    test_text = 'Test for <bold, ita_lic, code, links, text-mention and pre. http://google.com/ab_'
    test_entities_v2 = [
        {
            'length': 4,
            'offset': 0,
            'type': 'underline'
        },
        {
            'length': 4,
            'offset': 10,
            'type': 'bold'
        },
        {
            'length': 7,
            'offset': 16,
            'type': 'italic'
        },
        {
            'length': 6,
            'offset': 25,
            'type': 'code'
        },
        {
            'length': 5,
            'offset': 33,
            'type': 'text_link',
            'url': r'http://github.com/abc\)def'
        },
        {
            'length': 12,
            'offset': 40,
            'type': 'text_mention',
            'user': User(123456789, 'mentioned user', False),
        },
        {
            'length': 5,
            'offset': 57,
            'type': 'pre'
        },
        {
            'length': 17,
            'offset': 64,
            'type': 'url'
        },
        {
            'length': 36,
            'offset': 86,
            'type': 'italic'
        },
        {
            'length': 24,
            'offset': 91,
            'type': 'bold'
        },
        {
            'length': 4,
            'offset': 101,
            'type': 'strikethrough'
        },
        {
            'length': 10,
            'offset': 124,
            'type': 'pre',
            'language': 'python'
        },
    ]
    test_text_v2 = (
        r'Test for <bold, ita_lic, \`code, links, text-mention and `\pre. '
        'http://google.com and bold nested in strk nested in italic. Python pre.'
    )
    test_message = Message(
        message_id=1,
        from_user=None,
        date=None,
        chat=None,
        text=test_text,
        entities=[MessageEntity(**e) for e in test_entities],
        caption=test_text,
        caption_entities=[MessageEntity(**e) for e in test_entities],
    )
    test_message_v2 = Message(
        message_id=1,
        from_user=None,
        date=None,
        chat=None,
        text=test_text_v2,
        entities=[MessageEntity(**e) for e in test_entities_v2],
        caption=test_text_v2,
        caption_entities=[MessageEntity(**e) for e in test_entities_v2],
    )

    def test_all_possibilities_de_json_and_to_dict(self, bot, message_params):
        new = Message.de_json(message_params.to_dict(), bot)

        assert new.to_dict() == message_params.to_dict()

    def test_dict_approach(self, message):
        assert message['text'] == message.text
        assert message['chat_id'] == message.chat_id
        assert message['no_key'] is None

    def test_parse_entity(self):
        text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467'
                b'\\u200d\\U0001f467\\U0001f431http://google.com'
                ).decode('unicode-escape')
        entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          text=text,
                          entities=[entity])
        assert message.parse_entity(entity) == 'http://google.com'

    def test_parse_caption_entity(self):
        caption = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467'
                   b'\\u200d\\U0001f467\\U0001f431http://google.com'
                   ).decode('unicode-escape')
        entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          caption=caption,
                          caption_entities=[entity])
        assert message.parse_caption_entity(entity) == 'http://google.com'

    def test_parse_entities(self):
        text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467'
                b'\\u200d\\U0001f467\\U0001f431http://google.com'
                ).decode('unicode-escape')
        entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17)
        entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          text=text,
                          entities=[entity_2, entity])
        assert message.parse_entities(MessageEntity.URL) == {
            entity: 'http://google.com'
        }
        assert message.parse_entities() == {
            entity: 'http://google.com',
            entity_2: 'h'
        }

    def test_parse_caption_entities(self):
        text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467'
                b'\\u200d\\U0001f467\\U0001f431http://google.com'
                ).decode('unicode-escape')
        entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17)
        entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1)
        message = Message(
            1,
            self.from_user,
            self.date,
            self.chat,
            caption=text,
            caption_entities=[entity_2, entity],
        )
        assert message.parse_caption_entities(MessageEntity.URL) == {
            entity: 'http://google.com'
        }
        assert message.parse_caption_entities() == {
            entity: 'http://google.com',
            entity_2: 'h'
        }

    def test_text_html_simple(self):
        test_html_string = (
            '<u>Test</u> for &lt;<b>bold</b>, <i>ita_lic</i>, '
            r'<code>\`code</code>, '
            r'<a href="http://github.com/abc\)def">links</a>, '
            '<a href="tg://user?id=123456789">text-mention</a> and '
            r'<pre>`\pre</pre>. http://google.com '
            'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>. '
            '<pre><code class="python">Python pre</code></pre>.')
        text_html = self.test_message_v2.text_html
        assert text_html == test_html_string

    def test_text_html_empty(self, message):
        message.text = None
        message.caption = "test"
        assert message.text_html is None

    def test_text_html_urled(self):
        test_html_string = (
            '<u>Test</u> for &lt;<b>bold</b>, <i>ita_lic</i>, '
            r'<code>\`code</code>, '
            r'<a href="http://github.com/abc\)def">links</a>, '
            '<a href="tg://user?id=123456789">text-mention</a> and '
            r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
            'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>. '
            '<pre><code class="python">Python pre</code></pre>.')
        text_html = self.test_message_v2.text_html_urled
        assert text_html == test_html_string

    def test_text_markdown_simple(self):
        test_md_string = (
            r'Test for <*bold*, _ita_\__lic_, `code`, '
            '[links](http://github.com/ab_), '
            '[text-mention](tg://user?id=123456789) and ```python\npre```. '
            r'http://google.com/ab\_')
        text_markdown = self.test_message.text_markdown
        assert text_markdown == test_md_string

    def test_text_markdown_v2_simple(self):
        test_md_string = (
            r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
            '[links](http://github.com/abc\\\\\\)def), '
            '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. '
            r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. '
            '```python\nPython pre```\\.')
        text_markdown = self.test_message_v2.text_markdown_v2
        assert text_markdown == test_md_string

    def test_text_markdown_new_in_v2(self, message):
        message.text = 'test'
        message.entities = [
            MessageEntity(MessageEntity.BOLD, offset=0, length=4),
            MessageEntity(MessageEntity.ITALIC, offset=0, length=4),
        ]
        with pytest.raises(ValueError):
            assert message.text_markdown

        message.entities = [
            MessageEntity(MessageEntity.UNDERLINE, offset=0, length=4)
        ]
        with pytest.raises(ValueError):
            message.text_markdown

        message.entities = [
            MessageEntity(MessageEntity.STRIKETHROUGH, offset=0, length=4)
        ]
        with pytest.raises(ValueError):
            message.text_markdown

        message.entities = []

    def test_text_markdown_empty(self, message):
        message.text = None
        message.caption = "test"
        assert message.text_markdown is None
        assert message.text_markdown_v2 is None

    def test_text_markdown_urled(self):
        test_md_string = (
            r'Test for <*bold*, _ita_\__lic_, `code`, '
            '[links](http://github.com/ab_), '
            '[text-mention](tg://user?id=123456789) and ```python\npre```. '
            '[http://google.com/ab_](http://google.com/ab_)')
        text_markdown = self.test_message.text_markdown_urled
        assert text_markdown == test_md_string

    def test_text_markdown_v2_urled(self):
        test_md_string = (
            r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
            '[links](http://github.com/abc\\\\\\)def), '
            '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. '
            r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ '
            'nested in* italic_\\. ```python\nPython pre```\\.')
        text_markdown = self.test_message_v2.text_markdown_v2_urled
        assert text_markdown == test_md_string

    def test_text_html_emoji(self):
        text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode(
            'unicode-escape')
        expected = b'\\U0001f469\\u200d\\U0001f469\\u200d <b>ABC</b>'.decode(
            'unicode-escape')
        bold_entity = MessageEntity(type=MessageEntity.BOLD,
                                    offset=7,
                                    length=3)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          text=text,
                          entities=[bold_entity])
        assert expected == message.text_html

    def test_text_markdown_emoji(self):
        text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode(
            'unicode-escape')
        expected = b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*'.decode(
            'unicode-escape')
        bold_entity = MessageEntity(type=MessageEntity.BOLD,
                                    offset=7,
                                    length=3)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          text=text,
                          entities=[bold_entity])
        assert expected == message.text_markdown

    def test_caption_html_simple(self):
        test_html_string = (
            '<u>Test</u> for &lt;<b>bold</b>, <i>ita_lic</i>, '
            r'<code>\`code</code>, '
            r'<a href="http://github.com/abc\)def">links</a>, '
            '<a href="tg://user?id=123456789">text-mention</a> and '
            r'<pre>`\pre</pre>. http://google.com '
            'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>. '
            '<pre><code class="python">Python pre</code></pre>.')
        caption_html = self.test_message_v2.caption_html
        assert caption_html == test_html_string

    def test_caption_html_empty(self, message):
        message.text = "test"
        message.caption = None
        assert message.caption_html is None

    def test_caption_html_urled(self):
        test_html_string = (
            '<u>Test</u> for &lt;<b>bold</b>, <i>ita_lic</i>, '
            r'<code>\`code</code>, '
            r'<a href="http://github.com/abc\)def">links</a>, '
            '<a href="tg://user?id=123456789">text-mention</a> and '
            r'<pre>`\pre</pre>. <a href="http://google.com">http://google.com</a> '
            'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>. '
            '<pre><code class="python">Python pre</code></pre>.')
        caption_html = self.test_message_v2.caption_html_urled
        assert caption_html == test_html_string

    def test_caption_markdown_simple(self):
        test_md_string = (
            r'Test for <*bold*, _ita_\__lic_, `code`, '
            '[links](http://github.com/ab_), '
            '[text-mention](tg://user?id=123456789) and ```python\npre```. '
            r'http://google.com/ab\_')
        caption_markdown = self.test_message.caption_markdown
        assert caption_markdown == test_md_string

    def test_caption_markdown_v2_simple(self):
        test_md_string = (
            r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
            '[links](http://github.com/abc\\\\\\)def), '
            '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. '
            r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. '
            '```python\nPython pre```\\.')
        caption_markdown = self.test_message_v2.caption_markdown_v2
        assert caption_markdown == test_md_string

    def test_caption_markdown_empty(self, message):
        message.text = "test"
        message.caption = None
        assert message.caption_markdown is None
        assert message.caption_markdown_v2 is None

    def test_caption_markdown_urled(self):
        test_md_string = (
            r'Test for <*bold*, _ita_\__lic_, `code`, '
            '[links](http://github.com/ab_), '
            '[text-mention](tg://user?id=123456789) and ```python\npre```. '
            '[http://google.com/ab_](http://google.com/ab_)')
        caption_markdown = self.test_message.caption_markdown_urled
        assert caption_markdown == test_md_string

    def test_caption_markdown_v2_urled(self):
        test_md_string = (
            r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
            '[links](http://github.com/abc\\\\\\)def), '
            '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. '
            r'[http://google\.com](http://google.com) and _bold *nested in ~strk~ '
            'nested in* italic_\\. ```python\nPython pre```\\.')
        caption_markdown = self.test_message_v2.caption_markdown_v2_urled
        assert caption_markdown == test_md_string

    def test_caption_html_emoji(self):
        caption = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode(
            'unicode-escape')
        expected = b'\\U0001f469\\u200d\\U0001f469\\u200d <b>ABC</b>'.decode(
            'unicode-escape')
        bold_entity = MessageEntity(type=MessageEntity.BOLD,
                                    offset=7,
                                    length=3)
        message = Message(
            1,
            self.from_user,
            self.date,
            self.chat,
            caption=caption,
            caption_entities=[bold_entity],
        )
        assert expected == message.caption_html

    def test_caption_markdown_emoji(self):
        caption = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode(
            'unicode-escape')
        expected = b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*'.decode(
            'unicode-escape')
        bold_entity = MessageEntity(type=MessageEntity.BOLD,
                                    offset=7,
                                    length=3)
        message = Message(
            1,
            self.from_user,
            self.date,
            self.chat,
            caption=caption,
            caption_entities=[bold_entity],
        )
        assert expected == message.caption_markdown

    def test_parse_entities_url_emoji(self):
        url = b'http://github.com/?unicode=\\u2713\\U0001f469'.decode(
            'unicode-escape')
        text = 'some url'
        link_entity = MessageEntity(type=MessageEntity.URL,
                                    offset=0,
                                    length=8,
                                    url=url)
        message = Message(1,
                          self.from_user,
                          self.date,
                          self.chat,
                          text=text,
                          entities=[link_entity])
        assert message.parse_entities() == {link_entity: text}
        assert next(iter(message.parse_entities())).url == url

    def test_chat_id(self, message):
        assert message.chat_id == message.chat.id

    @pytest.mark.parametrize('type', argvalues=[Chat.SUPERGROUP, Chat.CHANNEL])
    def test_link_with_username(self, message, type):
        message.chat.username = '******'
        message.chat.type = type
        assert message.link == f'https://t.me/{message.chat.username}/{message.message_id}'

    @pytest.mark.parametrize('type, id',
                             argvalues=[(Chat.CHANNEL, -1003),
                                        (Chat.SUPERGROUP, -1003)])
    def test_link_with_id(self, message, type, id):
        message.chat.username = None
        message.chat.id = id
        message.chat.type = type
        # The leading - for group ids/ -100 for supergroup ids isn't supposed to be in the link
        assert message.link == f'https://t.me/c/{3}/{message.message_id}'

    @pytest.mark.parametrize('id, username',
                             argvalues=[(None, 'username'), (-3, None)])
    def test_link_private_chats(self, message, id, username):
        message.chat.type = Chat.PRIVATE
        message.chat.id = id
        message.chat.username = username
        assert message.link is None
        message.chat.type = Chat.GROUP
        assert message.link is None

    def test_effective_attachment(self, message_params):
        for i in (
                'audio',
                'game',
                'document',
                'animation',
                'photo',
                'sticker',
                'video',
                'voice',
                'video_note',
                'contact',
                'location',
                'venue',
                'invoice',
                'invoice',
                'successful_payment',
        ):
            item = getattr(message_params, i, None)
            if item:
                break
        else:
            item = None
        assert message_params.effective_attachment == item

    def test_reply_text(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            text = args[1] == 'test'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and text and reply

        monkeypatch.setattr(message.bot, 'send_message', test)
        assert message.reply_text('test')
        assert message.reply_text('test', quote=True)
        assert message.reply_text('test',
                                  reply_to_message_id=message.message_id,
                                  quote=True)

    def test_reply_markdown(self, monkeypatch, message):
        test_md_string = (
            r'Test for <*bold*, _ita_\__lic_, `code`, '
            '[links](http://github.com/ab_), '
            '[text-mention](tg://user?id=123456789) and ```python\npre```. '
            r'http://google.com/ab\_')

        def test(*args, **kwargs):
            cid = args[0] == message.chat_id
            markdown_text = args[1] == test_md_string
            markdown_enabled = kwargs['parse_mode'] == ParseMode.MARKDOWN
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return all([cid, markdown_text, reply, markdown_enabled])

        text_markdown = self.test_message.text_markdown
        assert text_markdown == test_md_string

        monkeypatch.setattr(message.bot, 'send_message', test)
        assert message.reply_markdown(self.test_message.text_markdown)
        assert message.reply_markdown(self.test_message.text_markdown,
                                      quote=True)
        assert message.reply_markdown(self.test_message.text_markdown,
                                      reply_to_message_id=message.message_id,
                                      quote=True)

    def test_reply_markdown_v2(self, monkeypatch, message):
        test_md_string = (
            r'__Test__ for <*bold*, _ita\_lic_, `\\\`code`, '
            '[links](http://github.com/abc\\\\\\)def), '
            '[text\\-mention](tg://user?id=123456789) and ```\\`\\\\pre```\\. '
            r'http://google\.com and _bold *nested in ~strk~ nested in* italic_\. '
            '```python\nPython pre```\\.')

        def test(*args, **kwargs):
            cid = args[0] == message.chat_id
            markdown_text = args[1] == test_md_string
            markdown_enabled = kwargs['parse_mode'] == ParseMode.MARKDOWN_V2
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return all([cid, markdown_text, reply, markdown_enabled])

        text_markdown = self.test_message_v2.text_markdown_v2
        assert text_markdown == test_md_string

        monkeypatch.setattr(message.bot, 'send_message', test)
        assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2)
        assert message.reply_markdown_v2(self.test_message_v2.text_markdown_v2,
                                         quote=True)
        assert message.reply_markdown_v2(
            self.test_message_v2.text_markdown_v2,
            reply_to_message_id=message.message_id,
            quote=True,
        )

    def test_reply_html(self, monkeypatch, message):
        test_html_string = (
            '<u>Test</u> for &lt;<b>bold</b>, <i>ita_lic</i>, '
            r'<code>\`code</code>, '
            r'<a href="http://github.com/abc\)def">links</a>, '
            '<a href="tg://user?id=123456789">text-mention</a> and '
            r'<pre>`\pre</pre>. http://google.com '
            'and <i>bold <b>nested in <s>strk</s> nested in</b> italic</i>. '
            '<pre><code class="python">Python pre</code></pre>.')

        def test(*args, **kwargs):
            cid = args[0] == message.chat_id
            html_text = args[1] == test_html_string
            html_enabled = kwargs['parse_mode'] == ParseMode.HTML
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return all([cid, html_text, reply, html_enabled])

        text_html = self.test_message_v2.text_html
        assert text_html == test_html_string

        monkeypatch.setattr(message.bot, 'send_message', test)
        assert message.reply_html(self.test_message_v2.text_html)
        assert message.reply_html(self.test_message_v2.text_html, quote=True)
        assert message.reply_html(self.test_message_v2.text_html,
                                  reply_to_message_id=message.message_id,
                                  quote=True)

    def test_reply_media_group(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            media = kwargs['media'] == 'reply_media_group'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and media and reply

        monkeypatch.setattr(message.bot, 'send_media_group', test)
        assert message.reply_media_group(media='reply_media_group')
        assert message.reply_media_group(media='reply_media_group', quote=True)

    def test_reply_photo(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            photo = kwargs['photo'] == 'test_photo'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and photo and reply

        monkeypatch.setattr(message.bot, 'send_photo', test)
        assert message.reply_photo(photo='test_photo')
        assert message.reply_photo(photo='test_photo', quote=True)

    def test_reply_audio(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            audio = kwargs['audio'] == 'test_audio'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and audio and reply

        monkeypatch.setattr(message.bot, 'send_audio', test)
        assert message.reply_audio(audio='test_audio')
        assert message.reply_audio(audio='test_audio', quote=True)

    def test_reply_document(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            document = kwargs['document'] == 'test_document'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and document and reply

        monkeypatch.setattr(message.bot, 'send_document', test)
        assert message.reply_document(document='test_document')
        assert message.reply_document(document='test_document', quote=True)

    def test_reply_animation(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            animation = kwargs['animation'] == 'test_animation'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and animation and reply

        monkeypatch.setattr(message.bot, 'send_animation', test)
        assert message.reply_animation(animation='test_animation')
        assert message.reply_animation(animation='test_animation', quote=True)

    def test_reply_sticker(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            sticker = kwargs['sticker'] == 'test_sticker'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and sticker and reply

        monkeypatch.setattr(message.bot, 'send_sticker', test)
        assert message.reply_sticker(sticker='test_sticker')
        assert message.reply_sticker(sticker='test_sticker', quote=True)

    def test_reply_video(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            video = kwargs['video'] == 'test_video'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and video and reply

        monkeypatch.setattr(message.bot, 'send_video', test)
        assert message.reply_video(video='test_video')
        assert message.reply_video(video='test_video', quote=True)

    def test_reply_video_note(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            video_note = kwargs['video_note'] == 'test_video_note'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and video_note and reply

        monkeypatch.setattr(message.bot, 'send_video_note', test)
        assert message.reply_video_note(video_note='test_video_note')
        assert message.reply_video_note(video_note='test_video_note',
                                        quote=True)

    def test_reply_voice(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            voice = kwargs['voice'] == 'test_voice'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and voice and reply

        monkeypatch.setattr(message.bot, 'send_voice', test)
        assert message.reply_voice(voice='test_voice')
        assert message.reply_voice(voice='test_voice', quote=True)

    def test_reply_location(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            location = kwargs['location'] == 'test_location'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and location and reply

        monkeypatch.setattr(message.bot, 'send_location', test)
        assert message.reply_location(location='test_location')
        assert message.reply_location(location='test_location', quote=True)

    def test_reply_venue(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            venue = kwargs['venue'] == 'test_venue'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and venue and reply

        monkeypatch.setattr(message.bot, 'send_venue', test)
        assert message.reply_venue(venue='test_venue')
        assert message.reply_venue(venue='test_venue', quote=True)

    def test_reply_contact(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            contact = kwargs['contact'] == 'test_contact'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and contact and reply

        monkeypatch.setattr(message.bot, 'send_contact', test)
        assert message.reply_contact(contact='test_contact')
        assert message.reply_contact(contact='test_contact', quote=True)

    def test_reply_poll(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            contact = kwargs['question'] == 'test_poll'
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and contact and reply

        monkeypatch.setattr(message.bot, 'send_poll', test)
        assert message.reply_poll(question='test_poll')
        assert message.reply_poll(question='test_poll', quote=True)

    def test_reply_dice(self, monkeypatch, message):
        def test(*args, **kwargs):
            id_ = args[0] == message.chat_id
            contact = kwargs['disable_notification'] is True
            if kwargs.get('reply_to_message_id'):
                reply = kwargs['reply_to_message_id'] == message.message_id
            else:
                reply = True
            return id_ and contact and reply

        monkeypatch.setattr(message.bot, 'send_dice', test)
        assert message.reply_dice(disable_notification=True)
        assert message.reply_dice(disable_notification=True, quote=True)

    def test_forward(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == 123456
            from_chat = kwargs['from_chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            if kwargs.get('disable_notification'):
                notification = kwargs['disable_notification'] is True
            else:
                notification = True
            return chat_id and from_chat and message_id and notification

        monkeypatch.setattr(message.bot, 'forward_message', test)
        assert message.forward(123456)
        assert message.forward(123456, disable_notification=True)
        assert not message.forward(635241)

    def test_copy(self, monkeypatch, message):
        keyboard = [[1, 2]]

        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == 123456
            from_chat = kwargs['from_chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            if kwargs.get('disable_notification'):
                notification = kwargs['disable_notification'] is True
            else:
                notification = True
            if kwargs.get('reply_markup'):
                reply_markup = kwargs['reply_markup'] is keyboard
            else:
                reply_markup = True
            return chat_id and from_chat and message_id and notification and reply_markup

        monkeypatch.setattr(message.bot, 'copy_message', test)
        assert message.copy(123456)
        assert message.copy(123456, disable_notification=True)
        assert message.copy(123456, reply_markup=keyboard)
        assert not message.copy(635241)

    @pytest.mark.pfff
    def test_reply_copy(self, monkeypatch, message):
        keyboard = [[1, 2]]

        def test(*args, **kwargs):
            chat_id = kwargs['from_chat_id'] == 123456
            from_chat = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == 456789
            if kwargs.get('disable_notification'):
                notification = kwargs['disable_notification'] is True
            else:
                notification = True
            if kwargs.get('reply_markup'):
                reply_markup = kwargs['reply_markup'] is keyboard
            else:
                reply_markup = True
            return chat_id and from_chat and message_id and notification and reply_markup

        monkeypatch.setattr(message.bot, 'copy_message', test)
        assert message.reply_copy(123456, 456789)
        assert message.reply_copy(123456, 456789, disable_notification=True)
        assert message.reply_copy(123456, 456789, reply_markup=keyboard)

    def test_edit_text(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            text = kwargs['text'] == 'test'
            return chat_id and message_id and text

        monkeypatch.setattr(message.bot, 'edit_message_text', test)
        assert message.edit_text(text='test')

    def test_edit_caption(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            caption = kwargs['caption'] == 'new caption'
            return chat_id and message_id and caption

        monkeypatch.setattr(message.bot, 'edit_message_caption', test)
        assert message.edit_caption(caption='new caption')

    def test_edit_media(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            media = kwargs['media'] == 'my_media'
            return chat_id and message_id and media

        monkeypatch.setattr(message.bot, 'edit_message_media', test)
        assert message.edit_media('my_media')

    def test_edit_reply_markup(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            reply_markup = kwargs['reply_markup'] == [['1', '2']]
            return chat_id and message_id and reply_markup

        monkeypatch.setattr(message.bot, 'edit_message_reply_markup', test)
        assert message.edit_reply_markup(reply_markup=[['1', '2']])

    def test_edit_live_location(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            latitude = kwargs['latitude'] == 1
            longitude = kwargs['longitude'] == 2
            return chat_id and message_id and longitude and latitude

        monkeypatch.setattr(message.bot, 'edit_message_live_location', test)
        assert message.edit_live_location(latitude=1, longitude=2)

    def test_stop_live_location(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            return chat_id and message_id

        monkeypatch.setattr(message.bot, 'stop_message_live_location', test)
        assert message.stop_live_location()

    def test_set_game_score(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            user_id = kwargs['user_id'] == 1
            score = kwargs['score'] == 2
            return chat_id and message_id and user_id and score

        monkeypatch.setattr(message.bot, 'set_game_score', test)
        assert message.set_game_score(user_id=1, score=2)

    def test_get_game_high_scores(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            user_id = kwargs['user_id'] == 1
            return chat_id and message_id and user_id

        monkeypatch.setattr(message.bot, 'get_game_high_scores', test)
        assert message.get_game_high_scores(user_id=1, score=2)

    def test_delete(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            return chat_id and message_id

        monkeypatch.setattr(message.bot, 'delete_message', test)
        assert message.delete()

    def test_stop_poll(self, monkeypatch, message):
        def test(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            return chat_id and message_id

        monkeypatch.setattr(message.bot, 'stop_poll', test)
        assert message.stop_poll()

    def test_pin(self, monkeypatch, message):
        def make_assertion(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            return chat_id and message_id

        monkeypatch.setattr(message.bot, 'pin_chat_message', make_assertion)
        assert message.pin()

    def test_unpin(self, monkeypatch, message):
        def make_assertion(*args, **kwargs):
            chat_id = kwargs['chat_id'] == message.chat_id
            message_id = kwargs['message_id'] == message.message_id
            return chat_id and message_id

        monkeypatch.setattr(message.bot, 'unpin_chat_message', make_assertion)
        assert message.unpin()

    def test_default_quote(self, message):
        message.bot.defaults = Defaults()
        kwargs = {}

        message.bot.defaults._quote = False
        message._quote(kwargs)
        assert 'reply_to_message_id' not in kwargs

        message.bot.defaults._quote = True
        message._quote(kwargs)
        assert 'reply_to_message_id' in kwargs

        kwargs = {}
        message.bot.defaults._quote = None
        message.chat.type = Chat.PRIVATE
        message._quote(kwargs)
        assert 'reply_to_message_id' not in kwargs

        message.chat.type = Chat.GROUP
        message._quote(kwargs)
        assert 'reply_to_message_id' in kwargs

    def test_equality(self):
        id_ = 1
        a = Message(
            id_,
            self.date,
            self.chat,
            from_user=self.from_user,
        )
        b = Message(
            id_,
            self.date,
            self.chat,
            from_user=self.from_user,
        )
        c = Message(id_,
                    self.date,
                    Chat(123, Chat.GROUP),
                    from_user=User(0, '', False))
        d = Message(0, self.date, self.chat, from_user=self.from_user)
        e = Update(id_)

        assert a == b
        assert hash(a) == hash(b)
        assert a is not b

        assert a != c
        assert hash(a) != hash(c)

        assert a != d
        assert hash(a) != hash(d)

        assert a != e
        assert hash(a) != hash(e)
Exemplo n.º 29
0
@pytest.fixture(scope='class')
def message(bot):
    return Message(
        TestMessage.id_,
        TestMessage.date,
        TestMessage.chat,
        from_user=TestMessage.from_user,
        bot=bot,
    )


@pytest.fixture(
    scope='function',
    params=[
        {
            'forward_from': User(99, 'forward_user', False),
            'forward_date': datetime.utcnow()
        },
        {
            'forward_from_chat': Chat(-23, 'channel'),
            'forward_from_message_id': 101,
            'forward_date': datetime.utcnow(),
        },
        {
            'reply_to_message': Message(50, None, None, None)
        },
        {
            'edit_date': datetime.utcnow()
        },
        {
            'text':
def inline_query(bot):
    return Update(0, inline_query=InlineQuery('id', User(2, 'test user', False),
                                              'test query', offset='22',
                                              location=Location(latitude=-23.691288,
                                                                longitude=-46.788279)))