Exemple #1
0
    def test_conversation_handler_per_message(self, dp, bot, user1, user2):
        def entry(bot, update):
            return 1

        def one(bot, update):
            return 2

        def two(bot, update):
            return ConversationHandler.END

        handler = ConversationHandler(
            entry_points=[CallbackQueryHandler(entry)],
            states={1: [CallbackQueryHandler(one)],
                    2: [CallbackQueryHandler(two)]},
            fallbacks=[],
            per_message=True)
        dp.add_handler(handler)

        # User one, starts the state machine.
        message = Message(0, user1, None, self.group, text='msg w/ inlinekeyboard', bot=bot)

        cbq = CallbackQuery(0, user1, None, message=message, data='data', bot=bot)
        dp.process_update(Update(update_id=0, callback_query=cbq))

        assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 1

        dp.process_update(Update(update_id=0, callback_query=cbq))

        assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 2

        # Let's now verify that for a different user in the same group, the state will not be
        # updated
        cbq.from_user = user2
        dp.process_update(Update(update_id=0, callback_query=cbq))

        assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 2
Exemple #2
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
    def test_webhook_no_ssl(self):
        print('Testing Webhook without SSL')
        self._setup_updater('', messages=0)
        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')
Exemple #4
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
Exemple #5
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
Exemple #6
0
def auto_spin(bot: Bot, job: Job):
    from telegram import Message, Chat
    u = Update(0, message=Message(0, None, 0, Chat(job.context, '')))
    if core.results_today.get(job.context) is None:
        do_the_spin(bot, u)

