async def test_basic(self, app, prefix, command): """Test the basic expected response from a prefix handler""" handler = self.make_default_handler() app.add_handler(handler) text = prefix + command assert await self.response(app, make_message_update(text)) assert not is_match(handler, make_message_update(command)) assert not is_match(handler, make_message_update(prefix + "notacommand")) assert not is_match(handler, make_command_update(f"not {text} at start")) assert not is_match( handler, make_message_update(bot=app.bot, message=None, caption="caption")) handler = PrefixHandler(prefix=["!", "#"], command="cmd", callback=self.callback) assert isinstance(handler.commands, frozenset) assert handler.commands == {"!cmd", "#cmd"} handler = PrefixHandler(prefix="#", command={"cmd", "bmd"}, callback=self.callback) assert isinstance(handler.commands, frozenset) assert handler.commands == {"#cmd", "#bmd"}
def test_pass_args(self, dp, prefix_message): handler = self.make_default_handler(self.ch_callback_args, pass_args=True) dp.add_handler(handler) assert self.response(dp, make_message_update(prefix_message)) update_with_args = make_message_update(prefix_message.text + ' one two') assert self.response(dp, update_with_args)
def test_with_filter(self, prefix_message_text): handler = self.make_default_handler(filters=Filters.group) text = prefix_message_text assert is_match(handler, make_message_update(text, chat=Chat(-23, Chat.GROUP))) assert not is_match( handler, make_message_update(text, chat=Chat(23, Chat.PRIVATE)))
def test_basic(self, dp, prefix, command): """Test the basic expected response from a prefix handler""" handler = self.make_default_handler() dp.add_handler(handler) text = prefix + command assert self.response(dp, make_message_update(text)) assert not is_match(handler, make_message_update(command)) assert not is_match(handler, make_message_update(prefix + 'notacommand')) assert not is_match(handler, make_command_update('not {} at start'.format(text)))
def test_basic_after_editing(self, dp, prefix, command): """Test the basic expected response from a prefix handler""" handler = self.make_default_handler() dp.add_handler(handler) text = prefix + command assert self.response(dp, make_message_update(text)) handler.command = 'foo' text = prefix + 'foo' assert self.response(dp, make_message_update(text))
async def test_basic(self, app, command): """Test whether a command handler responds to its command and not to others, or badly formatted commands""" handler = self.make_default_handler() app.add_handler(handler) assert await self.response(app, make_command_update(command, bot=app.bot)) assert not is_match(handler, make_command_update(command[1:], bot=app.bot)) assert not is_match( handler, make_command_update(f"/not{command[1:]}", bot=app.bot)) assert not is_match( handler, make_command_update(f"not {command} at start", bot=app.bot)) assert not is_match( handler, make_message_update(bot=app.bot, message=None, caption="caption")) handler = CommandHandler(["FOO", "bAR"], callback=self.callback) assert isinstance(handler.commands, frozenset) assert handler.commands == {"foo", "bar"} handler = CommandHandler(["FOO"], callback=self.callback) assert isinstance(handler.commands, frozenset) assert handler.commands == {"foo"}
async def test_webhook_arbitrary_callback_data(self, monkeypatch, updater, invalid_data, chat_id): """Here we only test one simple setup. telegram.ext.ExtBot.insert_callback_data is tested extensively in test_bot.py in conjunction with get_updates.""" updater.bot.arbitrary_callback_data = True async def return_true(*args, **kwargs): return True try: monkeypatch.setattr(updater.bot, "set_webhook", return_true) monkeypatch.setattr(updater.bot, "delete_webhook", return_true) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port async with updater: await updater.start_webhook(ip, port, url_path="TOKEN") # Now, we send an update to the server reply_markup = InlineKeyboardMarkup.from_button( InlineKeyboardButton(text="text", callback_data="callback_data")) if not invalid_data: reply_markup = updater.bot.callback_data_cache.process_keyboard( reply_markup) update = make_message_update( message="test_webhook_arbitrary_callback_data", message_factory=make_message, reply_markup=reply_markup, user=updater.bot.bot, ) await send_webhook_message(ip, port, update.to_json(), "TOKEN") received_update = await updater.update_queue.get() assert received_update.update_id == update.update_id message_dict = update.message.to_dict() received_dict = received_update.message.to_dict() message_dict.pop("reply_markup") received_dict.pop("reply_markup") assert message_dict == received_dict button = received_update.message.reply_markup.inline_keyboard[ 0][0] if invalid_data: assert isinstance(button.callback_data, InvalidCallbackData) else: assert button.callback_data == "callback_data" await updater.stop() finally: updater.bot.arbitrary_callback_data = False updater.bot.callback_data_cache.clear_callback_data() updater.bot.callback_data_cache.clear_callback_queries()
async def test_webhook_update_de_json_fails(self, monkeypatch, updater, caplog): async def delete_webhook(*args, **kwargs): return True async def set_webhook(*args, **kwargs): return True def de_json_fails(*args, **kwargs): raise TypeError("Invalid input") monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) orig_de_json = Update.de_json monkeypatch.setattr(Update, "de_json", de_json_fails) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port async with updater: return_value = await updater.start_webhook( ip_address=ip, port=port, url_path="TOKEN", ) assert return_value is updater.update_queue assert updater.running # Now, we send an update to the server update = make_message_update("Webhook") with caplog.at_level(logging.CRITICAL): await send_webhook_message(ip, port, update.to_json(), "TOKEN") assert len(caplog.records) == 1 assert caplog.records[-1].getMessage().startswith( "Something went wrong processing") # Make sure that everything works fine again when receiving proper updates caplog.clear() with caplog.at_level(logging.CRITICAL): monkeypatch.setattr(Update, "de_json", orig_de_json) await send_webhook_message(ip, port, update.to_json(), "TOKEN") assert ( await updater.update_queue.get()).to_dict() == update.to_dict() assert len(caplog.records) == 0 await updater.stop() assert not updater.running
async def test_webhook_ssl_just_for_telegram(self, monkeypatch, updater): """Here we just test that the SSL info is pased to Telegram, but __not__ to the the webhook server""" async def set_webhook(**kwargs): self.test_flag.append(bool(kwargs.get("certificate"))) return True async def return_true(*args, **kwargs): return True orig_wh_server_init = WebhookServer.__init__ def webhook_server_init(*args, **kwargs): self.test_flag = [kwargs.get("ssl_ctx") is None] orig_wh_server_init(*args, **kwargs) monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) monkeypatch.setattr(updater.bot, "delete_webhook", return_true) monkeypatch.setattr( "telegram.ext._utils.webhookhandler.WebhookServer.__init__", webhook_server_init) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port async with updater: await updater.start_webhook(ip, port, webhook_url=None, cert=Path(__file__).as_posix()) # Now, we send an update to the server update = make_message_update(message="test_message") await send_webhook_message(ip, port, update.to_json()) assert (await updater.update_queue.get()).to_dict() == update.to_dict() assert self.test_flag == [True, True] await updater.stop()
def test_filters_for_wrong_command(self, mock_filter): """Filters should not be executed if the command does not match the handler""" handler = self.make_default_handler(filters=mock_filter) assert not is_match(handler, make_message_update('/test')) assert not mock_filter.tested
def prefix_message_update(self, prefix_message): return make_message_update(prefix_message)
async def test_webhook_basic(self, monkeypatch, updater, drop_pending_updates, ext_bot, secret_token): # Testing with both ExtBot and Bot to make sure any logic in WebhookHandler # that depends on this distinction works if ext_bot and not isinstance(updater.bot, ExtBot): updater.bot = ExtBot(updater.bot.token) if not ext_bot and not type(updater.bot) is Bot: updater.bot = DictBot(updater.bot.token) async def delete_webhook(*args, **kwargs): # Dropping pending updates is done by passing the parameter to delete_webhook if kwargs.get("drop_pending_updates"): self.message_count += 1 return True async def set_webhook(*args, **kwargs): return True monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port async with updater: return_value = await updater.start_webhook( drop_pending_updates=drop_pending_updates, ip_address=ip, port=port, url_path="TOKEN", secret_token=secret_token, ) assert return_value is updater.update_queue assert updater.running # Now, we send an update to the server update = make_message_update("Webhook") await send_webhook_message(ip, port, update.to_json(), "TOKEN", secret_token=secret_token) assert (await updater.update_queue.get()).to_dict() == update.to_dict() # Returns Not Found if path is incorrect response = await send_webhook_message(ip, port, "123456", "webhook_handler.py") assert response.status_code == HTTPStatus.NOT_FOUND # Returns METHOD_NOT_ALLOWED if method is not allowed response = await send_webhook_message(ip, port, None, "TOKEN", get_method="HEAD") assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED if secret_token: # Returns Forbidden if no secret token is set response_text = "<html><title>403: {0}</title><body>403: {0}</body></html>" response = await send_webhook_message(ip, port, update.to_json(), "TOKEN") assert response.status_code == HTTPStatus.FORBIDDEN assert response.text == response_text.format( "Request did not include the secret token") # Returns Forbidden if the secret token is wrong response = await send_webhook_message( ip, port, update.to_json(), "TOKEN", secret_token="NotTheSecretToken") assert response.status_code == HTTPStatus.FORBIDDEN assert response.text == response_text.format( "Request had the wrong secret token") await updater.stop() assert not updater.running if drop_pending_updates: assert self.message_count == 1 else: assert self.message_count == 0 # We call the same logic twice to make sure that restarting the updater works as well await updater.start_webhook( drop_pending_updates=drop_pending_updates, ip_address=ip, port=port, url_path="TOKEN", ) assert updater.running update = make_message_update("Webhook") await send_webhook_message(ip, port, update.to_json(), "TOKEN") assert (await updater.update_queue.get()).to_dict() == update.to_dict() await updater.stop() assert not updater.running