python-telegram-bot/tests/test_updater.py

458 lines
14 KiB
Python
Raw Normal View History

#!/usr/bin/env python
# encoding: utf-8
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015 Leandro Toledo de Souza <leandrotoeldodesouza@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
2015-11-24 21:06:55 +01:00
"""
This module contains a object that represents Tests for Updater, Dispatcher,
WebhookServer and WebhookHandler
"""
import logging
import unittest
import sys
2015-11-21 23:09:44 +01:00
import re
2015-11-24 14:57:54 +01:00
import os
import signal
from random import randrange
from time import sleep
2015-11-21 23:09:44 +01:00
from datetime import datetime
2015-11-21 23:09:44 +01:00
try:
from urllib2 import urlopen, Request
except ImportError:
from urllib.request import Request, urlopen
sys.path.append('.')
2015-11-22 19:16:49 +01:00
from telegram import Update, Message, TelegramError, User, GroupChat, Updater
from telegram.dispatcher import run_async
2015-11-21 15:48:45 +01:00
from tests.base import BaseTest
2015-11-21 23:09:44 +01:00
from threading import Lock, Thread
# Enable logging
root = logging.getLogger()
root.setLevel(logging.INFO)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.WARN)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
root.addHandler(ch)
2015-11-24 21:06:55 +01:00
class UpdaterTest(BaseTest, unittest.TestCase):
"""
This object represents Tests for Updater, Dispatcher, WebhookServer and
WebhookHandler
"""
def setUp(self):
2015-11-22 19:16:49 +01:00
self.updater = Updater('', workers=2)
self.received_message = None
self.message_count = 0
2015-11-21 19:35:24 +01:00
self.lock = Lock()
2015-11-21 15:45:45 +01:00
def tearDown(self):
2015-11-22 19:16:49 +01:00
self.updater.stop()
2015-11-21 15:45:45 +01:00
2015-11-24 20:34:38 +01:00
def reset(self):
self.message_count = 0
self.received_message = None
def telegramHandlerTest(self, bot, update):
self.received_message = update.message.text
self.message_count += 1
2015-11-21 19:35:24 +01:00
@run_async
def asyncHandlerTest(self, bot, update):
sleep(1)
with self.lock:
self.received_message = update.message.text
self.message_count += 1
def stringHandlerTest(self, bot, update):
self.received_message = update
self.message_count += 1
2015-11-22 14:08:33 +01:00
def additionalArgsTest(self, bot, update, update_queue, args):
self.received_message = update
self.message_count += 1
if args[0] == 'resend':
update_queue.put('/test5 noresend')
elif args[0] == 'noresend':
pass
def errorRaisingHandlerTest(self, bot, update):
raise TelegramError(update)
2015-11-21 15:45:45 +01:00
def errorHandlerTest(self, bot, update, error):
self.received_message = error.message
2015-11-21 15:45:45 +01:00
self.message_count += 1
2015-11-24 20:34:38 +01:00
def test_addRemoveTelegramMessageHandler(self):
print('Testing add/removeTelegramMessageHandler')
bot = MockBot('Test')
self.updater.bot = bot
d = self.updater.dispatcher
d.addTelegramMessageHandler(
self.telegramHandlerTest)
self.updater.start_polling(0.01)
sleep(.1)
self.assertEqual(self.received_message, 'Test')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeTelegramMessageHandler(self.telegramHandlerTest)
self.reset()
bot.send_messages = 1
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addTelegramMessageHandlerMultipleMessages(self):
print('Testing addTelegramMessageHandler and send 100 messages...')
2015-11-22 19:16:49 +01:00
self.updater.bot = MockBot('Multiple', 100)
self.updater.dispatcher.addTelegramMessageHandler(
self.telegramHandlerTest)
2015-11-22 19:16:49 +01:00
self.updater.start_polling(0.0)
sleep(.5)
self.assertEqual(self.received_message, 'Multiple')
self.assertEqual(self.message_count, 100)
2015-11-24 20:34:38 +01:00
def test_addRemoveTelegramRegexHandler(self):
print('Testing add/removeStringRegexHandler')
bot = MockBot('Test2')
self.updater.bot = bot
d = self.updater.dispatcher
regobj = re.compile('Te.*')
self.updater.dispatcher.addTelegramRegexHandler(regobj,
2015-11-22 19:16:49 +01:00
self.telegramHandlerTest)
self.updater.start_polling(0.01)
sleep(.1)
self.assertEqual(self.received_message, 'Test2')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeTelegramRegexHandler(regobj, self.telegramHandlerTest)
self.reset()
bot.send_messages = 1
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveTelegramCommandHandler(self):
print('Testing add/removeTelegramCommandHandler')
bot = MockBot('/test')
self.updater.bot = bot
d = self.updater.dispatcher
2015-11-22 19:16:49 +01:00
self.updater.dispatcher.addTelegramCommandHandler(
'test', self.telegramHandlerTest)
self.updater.start_polling(0.01)
sleep(.1)
self.assertEqual(self.received_message, '/test')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeTelegramCommandHandler('test', self.telegramHandlerTest)
self.reset()
bot.send_messages = 1
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveUnknownTelegramCommandHandler(self):
print('Testing add/removeUnknownTelegramCommandHandler')
bot = MockBot('/test2')
self.updater.bot = bot
d = self.updater.dispatcher
2015-11-22 19:16:49 +01:00
self.updater.dispatcher.addUnknownTelegramCommandHandler(
self.telegramHandlerTest)
self.updater.start_polling(0.01)
sleep(.1)
self.assertEqual(self.received_message, '/test2')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeUnknownTelegramCommandHandler(self.telegramHandlerTest)
self.reset()
bot.send_messages = 1
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveStringRegexHandler(self):
print('Testing add/removeStringRegexHandler')
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addStringRegexHandler('Te.*', self.stringHandlerTest)
queue = self.updater.start_polling(0.01)
queue.put('Test3')
sleep(.1)
self.assertEqual(self.received_message, 'Test3')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeStringRegexHandler('Te.*', self.stringHandlerTest)
self.reset()
queue.put('Test3')
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveStringCommandHandler(self):
print('Testing add/removeStringCommandHandler')
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addStringCommandHandler(
'test3', self.stringHandlerTest)
queue = self.updater.start_polling(0.01)
queue.put('/test3')
sleep(.1)
self.assertEqual(self.received_message, '/test3')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeStringCommandHandler('test3', self.stringHandlerTest)
self.reset()
queue.put('/test3')
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveUnknownStringCommandHandler(self):
print('Testing add/removeUnknownStringCommandHandler')
bot = MockBot('/test')
self.updater.bot = bot
d = self.updater.dispatcher
d.addUnknownStringCommandHandler(
self.stringHandlerTest)
queue = self.updater.start_polling(0.01)
queue.put('/test4')
sleep(.1)
self.assertEqual(self.received_message, '/test4')
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeUnknownStringCommandHandler(self.stringHandlerTest)
self.reset()
bot.send_messages = 1
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_addRemoveErrorHandler(self):
print('Testing add/removeErrorHandler')
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addErrorHandler(self.errorHandlerTest)
queue = self.updater.start_polling(0.01)
error = TelegramError("Unauthorized.")
queue.put(error)
sleep(.1)
self.assertEqual(self.received_message, "Unauthorized.")
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeErrorHandler(self.errorHandlerTest)
self.reset()
queue.put(error)
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
def test_errorInHandler(self):
print('Testing error in Handler')
2015-11-24 20:34:38 +01:00
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addStringRegexHandler('.*',
self.errorRaisingHandlerTest)
self.updater.dispatcher.addErrorHandler(self.errorHandlerTest)
queue = self.updater.start_polling(0.01)
queue.put('Test Error 1')
sleep(.1)
self.assertEqual(self.received_message, 'Test Error 1')
def test_errorOnGetUpdates(self):
print('Testing error on getUpdates')
2015-11-24 20:34:38 +01:00
bot = MockBot('', raise_error=True)
self.updater.bot = bot
d = self.updater.dispatcher
d.addErrorHandler(self.errorHandlerTest)
self.updater.start_polling(0.01)
sleep(.1)
self.assertEqual(self.received_message, "Test Error 2")
2015-11-24 20:34:38 +01:00
def test_addRemoveTypeHandler(self):
print('Testing add/removeTypeHandler')
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addTypeHandler(dict, self.stringHandlerTest)
queue = self.updater.start_polling(0.01)
payload = {"Test": 42}
queue.put(payload)
sleep(.1)
self.assertEqual(self.received_message, payload)
2015-11-24 20:34:38 +01:00
# Remove handler
d.removeTypeHandler(dict, self.stringHandlerTest)
self.reset()
queue.put(payload)
sleep(.1)
self.assertTrue(None is self.received_message)
2015-11-24 20:34:38 +01:00
2015-11-21 19:35:24 +01:00
def test_runAsync(self):
print('Testing @run_async')
2015-11-24 20:34:38 +01:00
bot = MockBot('Test5', messages=2)
self.updater.bot = bot
d = self.updater.dispatcher
d.addTelegramMessageHandler(
2015-11-21 19:35:24 +01:00
self.asyncHandlerTest)
2015-11-22 19:16:49 +01:00
self.updater.start_polling(0.01)
2015-11-21 19:35:24 +01:00
sleep(1.2)
self.assertEqual(self.received_message, 'Test5')
2015-11-21 19:35:24 +01:00
self.assertEqual(self.message_count, 2)
2015-11-22 14:08:33 +01:00
def test_additionalArgs(self):
print('Testing additional arguments for handlers')
self.updater.bot = MockBot('', messages=0)
2015-11-22 19:16:49 +01:00
self.updater.dispatcher.addStringCommandHandler(
2015-11-22 14:08:33 +01:00
'test5', self.additionalArgsTest)
queue = self.updater.start_polling(0.01)
2015-11-22 14:08:33 +01:00
queue.put('/test5 resend')
sleep(.1)
2015-11-22 14:08:33 +01:00
self.assertEqual(self.received_message, '/test5 noresend')
self.assertEqual(self.message_count, 2)
def test_webhook(self):
2015-11-21 23:09:44 +01:00
print('Testing Webhook')
2015-11-24 20:34:38 +01:00
bot = MockBot('', messages=0)
self.updater.bot = bot
d = self.updater.dispatcher
d.addTelegramMessageHandler(
self.telegramHandlerTest)
# Select random port for travis
port = randrange(1024, 49152)
2015-11-22 19:16:49 +01:00
self.updater.start_webhook('127.0.0.1', port,
2015-11-24 21:06:55 +01:00
'./tests/test_updater.py',
'./tests/test_updater.py',
2015-11-22 19:16:49 +01:00
listen='127.0.0.1')
2015-11-21 23:09:44 +01:00
sleep(0.5)
# SSL-Wrapping will fail, so we start the server without SSL
2015-11-22 19:16:49 +01:00
Thread(target=self.updater.httpd.serve_forever).start()
2015-11-21 23:09:44 +01:00
# Now, we send an update to the server via urlopen
message = Message(1, User(1, "Tester"), datetime.now(),
GroupChat(1, "Test Group"))
2015-11-21 23:09:44 +01:00
message.text = "Webhook Test"
update = Update(1)
update.message = message
try:
payload = bytes(update.to_json(), encoding='utf-8')
except TypeError:
payload = bytes(update.to_json())
2015-11-21 23:09:44 +01:00
header = {
'content-type': 'application/json',
'content-length': str(len(payload))
}
r = Request('http://127.0.0.1:%d/TOKEN' % port,
data=payload,
headers=header)
2015-11-21 23:09:44 +01:00
urlopen(r)
sleep(1)
self.assertEqual(self.received_message, 'Webhook Test')
print("Test other webhook server functionalites...")
request = Request('http://localhost:%d/webookhandler.py' % port)
response = urlopen(request)
self.assertEqual(b'', response.read())
self.assertEqual(200, response.code)
request.get_method = lambda: 'HEAD'
response = urlopen(request)
self.assertEqual(b'', response.read())
self.assertEqual(200, response.code)
# Test multiple shutdown() calls
self.updater.httpd.shutdown()
self.updater.httpd.shutdown()
self.assertTrue(True)
2015-11-24 14:57:54 +01:00
def signalsender(self):
sleep(0.5)
os.kill(os.getpid(), signal.SIGTERM)
def test_idle(self):
print('Testing idle')
self.updater.bot = MockBot('Test6', messages=0)
2015-11-24 14:57:54 +01:00
self.updater.start_polling(poll_interval=0.01)
Thread(target=self.signalsender).start()
self.updater.idle()
# If we get this far, idle() ran through
sleep(1)
self.updater.running = False
class MockBot:
def __init__(self, text, messages=1, raise_error=False):
self.text = text
self.send_messages = messages
self.raise_error = raise_error
self.token = "TOKEN"
pass
2015-11-24 21:06:55 +01:00
@staticmethod
def mockUpdate(text):
message = Message(0, None, None, None)
message.text = text
update = Update(0)
update.message = message
return update
2015-11-21 15:50:39 +01:00
def setWebhook(self, webhook_url=None, certificate=None):
2015-11-21 15:48:45 +01:00
pass
2015-11-21 15:45:45 +01:00
def getUpdates(self,
offset=None,
limit=100,
timeout=0,
network_delay=2.):
if self.raise_error:
raise TelegramError('Test Error 2')
elif self.send_messages >= 2:
self.send_messages -= 2
return self.mockUpdate(self.text), self.mockUpdate(self.text)
elif self.send_messages == 1:
self.send_messages -= 1
return self.mockUpdate(self.text),
else:
return []
if __name__ == '__main__':
unittest.main()