@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':
            'a text message',
            'enitites':
            [MessageEntity('bold', 10, 4),
             MessageEntity('italic', 16, 7)],
        },
        {
            'caption':
            'A message caption',
            'caption_entities':
Exemple #8
0
def message(bot):
    return Message(1, None, Chat(1, ''), from_user=User(1, '', False), bot=bot)
def message(bot):
    return Message(1, None, None, None, bot=bot)
class TestMessage(object):
    id = 1
    from_user = User(2, 'testuser', False)
    date = datetime.now()
    chat = Chat(3, 'private')
    test_entities = [{
        'length': 4,
        'offset': 10,
        'type': 'bold'
    }, {
        'length': 7,
        'offset': 16,
        'type': 'italic'
    }, {
        'length': 4,
        'offset': 25,
        'type': 'code'
    }, {
        'length': 5,
        'offset': 31,
        'type': 'text_link',
        'url': 'http://github.com/'
    }, {
        'length': 3,
        'offset': 41,
        'type': 'pre'
    }, {
        'length': 17,
        'offset': 46,
        'type': 'url'
    }]
    test_text = 'Test for <bold, ita_lic, code, links and pre. http://google.com'
    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])

    def test_all_posibilities_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['date'] == message.date
        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 = (
            'Test for &lt;<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
            '<a href="http://github.com/">links</a> and <pre>pre</pre>. '
            'http://google.com')
        text_html = self.test_message.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 = (
            'Test for &lt;<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
            '<a href="http://github.com/">links</a> and <pre>pre</pre>. '
            '<a href="http://google.com">http://google.com</a>')
        text_html = self.test_message.text_html_urled
        assert text_html == test_html_string

    def test_text_markdown_simple(self):
        test_md_string = (
            'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and '
            '```pre```. http://google.com')
        text_markdown = self.test_message.text_markdown
        assert text_markdown == test_md_string

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

    def test_text_markdown_urled(self):
        test_md_string = (
            'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and '
            '```pre```. [http://google.com](http://google.com)')
        text_markdown = self.test_message.text_markdown_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 = (
            'Test for &lt;<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
            '<a href="http://github.com/">links</a> and <pre>pre</pre>. '
            'http://google.com')
        caption_html = self.test_message.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 = (
            'Test for &lt;<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
            '<a href="http://github.com/">links</a> and <pre>pre</pre>. '
            '<a href="http://google.com">http://google.com</a>')
        caption_html = self.test_message.caption_html_urled
        assert caption_html == test_html_string

    def test_caption_markdown_simple(self):
        test_md_string = (
            'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and '
            '```pre```. http://google.com')
        caption_markdown = self.test_message.caption_markdown
        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

    def test_caption_markdown_urled(self):
        test_md_string = (
            'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and '
            '```pre```. [http://google.com](http://google.com)')
        caption_markdown = self.test_message.caption_markdown_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

    def test_link(self, message):
        assert message.link is None
        message.chat.username = '******'
        message.chat.type = 'supergroup'
        assert message.link == 'https://t.me/{}/{}'.format(
            message.chat.username, message.message_id)
        message.chat.type = 'channel'
        assert message.link == 'https://t.me/{}/{}'.format(
            message.chat.username, message.message_id)
        message.chat.type = 'private'
        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[1] == message.chat_id
            text = args[2] == '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('telegram.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 = (
            'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and '
            '```pre```. http://google.com')

        def test(*args, **kwargs):
            cid = args[1] == message.chat_id
            markdown_text = args[2] == 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('telegram.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_html(self, monkeypatch, message):
        test_html_string = (
            'Test for &lt;<b>bold</b>, <i>ita_lic</i>, <code>code</code>, '
            '<a href="http://github.com/">links</a> and <pre>pre</pre>. '
            'http://google.com')

        def test(*args, **kwargs):
            cid = args[1] == message.chat_id
            html_text = args[2] == 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.text_html
        assert text_html == test_html_string

        monkeypatch.setattr('telegram.Bot.send_message', test)
        assert message.reply_html(self.test_message.text_html)
        assert message.reply_html(self.test_message.text_html, quote=True)
        assert message.reply_html(self.test_message.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.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[1] == 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('telegram.Bot.send_contact', test)
        assert message.reply_contact(contact='test_contact')
        assert message.reply_contact(contact='test_contact', 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('telegram.Bot.forward_message', test)
        assert message.forward(123456)
        assert message.forward(123456, disable_notification=True)
        assert not message.forward(635241)

    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('telegram.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('telegram.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('telegram.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('telegram.Bot.edit_message_reply_markup', test)
        assert message.edit_reply_markup(reply_markup=[['1', '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('telegram.Bot.delete_message', test)
        assert message.delete()

    def test_equality(self):
        id = 1
        a = Message(id, self.from_user, self.date, self.chat)
        b = Message(id, self.from_user, self.date, self.chat)
        c = Message(id, User(0, '', False), self.date, self.chat)
        d = Message(0, self.from_user, self.date, self.chat)
        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)
class TestCallbackQuery:
    id = 'id'
    from_user = User(1, 'test_user')
    chat_instance = 'chat_instance'
    message = Message(3, User(5, 'bot'), None, Chat(4, 'private'))
    data = 'data'
    inline_message_id = 'inline_message_id'
    game_short_name = 'the_game'

    def test_de_json(self, bot):
        json_dict = {
            'id': self.id,
            'from': self.from_user.to_dict(),
            'chat_instance': self.chat_instance,
            'message': self.message.to_dict(),
            'data': self.data,
            'inline_message_id': self.inline_message_id,
            'game_short_name': self.game_short_name
        }
        callbackquery = CallbackQuery.de_json(json_dict, bot)

        assert callbackquery.id == self.id
        assert callbackquery.from_user == self.from_user
        assert callbackquery.chat_instance == self.chat_instance
        assert callbackquery.message == self.message
        assert callbackquery.data == self.data
        assert callbackquery.inline_message_id == self.inline_message_id
        assert callbackquery.game_short_name == self.game_short_name

    def test_to_json(self, callback_query):
        json.loads(callback_query.to_json())

    def test_to_dict(self, callback_query):
        callback_query_dict = callback_query.to_dict()

        assert isinstance(callback_query_dict, dict)
        assert callback_query_dict['id'] == callback_query.id
        assert callback_query_dict['from'] == callback_query.from_user.to_dict(
        )
        assert callback_query_dict[
            'chat_instance'] == callback_query.chat_instance
        if callback_query.message:
            assert callback_query_dict[
                'message'] == callback_query.message.to_dict()
        else:
            assert callback_query_dict[
                'inline_message_id'] == callback_query.inline_message_id
        assert callback_query_dict['data'] == callback_query.data
        assert callback_query_dict[
            'game_short_name'] == callback_query.game_short_name

    def test_answer(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            return args[1] == callback_query.id

        monkeypatch.setattr('telegram.Bot.answerCallbackQuery', test)
        # TODO: PEP8
        assert callback_query.answer()

    def test_edit_message_text(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                text = kwargs['text'] == 'test'
                return id and text
            except KeyError:
                chat_id = kwargs['chat_id'] == callback_query.message.chat_id
                message_id = kwargs[
                    'message_id'] == callback_query.message.message_id
                text = kwargs['text'] == 'test'
                return chat_id and message_id and text

        monkeypatch.setattr('telegram.Bot.edit_message_text', test)
        assert callback_query.edit_message_text(text="test")

    def test_edit_message_caption(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                caption = kwargs['caption'] == 'new caption'
                return id and caption
            except KeyError:
                id = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs[
                    'message_id'] == callback_query.message.message_id
                caption = kwargs['caption'] == 'new caption'
                return id and message and caption

        monkeypatch.setattr('telegram.Bot.edit_message_caption', test)
        assert callback_query.edit_message_caption(caption='new caption')

    def test_edit_message_reply_markup(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                reply_markup = kwargs['reply_markup'] == [["1", "2"]]
                return id and reply_markup
            except KeyError:
                id = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs[
                    'message_id'] == callback_query.message.message_id
                reply_markup = kwargs['reply_markup'] == [["1", "2"]]
                return id and message and reply_markup

        monkeypatch.setattr('telegram.Bot.edit_message_reply_markup', test)
        assert callback_query.edit_message_reply_markup(
            reply_markup=[["1", "2"]])
Exemple #12
0
def update(bot):
    user = User(id=321, first_name='test_user', is_bot=False)
    chat = Chat(id=123, type='group')
    message = Message(1, user, None, chat, text="Hi there", bot=bot)
    return Update(0, message=message)
Exemple #13
0
    def test_dispatcher_integration_handlers(self, caplog, bot,
                                             base_persistence, chat_data,
                                             user_data):
        def get_user_data():
            return user_data

        def get_chat_data():
            return chat_data

        base_persistence.get_user_data = get_user_data
        base_persistence.get_chat_data = get_chat_data
        # base_persistence.update_chat_data = lambda x: x
        # base_persistence.update_user_data = lambda x: x
        updater = Updater(bot=bot,
                          persistence=base_persistence,
                          use_context=True)
        dp = updater.dispatcher

        def callback_known_user(update, context):
            if not context.user_data['test1'] == 'test2':
                pytest.fail('user_data corrupt')

        def callback_known_chat(update, context):
            if not context.chat_data['test3'] == 'test4':
                pytest.fail('chat_data corrupt')

        def callback_unknown_user_or_chat(update, context):
            if not context.user_data == {}:
                pytest.fail('user_data corrupt')
            if not context.chat_data == {}:
                pytest.fail('chat_data corrupt')
            context.user_data[1] = 'test7'
            context.chat_data[2] = 'test8'

        known_user = MessageHandler(Filters.user(user_id=12345),
                                    callback_known_user,
                                    pass_chat_data=True,
                                    pass_user_data=True)
        known_chat = MessageHandler(Filters.chat(chat_id=-67890),
                                    callback_known_chat,
                                    pass_chat_data=True,
                                    pass_user_data=True)
        unknown = MessageHandler(Filters.all,
                                 callback_unknown_user_or_chat,
                                 pass_chat_data=True,
                                 pass_user_data=True)
        dp.add_handler(known_user)
        dp.add_handler(known_chat)
        dp.add_handler(unknown)
        user1 = User(id=12345, first_name='test user', is_bot=False)
        user2 = User(id=54321, first_name='test user', is_bot=False)
        chat1 = Chat(id=-67890, type='group')
        chat2 = Chat(id=-987654, type='group')
        m = Message(1, user1, None, chat2)
        u = Update(0, m)
        with caplog.at_level(logging.ERROR):
            dp.process_update(u)
        rec = caplog.records[-1]
        assert rec.msg == 'No error handlers are registered, logging exception.'
        assert rec.levelname == 'ERROR'
        rec = caplog.records[-2]
        assert rec.msg == 'No error handlers are registered, logging exception.'
        assert rec.levelname == 'ERROR'
        m.from_user = user2
        m.chat = chat1
        u = Update(1, m)
        dp.process_update(u)
        m.chat = chat2
        u = Update(2, m)

        def save_chat_data(data):
            if -987654 not in data:
                pytest.fail()

        def save_user_data(data):
            if 54321 not in data:
                pytest.fail()

        base_persistence.update_chat_data = save_chat_data
        base_persistence.update_user_data = save_user_data
        dp.process_update(u)

        assert dp.user_data[54321][1] == 'test7'
        assert dp.chat_data[-987654][2] == 'test8'
class TestDispatcher(object):
    message_update = Update(1,
                            message=Message(1,
                                            User(1, '', False),
                                            None,
                                            Chat(1, ''),
                                            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_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):
        raise TelegramError(update.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 test_error_handler(self, dp):
        dp.add_error_handler(self.error_handler)
        error = TelegramError('Unauthorized.')
        dp.update_queue.put(error)
        sleep(.1)
        assert self.received == 'Unauthorized.'

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

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

    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

        with pytest.raises(
                TypeError,
                match=
                'persistence should 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(.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(.1)

        assert self.count == 1

    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(.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(.1)
        assert self.received == self.message_update.message

    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(.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(.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(.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(.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',
                                        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 = []

        def start1(b, u):
            passed.append('start1')
            raise Exception('General exception')

        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',
                                        bot=bot))

        # If an unhandled exception was caught, no further handlers from the same group should be
        # called.
        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', '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',
                                        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_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',
                                        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_process_message_no_reply_markup(self, callback_data_cache):
     message = Message(1, None, None)
     callback_data_cache.process_message(message)
     assert message.reply_markup is None
class TestCallbackQuery:
    id_ = 'id'
    from_user = User(1, 'test_user', False)
    chat_instance = 'chat_instance'
    message = Message(3, User(5, 'bot', False), None, Chat(4, 'private'))
    data = 'data'
    inline_message_id = 'inline_message_id'
    game_short_name = 'the_game'

    def test_de_json(self, bot):
        json_dict = {'id': self.id_,
                     'from': self.from_user.to_dict(),
                     'chat_instance': self.chat_instance,
                     'message': self.message.to_dict(),
                     'data': self.data,
                     'inline_message_id': self.inline_message_id,
                     'game_short_name': self.game_short_name,
                     'default_quote': True}
        callback_query = CallbackQuery.de_json(json_dict, bot)

        assert callback_query.id == self.id_
        assert callback_query.from_user == self.from_user
        assert callback_query.chat_instance == self.chat_instance
        assert callback_query.message == self.message
        assert callback_query.message.default_quote is True
        assert callback_query.data == self.data
        assert callback_query.inline_message_id == self.inline_message_id
        assert callback_query.game_short_name == self.game_short_name

    def test_to_dict(self, callback_query):
        callback_query_dict = callback_query.to_dict()

        assert isinstance(callback_query_dict, dict)
        assert callback_query_dict['id'] == callback_query.id
        assert callback_query_dict['from'] == callback_query.from_user.to_dict()
        assert callback_query_dict['chat_instance'] == callback_query.chat_instance
        if callback_query.message:
            assert callback_query_dict['message'] == callback_query.message.to_dict()
        else:
            assert callback_query_dict['inline_message_id'] == callback_query.inline_message_id
        assert callback_query_dict['data'] == callback_query.data
        assert callback_query_dict['game_short_name'] == callback_query.game_short_name

    def test_answer(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            return args[0] == callback_query.id

        monkeypatch.setattr(callback_query.bot, 'answerCallbackQuery', test)
        # TODO: PEP8
        assert callback_query.answer()

    def test_edit_message_text(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            text = args[0] == 'test'
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and text
            except KeyError:
                chat_id = kwargs['chat_id'] == callback_query.message.chat_id
                message_id = kwargs['message_id'] == callback_query.message.message_id
                return chat_id and message_id and text

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

    def test_edit_message_caption(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            caption = kwargs['caption'] == 'new caption'
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and caption
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and caption

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

    def test_edit_message_reply_markup(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            reply_markup = kwargs['reply_markup'] == [['1', '2']]
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and reply_markup
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and reply_markup

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

    def test_edit_message_media(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            message_media = kwargs.get('media') == [['1', '2']] or args[0] == [['1', '2']]
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and message_media
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and message_media

        monkeypatch.setattr(callback_query.bot, 'edit_message_media', test)
        assert callback_query.edit_message_media(media=[['1', '2']])
        assert callback_query.edit_message_media([['1', '2']])

    def test_edit_message_live_location(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            latitude = kwargs.get('latitude') == 1 or args[0] == 1
            longitude = kwargs.get('longitude') == 2 or args[1] == 2
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and latitude and longitude
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and latitude and longitude

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

    def test_stop_message_live_location(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message

        monkeypatch.setattr(callback_query.bot, 'stop_message_live_location', test)
        assert callback_query.stop_message_live_location()

    def test_set_game_score(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            user_id = kwargs.get('user_id') == 1 or args[0] == 1
            score = kwargs.get('score') == 2 or args[1] == 2
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and user_id and score
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and user_id and score

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

    def test_get_game_high_scores(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            user_id = kwargs.get('user_id') == 1 or args[0] == 1
            try:
                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
                return id_ and user_id
            except KeyError:
                id_ = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs['message_id'] == callback_query.message.message_id
                return id_ and message and user_id

        monkeypatch.setattr(callback_query.bot, 'get_game_high_scores', test)
        assert callback_query.get_game_high_scores(user_id=1)
        assert callback_query.get_game_high_scores(1)

    def test_equality(self):
        a = CallbackQuery(self.id_, self.from_user, 'chat')
        b = CallbackQuery(self.id_, self.from_user, 'chat')
        c = CallbackQuery(self.id_, None, '')
        d = CallbackQuery('', None, 'chat')
        e = Audio(self.id_, 'unique_id', 1)

        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)
def message(bot):
    return Message(TestMessage.id_,
                   TestMessage.date,
                   TestMessage.chat,
                   from_user=TestMessage.from_user,
                   bot=bot)
class TestCallbackQuery(object):
    id = 'id'
    from_user = User(1, 'test_user', False)
    chat_instance = 'chat_instance'
    message = Message(3, User(5, 'bot', False), None, Chat(4, 'private'))
    data = 'data'
    inline_message_id = 'inline_message_id'
    game_short_name = 'the_game'

    def test_de_json(self, bot):
        json_dict = {
            'id': self.id,
            'from': self.from_user.to_dict(),
            'chat_instance': self.chat_instance,
            'message': self.message.to_dict(),
            'data': self.data,
            'inline_message_id': self.inline_message_id,
            'game_short_name': self.game_short_name
        }
        callback_query = CallbackQuery.de_json(json_dict, bot)

        assert callback_query.id == self.id
        assert callback_query.from_user == self.from_user
        assert callback_query.chat_instance == self.chat_instance
        assert callback_query.message == self.message
        assert callback_query.data == self.data
        assert callback_query.inline_message_id == self.inline_message_id
        assert callback_query.game_short_name == self.game_short_name

    def test_to_dict(self, callback_query):
        callback_query_dict = callback_query.to_dict()

        assert isinstance(callback_query_dict, dict)
        assert callback_query_dict['id'] == callback_query.id
        assert callback_query_dict['from'] == callback_query.from_user.to_dict(
        )
        assert callback_query_dict[
            'chat_instance'] == callback_query.chat_instance
        if callback_query.message:
            assert callback_query_dict[
                'message'] == callback_query.message.to_dict()
        else:
            assert callback_query_dict[
                'inline_message_id'] == callback_query.inline_message_id
        assert callback_query_dict['data'] == callback_query.data
        assert callback_query_dict[
            'game_short_name'] == callback_query.game_short_name

    def test_answer(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            return args[1] == callback_query.id

        monkeypatch.setattr('telegram.Bot.answerCallbackQuery', test)
        # TODO: PEP8
        assert callback_query.answer()

    def test_edit_message_text(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                text = kwargs['text'] == 'test'
                return id and text
            except KeyError:
                chat_id = kwargs['chat_id'] == callback_query.message.chat_id
                message_id = kwargs[
                    'message_id'] == callback_query.message.message_id
                text = kwargs['text'] == 'test'
                return chat_id and message_id and text

        monkeypatch.setattr('telegram.Bot.edit_message_text', test)
        assert callback_query.edit_message_text(text='test')

    def test_edit_message_caption(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                caption = kwargs['caption'] == 'new caption'
                return id and caption
            except KeyError:
                id = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs[
                    'message_id'] == callback_query.message.message_id
                caption = kwargs['caption'] == 'new caption'
                return id and message and caption

        monkeypatch.setattr('telegram.Bot.edit_message_caption', test)
        assert callback_query.edit_message_caption(caption='new caption')

    def test_edit_message_reply_markup(self, monkeypatch, callback_query):
        def test(*args, **kwargs):
            try:
                id = kwargs[
                    'inline_message_id'] == callback_query.inline_message_id
                reply_markup = kwargs['reply_markup'] == [['1', '2']]
                return id and reply_markup
            except KeyError:
                id = kwargs['chat_id'] == callback_query.message.chat_id
                message = kwargs[
                    'message_id'] == callback_query.message.message_id
                reply_markup = kwargs['reply_markup'] == [['1', '2']]
                return id and message and reply_markup

        monkeypatch.setattr('telegram.Bot.edit_message_reply_markup', test)
        assert callback_query.edit_message_reply_markup(
            reply_markup=[['1', '2']])

    def test_equality(self):
        a = CallbackQuery(self.id, self.from_user, 'chat')
        b = CallbackQuery(self.id, self.from_user, 'chat')
        c = CallbackQuery(self.id, None, '')
        d = CallbackQuery('', None, 'chat')
        e = Audio(self.id, 1)

        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)
Exemple #19
0
    Message,
    Update,
    Chat,
    Bot,
    User,
    CallbackQuery,
    InlineQuery,
    ChosenInlineResult,
    ShippingQuery,
    PreCheckoutQuery,
)
from telegram.ext import Filters, MessageHandler, CallbackContext, JobQueue, UpdateFilter

message = Message(1,
                  None,
                  Chat(1, ''),
                  from_user=User(1, '', False),
                  text='Text')

params = [
    {
        'callback_query':
        CallbackQuery(1, User(1, '', False), 'chat', message=message)
    },
    {
        'inline_query': InlineQuery(1, User(1, '', False), '', '')
    },
    {
        'chosen_inline_result': ChosenInlineResult('id', User(1, '', False),
                                                   '')
    },
 def setUp(self):
     self.message = Message(0, User(0, "Testuser"), datetime.now(),
                            Chat(0, 'private'))
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program.  If not, see [http://www.gnu.org/licenses/].
from queue import Queue

import pytest

from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery,
                      ChosenInlineResult, ShippingQuery, PreCheckoutQuery, Location)
from telegram.ext import InlineQueryHandler, CallbackContext, JobQueue

message = Message(1, User(1, '', False), None, Chat(1, ''), text='Text')

params = [
    {'message': message},
    {'edited_message': message},
    {'callback_query': CallbackQuery(1, User(1, '', False), 'chat', message=message)},
    {'channel_post': message},
    {'edited_channel_post': message},
    {'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 = ('message', 'edited_message', 'callback_query', 'channel_post',
       'edited_channel_post', 'chosen_inline_result',
def message_params(bot, request):
    return Message(message_id=TestMessage.id_,
                   from_user=TestMessage.from_user,
                   date=TestMessage.date,
                   chat=TestMessage.chat, bot=bot, **request.param)
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)
 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'
Exemple #25
0
def update():
    _update = Update(0)
    _update.message = Message(0, 0, datetime.utcnow(), Chat(0, 0))
    return _update
    Bot,
    CallbackQuery,
    Chat,
    ChosenInlineResult,
    Message,
    PollAnswer,
    PreCheckoutQuery,
    ShippingQuery,
    Update,
    User,
)
from telegram.ext import CallbackContext, JobQueue, PollAnswerHandler

message = Message(1,
                  None,
                  Chat(1, ""),
                  from_user=User(1, "", False),
                  text="Text")

params = [
    {
        "message": message
    },
    {
        "edited_message": message
    },
    {
        "callback_query":
        CallbackQuery(1, User(1, "", False), "chat", message=message)
    },
    {
Exemple #27
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"]
def update():
    return Update(
        0,
        Message(0, User(0, 'Testuser', False), datetime.datetime.utcnow(),
                Chat(0, 'private')))
Exemple #29
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
Exemple #30
0
 def test_channel_message_without_chat(self, bot):
     handler = ConversationHandler(entry_points=[CommandHandler('start', self.start_end)],
                                   states={}, fallbacks=[])
     message = Message(0, None, None, Chat(0, Chat.CHANNEL, 'Misses Test'), bot=bot)
     update = Update(0, message=message)
     assert not handler.check_update(update)