From 6d5c3187fc34342716fd8ca63eb77cec5a3309a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Mon, 4 Jan 2016 17:31:06 +0100 Subject: [PATCH 01/34] Initial commit for inline bot support --- docs/source/telegram.choseninlineresult.rst | 7 + docs/source/telegram.inlinequery.rst | 7 + docs/source/telegram.inlinequeryresult.rst | 7 + docs/source/telegram.rst | 3 + examples/inlinebot.py | 106 +++++ telegram/__init__.py | 9 +- telegram/bot.py | 50 +++ telegram/choseninlineresult.py | 79 ++++ telegram/dispatcher.py | 61 ++- telegram/inlinequery.py | 82 ++++ telegram/inlinequeryresult.py | 410 ++++++++++++++++++++ telegram/update.py | 15 +- 12 files changed, 818 insertions(+), 18 deletions(-) create mode 100644 docs/source/telegram.choseninlineresult.rst create mode 100644 docs/source/telegram.inlinequery.rst create mode 100644 docs/source/telegram.inlinequeryresult.rst create mode 100644 examples/inlinebot.py create mode 100644 telegram/choseninlineresult.py create mode 100644 telegram/inlinequery.py create mode 100644 telegram/inlinequeryresult.py diff --git a/docs/source/telegram.choseninlineresult.rst b/docs/source/telegram.choseninlineresult.rst new file mode 100644 index 000000000..45ea766c9 --- /dev/null +++ b/docs/source/telegram.choseninlineresult.rst @@ -0,0 +1,7 @@ +telegram.choseninlineresult module +================================== + +.. automodule:: telegram.choseninlineresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequery.rst b/docs/source/telegram.inlinequery.rst new file mode 100644 index 000000000..fd7c90efc --- /dev/null +++ b/docs/source/telegram.inlinequery.rst @@ -0,0 +1,7 @@ +telegram.inlinequery module +=========================== + +.. automodule:: telegram.inlinequery + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequeryresult.rst b/docs/source/telegram.inlinequeryresult.rst new file mode 100644 index 000000000..1daeba325 --- /dev/null +++ b/docs/source/telegram.inlinequeryresult.rst @@ -0,0 +1,7 @@ +telegram.inlinequeryresult module +================================= + +.. automodule:: telegram.inlinequeryresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.rst b/docs/source/telegram.rst index e08c0dee9..793ad6d2b 100644 --- a/docs/source/telegram.rst +++ b/docs/source/telegram.rst @@ -12,6 +12,9 @@ Submodules telegram.updater telegram.dispatcher telegram.jobqueue + telegram.inlinequery + telegram.inlinequeryresult + telegram.choseninlineresult telegram.chataction telegram.contact telegram.document diff --git a/examples/inlinebot.py b/examples/inlinebot.py new file mode 100644 index 000000000..f7bce001a --- /dev/null +++ b/examples/inlinebot.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Simple Bot to reply to Telegram messages +# This program is dedicated to the public domain under the CC0 license. + +""" +This Bot uses the Updater class to handle the bot. + +First, a few handler functions are defined. Then, those functions are passed to +the Dispatcher and registered at their respective places. +Then, the bot is started and runs until we press Ctrl-C on the command line. + +Usage: +Basic inline bot example. Applies different text transformations. +Press Ctrl-C on the command line or send a signal to the process to stop the +bot. +""" +from random import getrandbits + +import re + +from telegram import Updater, Update, InlineQueryResultArticle, ParseMode +import logging + +# Enable logging +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.INFO) + +logger = logging.getLogger(__name__) + + +# Define a few command handlers. These usually take the two arguments bot and +# update. Error handlers also receive the raised TelegramError object in error. +def start(bot, update): + bot.sendMessage(update.message.chat_id, text='Hi!') + + +def help(bot, update): + bot.sendMessage(update.message.chat_id, text='Help!') + + +def escape_markdown(text): + """Helper function to escape telegram markup symbols""" + escape_chars = '\*_`\[' + return re.sub(r'([%s])' % escape_chars, r'\\\1', text) + + +def inlinequery(bot, update): + if update.inline_query is not None and update.inline_query.query: + query = update.inline_query.query + results = list() + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Caps", + message_text=query.upper())) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Bold", + message_text="*%s*" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Italic", + message_text="_%s_" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + bot.answerInlineQuery(update.inline_query.id, results=results) + + + +def error(bot, update, error): + logger.warn('Update "%s" caused error "%s"' % (update, error)) + + +def main(): + # Create the Updater and pass it your bot's token. + updater = Updater("TOKEN") + + # Get the dispatcher to register handlers + dp = updater.dispatcher + + # on different commands - answer in Telegram + dp.addTelegramCommandHandler("start", start) + dp.addTelegramCommandHandler("help", help) + + # on noncommand i.e message - echo the message on Telegram + dp.addTelegramInlineHandler(inlinequery) + + # log all errors + dp.addErrorHandler(error) + + # Start the Bot + updater.start_polling() + + # Block until the user presses Ctrl-C or the process receives SIGINT, + # SIGTERM or SIGABRT. This should be used most of the time, since + # start_polling() is non-blocking and will stop the bot gracefully. + updater.idle() + +if __name__ == '__main__': + main() diff --git a/telegram/__init__.py b/telegram/__init__.py index 12b2ec193..357c57213 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -45,6 +45,10 @@ from .nullhandler import NullHandler from .emoji import Emoji from .parsemode import ParseMode from .message import Message +from .inlinequery import InlineQuery +from .choseninlineresult import ChosenInlineResult +from .inlinequeryresult import InlineQueryResultArticle, InlineQueryResultGif,\ + InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, InlineQueryResultVideo from .update import Update from .bot import Bot from .dispatcher import Dispatcher @@ -56,4 +60,7 @@ __all__ = ['Bot', 'Updater', 'Dispatcher', 'Emoji', 'TelegramError', 'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction', 'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize', 'Chat', 'Update', 'ParseMode', 'Message', - 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue'] + 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue', + 'InlineQuery', 'ChosenInlineResult', 'InlineQueryResultArticle', + 'InlineQueryResultGif', 'InlineQueryResultPhoto', + 'InlineQueryResultMpeg4Gif', 'InlineQueryResultVideo'] diff --git a/telegram/bot.py b/telegram/bot.py index e520cb5b4..476d18ed0 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -583,6 +583,56 @@ class Bot(TelegramObject): return url, data + @log + def answerInlineQuery(self, + inline_query_id, + results, + cache_time=None, + is_personal=None, + next_offset=None): + """Use this method to reply to an inline query. + + Args: + inline_query_id (int): + Unique identifier for answered query + results (list[InlineQueryResult]): + A list of results for the inline query + + Keyword Args: + cache_time (Optional[int]): The maximum amount of time the result + of the inline query may be cached on the server + is_personal (Optional[bool]): Pass True, if results may be cached + on the server side only for the user that sent the query. By + default, results may be returned to any user who sends the same + query + next_offset (Optional[str]): Pass the offset that a client should + send in the next query with the same text to receive more + results. Pass an empty string if there are no more results or + if you don't support pagination. Offset length can't exceed 64 + bytes. + + Returns: + A boolean if answering was successful + """ + + url = '%s/answerInlineQuery' % self.base_url + + results = [res.to_dict() for res in results] + + data = {'inline_query_id': inline_query_id, + 'results': results} + + if cache_time is not None: + data['cache_time'] = cache_time + if is_personal is not None: + data['is_personal'] = is_personal + if next_offset is not None: + data['next_offset'] = next_offset + + result = request.post(url, data) + + return result + @log def getUserProfilePhotos(self, user_id, diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py new file mode 100644 index 000000000..03b0f4d25 --- /dev/null +++ b/telegram/choseninlineresult.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains a object that represents a Telegram ChosenInlineResult +""" + + +from telegram import TelegramObject + + +class ChosenInlineResult(TelegramObject): + """This object represents a Telegram ChosenInlineResult. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + Args: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + """ + + def __init__(self, + result_id, + from_user, + query): + # Required + self.result_id = int(result_id) + self.from_user = from_user + self.query = query + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.ChosenInlineResult: + """ + if not data: + return None + + return ChosenInlineResult(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(ChosenInlineResult, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/dispatcher.py b/telegram/dispatcher.py index defe6aff6..3752d6bec 100644 --- a/telegram/dispatcher.py +++ b/telegram/dispatcher.py @@ -128,6 +128,7 @@ class Dispatcher: self.bot = bot self.update_queue = update_queue self.telegram_message_handlers = [] + self.telegram_inline_handlers = [] self.telegram_command_handlers = {} self.telegram_regex_handlers = {} self.string_regex_handlers = {} @@ -232,21 +233,23 @@ class Dispatcher: handled = True # Telegram update (regex) - if isinstance(update, Update): + if isinstance(update, Update) and update.message is not None: self.dispatchRegex(update) handled = True - # Telegram update (command) - if isinstance(update, Update) \ - and update.message.text.startswith('/'): - self.dispatchTelegramCommand(update) - handled = True - - # Telegram update (message) - elif isinstance(update, Update): - self.dispatchTelegramMessage(update) - handled = True + # Telegram update (command) + if update.message.text.startswith('/'): + self.dispatchTelegramCommand(update) + # Telegram update (message) + else: + self.dispatchTelegramMessage(update) + handled = True + elif isinstance(update, Update) and \ + (update.inline_query is not None or + update.chosen_inline_result is not None): + self.dispatchTelegramInline(update) + handled = True # Update not recognized if not handled: self.dispatchError(update, TelegramError( @@ -264,6 +267,17 @@ class Dispatcher: self.telegram_message_handlers.append(handler) + def addTelegramInlineHandler(self, handler): + """ + Registers an inline query handler in the Dispatcher. + + Args: + handler (function): A function that takes (Bot, Update, *args) as + arguments. + """ + + self.telegram_inline_handlers.append(handler) + def addTelegramCommandHandler(self, command, handler): """ Registers a command handler in the Dispatcher. @@ -393,6 +407,17 @@ class Dispatcher: if handler in self.telegram_message_handlers: self.telegram_message_handlers.remove(handler) + def removeTelegramInlineHandler(self, handler): + """ + De-registers an inline query handler. + + Args: + handler (any): + """ + + if handler in self.telegram_inline_handlers: + self.telegram_inline_handlers.remove(handler) + def removeTelegramCommandHandler(self, command, handler): """ De-registers a command handler. @@ -558,9 +583,6 @@ class Dispatcher: for t in self.type_handlers: if isinstance(update, t): self.dispatchTo(self.type_handlers[t], update) - else: - self.dispatchError(update, TelegramError( - "Received update of unknown type %s" % type(update))) def dispatchTelegramMessage(self, update): """ @@ -573,6 +595,17 @@ class Dispatcher: self.dispatchTo(self.telegram_message_handlers, update) + def dispatchTelegramInline(self, update): + """ + Dispatches an update that contains an inline update. + + Args: + update (telegram.Update): The Telegram update that contains the + message. + """ + + self.dispatchTo(self.telegram_inline_handlers, update) + def dispatchError(self, update, error): """ Dispatches an error. diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py new file mode 100644 index 000000000..7a365a632 --- /dev/null +++ b/telegram/inlinequery.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +"""This module contains a object that represents a Telegram InlineQuery""" + +from telegram import TelegramObject, User + + +class InlineQuery(TelegramObject): + """This object represents a Telegram InlineQuery. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + Args: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + """ + + def __init__(self, + id, + from_user, + query, + offset): + # Required + self.id = int(id) + self.from_user = from_user + self.query = query + self.offset = offset + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQuery: + """ + if not data: + return None + + data['from_user'] = User.de_json(data.pop('from')) + + return InlineQuery(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(InlineQuery, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py new file mode 100644 index 000000000..b2c03229a --- /dev/null +++ b/telegram/inlinequeryresult.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains the classes that represent Telegram InlineQueryResults +""" + +from telegram import TelegramObject + + +class InlineQueryResult(TelegramObject): + """This object represents a Telegram InlineQueryResult. + + Attributes: + type (str): + id (str): + + Args: + type (str): + id (str): + + """ + + def __init__(self, + type, + id): + # Required + self.type = str(type) + self.id = str(id) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResult: + """ + if not data: + return None + + return InlineQueryResult(**data) + + +class InlineQueryResultArticle(InlineQueryResult): + """This object represents a Telegram InlineQueryResultArticle. + + Attributes: + id (str): + title (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + url (str): + hide_url (bool): + description (str): + thumb_url (str): + thumb_width (int): + thumb_height (int): + + Args: + id (str): + title (str): + message_text (str): + + Keyword Args: + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + url (Optional[str]): + hide_url (Optional[bool]): + description (Optional[str]): + thumb_url (Optional[str]): + thumb_width (Optional[int]): + thumb_height (Optional[int]): + """ + + def __init__(self, + id, + title, + message_text, + **kwargs): + # Required + super(InlineQueryResultArticle, self).__init__('article', id) + self.title = title + self.message_text = message_text + + # Optional + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + self.url = kwargs.get('url', '') + self.hide_url = kwargs.get('hide_url', False) + self.description = kwargs.get('description', '') + self.thumb_url = kwargs.get('thumb_url', '') + self.parse_mode = kwargs.get('parse_mode', '') + if 'thumb_width' in kwargs: + self.thumb_width = int(kwargs['thumb_width']) + if 'thumb_height' in kwargs: + self.thumb_height = int(kwargs['thumb_height']) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultArticle: + """ + if not data: + return None + + return InlineQueryResultArticle(**data) + + +class InlineQueryResultPhoto(InlineQueryResult): + """This object represents a Telegram InlineQueryResultPhoto. + + Attributes: + id (str): + photo_url (str): + mime_type (str): + photo_width (int): + photo_height (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + photo_url (str): + + Keyword Args: + mime_type (Optional[str]): + photo_width (Optional[int]): + photo_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + photo_url, + **kwargs): + # Required + super(InlineQueryResultPhoto, self).__init__('photo', id) + self.photo_url = photo_url + + # Optional + self.mime_type = kwargs.get('mime_type', 'image/jpeg') + if 'photo_width' in kwargs: + self.photo_width = int(kwargs['photo_width']) + if 'photo_height' in kwargs: + self.photo_height = int(kwargs['photo_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultPhoto: + """ + if not data: + return None + + return InlineQueryResultPhoto(**data) + + +class InlineQueryResultGif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultGif. + + Attributes: + id (str): + gif_url (str): + gif_width (int): + gif_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + gif_url (str): + + Keyword Args: + gif_width (Optional[int]): + gif_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + gif_url, + **kwargs): + # Required + super(InlineQueryResultGif, self).__init__('gif', id) + self.gif_url = gif_url + + # Optional + if 'gif_width' in kwargs: + self.gif_width = int(kwargs['gif_width']) + if 'gif_height' in kwargs: + self.gif_height = int(kwargs['gif_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultGif: + """ + if not data: + return None + + return InlineQueryResultGif(**data) + + +class InlineQueryResultMpeg4Gif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultMpeg4Gif. + + Attributes: + id (str): + mpeg4_url (str): + mpeg4_width (int): + mpeg4_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + mpeg4_url (str): + + Keyword Args: + mpeg4_width (Optional[int]): + mpeg4_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + mpeg4_url, + **kwargs): + # Required + super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) + self.mpeg4_url = mpeg4_url + + # Optional + if 'mpeg4_width' in kwargs: + self.mpeg4_width = int(kwargs['mpeg4_width']) + if 'mpeg4_height' in kwargs: + self.mpeg4_height = int(kwargs['mpeg4_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultMpeg4Gif: + """ + if not data: + return None + + return InlineQueryResultMpeg4Gif(**data) + + +class InlineQueryResultVideo(InlineQueryResult): + """This object represents a Telegram InlineQueryResultVideo. + + Attributes: + id (str): + video_url (str): + mime_type (str): + video_width (int): + video_height (int): + video_duration (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + video_url (str): + mime_type (str): + + Keyword Args: + video_width (Optional[int]): + video_height (Optional[int]): + video_duration (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + video_url, + mime_type, + **kwargs): + # Required + super(InlineQueryResultVideo, self).__init__('video', id) + self.video_url = video_url + self.mime_type = mime_type + + # Optional + if 'video_width' in kwargs: + self.video_width = int(kwargs['video_width']) + if 'video_height' in kwargs: + self.video_height = int(kwargs['video_height']) + if 'video_duration' in kwargs: + self.video_duration = int(kwargs['video_duration']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultVideo: + """ + if not data: + return None + + return InlineQueryResultVideo(**data) diff --git a/telegram/update.py b/telegram/update.py index fc8d15d6d..db508e243 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -18,7 +18,7 @@ """This module contains a object that represents a Telegram Update""" -from telegram import Message, TelegramObject +from telegram import Message, TelegramObject, InlineQuery, ChosenInlineResult class Update(TelegramObject): @@ -27,6 +27,8 @@ class Update(TelegramObject): Attributes: update_id (int): message (:class:`telegram.Message`): + inline_query (:class:`telegram.InlineQuery`): + chosen_inline_result (:class:`telegram.ChosenInlineResult`): Args: update_id (int): @@ -34,6 +36,8 @@ class Update(TelegramObject): Keyword Args: message (Optional[:class:`telegram.Message`]): + inline_query (Optional[:class:`telegram.InlineQuery`]): + chosen_inline_result (Optional[:class:`telegram.ChosenInlineResult`]) """ def __init__(self, update_id, @@ -42,12 +46,14 @@ class Update(TelegramObject): self.update_id = int(update_id) # Optionals self.message = kwargs.get('message') + self.inline_query = kwargs.get('inline_query') + self.chosen_inline_result = kwargs.get('chosen_inline_result') @staticmethod def de_json(data): """ Args: - data (str): + data (dict): Returns: telegram.Update: @@ -55,6 +61,9 @@ class Update(TelegramObject): if not data: return None - data['message'] = Message.de_json(data['message']) + data['message'] = Message.de_json(data.get('message')) + data['inline_query'] = InlineQuery.de_json(data.get('inline_query')) + data['chosen_inline_result'] = \ + ChosenInlineResult.de_json(data.get('chosen_inline_result')) return Update(**data) From e2e98e86dbb5645d947bea371a95736699e33552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Mon, 4 Jan 2016 17:31:06 +0100 Subject: [PATCH 02/34] Initial commit for inline bot support --- docs/source/telegram.choseninlineresult.rst | 7 + docs/source/telegram.inlinequery.rst | 7 + docs/source/telegram.inlinequeryresult.rst | 7 + docs/source/telegram.rst | 3 + examples/inlinebot.py | 106 +++++ telegram/__init__.py | 9 +- telegram/bot.py | 50 +++ telegram/choseninlineresult.py | 79 ++++ telegram/dispatcher.py | 58 ++- telegram/inlinequery.py | 82 ++++ telegram/inlinequeryresult.py | 410 ++++++++++++++++++++ telegram/update.py | 15 +- 12 files changed, 818 insertions(+), 15 deletions(-) create mode 100644 docs/source/telegram.choseninlineresult.rst create mode 100644 docs/source/telegram.inlinequery.rst create mode 100644 docs/source/telegram.inlinequeryresult.rst create mode 100644 examples/inlinebot.py create mode 100644 telegram/choseninlineresult.py create mode 100644 telegram/inlinequery.py create mode 100644 telegram/inlinequeryresult.py diff --git a/docs/source/telegram.choseninlineresult.rst b/docs/source/telegram.choseninlineresult.rst new file mode 100644 index 000000000..45ea766c9 --- /dev/null +++ b/docs/source/telegram.choseninlineresult.rst @@ -0,0 +1,7 @@ +telegram.choseninlineresult module +================================== + +.. automodule:: telegram.choseninlineresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequery.rst b/docs/source/telegram.inlinequery.rst new file mode 100644 index 000000000..fd7c90efc --- /dev/null +++ b/docs/source/telegram.inlinequery.rst @@ -0,0 +1,7 @@ +telegram.inlinequery module +=========================== + +.. automodule:: telegram.inlinequery + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequeryresult.rst b/docs/source/telegram.inlinequeryresult.rst new file mode 100644 index 000000000..1daeba325 --- /dev/null +++ b/docs/source/telegram.inlinequeryresult.rst @@ -0,0 +1,7 @@ +telegram.inlinequeryresult module +================================= + +.. automodule:: telegram.inlinequeryresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.rst b/docs/source/telegram.rst index e08c0dee9..793ad6d2b 100644 --- a/docs/source/telegram.rst +++ b/docs/source/telegram.rst @@ -12,6 +12,9 @@ Submodules telegram.updater telegram.dispatcher telegram.jobqueue + telegram.inlinequery + telegram.inlinequeryresult + telegram.choseninlineresult telegram.chataction telegram.contact telegram.document diff --git a/examples/inlinebot.py b/examples/inlinebot.py new file mode 100644 index 000000000..f7bce001a --- /dev/null +++ b/examples/inlinebot.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Simple Bot to reply to Telegram messages +# This program is dedicated to the public domain under the CC0 license. + +""" +This Bot uses the Updater class to handle the bot. + +First, a few handler functions are defined. Then, those functions are passed to +the Dispatcher and registered at their respective places. +Then, the bot is started and runs until we press Ctrl-C on the command line. + +Usage: +Basic inline bot example. Applies different text transformations. +Press Ctrl-C on the command line or send a signal to the process to stop the +bot. +""" +from random import getrandbits + +import re + +from telegram import Updater, Update, InlineQueryResultArticle, ParseMode +import logging + +# Enable logging +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.INFO) + +logger = logging.getLogger(__name__) + + +# Define a few command handlers. These usually take the two arguments bot and +# update. Error handlers also receive the raised TelegramError object in error. +def start(bot, update): + bot.sendMessage(update.message.chat_id, text='Hi!') + + +def help(bot, update): + bot.sendMessage(update.message.chat_id, text='Help!') + + +def escape_markdown(text): + """Helper function to escape telegram markup symbols""" + escape_chars = '\*_`\[' + return re.sub(r'([%s])' % escape_chars, r'\\\1', text) + + +def inlinequery(bot, update): + if update.inline_query is not None and update.inline_query.query: + query = update.inline_query.query + results = list() + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Caps", + message_text=query.upper())) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Bold", + message_text="*%s*" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Italic", + message_text="_%s_" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + bot.answerInlineQuery(update.inline_query.id, results=results) + + + +def error(bot, update, error): + logger.warn('Update "%s" caused error "%s"' % (update, error)) + + +def main(): + # Create the Updater and pass it your bot's token. + updater = Updater("TOKEN") + + # Get the dispatcher to register handlers + dp = updater.dispatcher + + # on different commands - answer in Telegram + dp.addTelegramCommandHandler("start", start) + dp.addTelegramCommandHandler("help", help) + + # on noncommand i.e message - echo the message on Telegram + dp.addTelegramInlineHandler(inlinequery) + + # log all errors + dp.addErrorHandler(error) + + # Start the Bot + updater.start_polling() + + # Block until the user presses Ctrl-C or the process receives SIGINT, + # SIGTERM or SIGABRT. This should be used most of the time, since + # start_polling() is non-blocking and will stop the bot gracefully. + updater.idle() + +if __name__ == '__main__': + main() diff --git a/telegram/__init__.py b/telegram/__init__.py index d35258811..3da751e35 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -46,6 +46,10 @@ from .nullhandler import NullHandler from .emoji import Emoji from .parsemode import ParseMode from .message import Message +from .inlinequery import InlineQuery +from .choseninlineresult import ChosenInlineResult +from .inlinequeryresult import InlineQueryResultArticle, InlineQueryResultGif,\ + InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, InlineQueryResultVideo from .update import Update from .bot import Bot from .dispatcher import Dispatcher @@ -57,4 +61,7 @@ __all__ = ['Bot', 'Updater', 'Dispatcher', 'Emoji', 'TelegramError', 'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction', 'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize', 'Chat', 'Update', 'ParseMode', 'Message', - 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue'] + 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue', + 'InlineQuery', 'ChosenInlineResult', 'InlineQueryResultArticle', + 'InlineQueryResultGif', 'InlineQueryResultPhoto', + 'InlineQueryResultMpeg4Gif', 'InlineQueryResultVideo'] diff --git a/telegram/bot.py b/telegram/bot.py index d7080798b..c7af027eb 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -584,6 +584,56 @@ class Bot(TelegramObject): return url, data + @log + def answerInlineQuery(self, + inline_query_id, + results, + cache_time=None, + is_personal=None, + next_offset=None): + """Use this method to reply to an inline query. + + Args: + inline_query_id (int): + Unique identifier for answered query + results (list[InlineQueryResult]): + A list of results for the inline query + + Keyword Args: + cache_time (Optional[int]): The maximum amount of time the result + of the inline query may be cached on the server + is_personal (Optional[bool]): Pass True, if results may be cached + on the server side only for the user that sent the query. By + default, results may be returned to any user who sends the same + query + next_offset (Optional[str]): Pass the offset that a client should + send in the next query with the same text to receive more + results. Pass an empty string if there are no more results or + if you don't support pagination. Offset length can't exceed 64 + bytes. + + Returns: + A boolean if answering was successful + """ + + url = '%s/answerInlineQuery' % self.base_url + + results = [res.to_dict() for res in results] + + data = {'inline_query_id': inline_query_id, + 'results': results} + + if cache_time is not None: + data['cache_time'] = cache_time + if is_personal is not None: + data['is_personal'] = is_personal + if next_offset is not None: + data['next_offset'] = next_offset + + result = request.post(url, data) + + return result + @log def getUserProfilePhotos(self, user_id, diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py new file mode 100644 index 000000000..03b0f4d25 --- /dev/null +++ b/telegram/choseninlineresult.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains a object that represents a Telegram ChosenInlineResult +""" + + +from telegram import TelegramObject + + +class ChosenInlineResult(TelegramObject): + """This object represents a Telegram ChosenInlineResult. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + Args: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + """ + + def __init__(self, + result_id, + from_user, + query): + # Required + self.result_id = int(result_id) + self.from_user = from_user + self.query = query + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.ChosenInlineResult: + """ + if not data: + return None + + return ChosenInlineResult(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(ChosenInlineResult, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/dispatcher.py b/telegram/dispatcher.py index 07ea8ecbc..d888597b3 100644 --- a/telegram/dispatcher.py +++ b/telegram/dispatcher.py @@ -130,6 +130,7 @@ class Dispatcher: self.bot = bot self.update_queue = update_queue self.telegram_message_handlers = [] + self.telegram_inline_handlers = [] self.telegram_command_handlers = {} self.telegram_regex_handlers = {} self.string_regex_handlers = {} @@ -236,21 +237,23 @@ class Dispatcher: handled = True # Telegram update (regex) - if isinstance(update, Update): + if isinstance(update, Update) and update.message is not None: self.dispatchRegex(update) handled = True - # Telegram update (command) - if isinstance(update, Update) \ - and update.message.text.startswith('/'): - self.dispatchTelegramCommand(update) - handled = True - - # Telegram update (message) - elif isinstance(update, Update): - self.dispatchTelegramMessage(update) - handled = True + # Telegram update (command) + if update.message.text.startswith('/'): + self.dispatchTelegramCommand(update) + # Telegram update (message) + else: + self.dispatchTelegramMessage(update) + handled = True + elif isinstance(update, Update) and \ + (update.inline_query is not None or + update.chosen_inline_result is not None): + self.dispatchTelegramInline(update) + handled = True # Update not recognized if not handled: self.dispatchError(update, TelegramError( @@ -268,6 +271,17 @@ class Dispatcher: self.telegram_message_handlers.append(handler) + def addTelegramInlineHandler(self, handler): + """ + Registers an inline query handler in the Dispatcher. + + Args: + handler (function): A function that takes (Bot, Update, *args) as + arguments. + """ + + self.telegram_inline_handlers.append(handler) + def addTelegramCommandHandler(self, command, handler): """ Registers a command handler in the Dispatcher. @@ -397,6 +411,17 @@ class Dispatcher: if handler in self.telegram_message_handlers: self.telegram_message_handlers.remove(handler) + def removeTelegramInlineHandler(self, handler): + """ + De-registers an inline query handler. + + Args: + handler (any): + """ + + if handler in self.telegram_inline_handlers: + self.telegram_inline_handlers.remove(handler) + def removeTelegramCommandHandler(self, command, handler): """ De-registers a command handler. @@ -574,6 +599,17 @@ class Dispatcher: self.dispatchTo(self.telegram_message_handlers, update) + def dispatchTelegramInline(self, update): + """ + Dispatches an update that contains an inline update. + + Args: + update (telegram.Update): The Telegram update that contains the + message. + """ + + self.dispatchTo(self.telegram_inline_handlers, update) + def dispatchError(self, update, error): """ Dispatches an error. diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py new file mode 100644 index 000000000..7a365a632 --- /dev/null +++ b/telegram/inlinequery.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +"""This module contains a object that represents a Telegram InlineQuery""" + +from telegram import TelegramObject, User + + +class InlineQuery(TelegramObject): + """This object represents a Telegram InlineQuery. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + Args: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + """ + + def __init__(self, + id, + from_user, + query, + offset): + # Required + self.id = int(id) + self.from_user = from_user + self.query = query + self.offset = offset + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQuery: + """ + if not data: + return None + + data['from_user'] = User.de_json(data.pop('from')) + + return InlineQuery(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(InlineQuery, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py new file mode 100644 index 000000000..b2c03229a --- /dev/null +++ b/telegram/inlinequeryresult.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains the classes that represent Telegram InlineQueryResults +""" + +from telegram import TelegramObject + + +class InlineQueryResult(TelegramObject): + """This object represents a Telegram InlineQueryResult. + + Attributes: + type (str): + id (str): + + Args: + type (str): + id (str): + + """ + + def __init__(self, + type, + id): + # Required + self.type = str(type) + self.id = str(id) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResult: + """ + if not data: + return None + + return InlineQueryResult(**data) + + +class InlineQueryResultArticle(InlineQueryResult): + """This object represents a Telegram InlineQueryResultArticle. + + Attributes: + id (str): + title (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + url (str): + hide_url (bool): + description (str): + thumb_url (str): + thumb_width (int): + thumb_height (int): + + Args: + id (str): + title (str): + message_text (str): + + Keyword Args: + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + url (Optional[str]): + hide_url (Optional[bool]): + description (Optional[str]): + thumb_url (Optional[str]): + thumb_width (Optional[int]): + thumb_height (Optional[int]): + """ + + def __init__(self, + id, + title, + message_text, + **kwargs): + # Required + super(InlineQueryResultArticle, self).__init__('article', id) + self.title = title + self.message_text = message_text + + # Optional + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + self.url = kwargs.get('url', '') + self.hide_url = kwargs.get('hide_url', False) + self.description = kwargs.get('description', '') + self.thumb_url = kwargs.get('thumb_url', '') + self.parse_mode = kwargs.get('parse_mode', '') + if 'thumb_width' in kwargs: + self.thumb_width = int(kwargs['thumb_width']) + if 'thumb_height' in kwargs: + self.thumb_height = int(kwargs['thumb_height']) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultArticle: + """ + if not data: + return None + + return InlineQueryResultArticle(**data) + + +class InlineQueryResultPhoto(InlineQueryResult): + """This object represents a Telegram InlineQueryResultPhoto. + + Attributes: + id (str): + photo_url (str): + mime_type (str): + photo_width (int): + photo_height (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + photo_url (str): + + Keyword Args: + mime_type (Optional[str]): + photo_width (Optional[int]): + photo_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + photo_url, + **kwargs): + # Required + super(InlineQueryResultPhoto, self).__init__('photo', id) + self.photo_url = photo_url + + # Optional + self.mime_type = kwargs.get('mime_type', 'image/jpeg') + if 'photo_width' in kwargs: + self.photo_width = int(kwargs['photo_width']) + if 'photo_height' in kwargs: + self.photo_height = int(kwargs['photo_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultPhoto: + """ + if not data: + return None + + return InlineQueryResultPhoto(**data) + + +class InlineQueryResultGif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultGif. + + Attributes: + id (str): + gif_url (str): + gif_width (int): + gif_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + gif_url (str): + + Keyword Args: + gif_width (Optional[int]): + gif_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + gif_url, + **kwargs): + # Required + super(InlineQueryResultGif, self).__init__('gif', id) + self.gif_url = gif_url + + # Optional + if 'gif_width' in kwargs: + self.gif_width = int(kwargs['gif_width']) + if 'gif_height' in kwargs: + self.gif_height = int(kwargs['gif_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultGif: + """ + if not data: + return None + + return InlineQueryResultGif(**data) + + +class InlineQueryResultMpeg4Gif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultMpeg4Gif. + + Attributes: + id (str): + mpeg4_url (str): + mpeg4_width (int): + mpeg4_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + mpeg4_url (str): + + Keyword Args: + mpeg4_width (Optional[int]): + mpeg4_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + mpeg4_url, + **kwargs): + # Required + super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) + self.mpeg4_url = mpeg4_url + + # Optional + if 'mpeg4_width' in kwargs: + self.mpeg4_width = int(kwargs['mpeg4_width']) + if 'mpeg4_height' in kwargs: + self.mpeg4_height = int(kwargs['mpeg4_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultMpeg4Gif: + """ + if not data: + return None + + return InlineQueryResultMpeg4Gif(**data) + + +class InlineQueryResultVideo(InlineQueryResult): + """This object represents a Telegram InlineQueryResultVideo. + + Attributes: + id (str): + video_url (str): + mime_type (str): + video_width (int): + video_height (int): + video_duration (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + video_url (str): + mime_type (str): + + Keyword Args: + video_width (Optional[int]): + video_height (Optional[int]): + video_duration (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + video_url, + mime_type, + **kwargs): + # Required + super(InlineQueryResultVideo, self).__init__('video', id) + self.video_url = video_url + self.mime_type = mime_type + + # Optional + if 'video_width' in kwargs: + self.video_width = int(kwargs['video_width']) + if 'video_height' in kwargs: + self.video_height = int(kwargs['video_height']) + if 'video_duration' in kwargs: + self.video_duration = int(kwargs['video_duration']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultVideo: + """ + if not data: + return None + + return InlineQueryResultVideo(**data) diff --git a/telegram/update.py b/telegram/update.py index 4df1076d3..2ba169b11 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -19,7 +19,7 @@ """This module contains a object that represents a Telegram Update""" -from telegram import Message, TelegramObject +from telegram import Message, TelegramObject, InlineQuery, ChosenInlineResult class Update(TelegramObject): @@ -28,6 +28,8 @@ class Update(TelegramObject): Attributes: update_id (int): message (:class:`telegram.Message`): + inline_query (:class:`telegram.InlineQuery`): + chosen_inline_result (:class:`telegram.ChosenInlineResult`): Args: update_id (int): @@ -35,6 +37,8 @@ class Update(TelegramObject): Keyword Args: message (Optional[:class:`telegram.Message`]): + inline_query (Optional[:class:`telegram.InlineQuery`]): + chosen_inline_result (Optional[:class:`telegram.ChosenInlineResult`]) """ def __init__(self, update_id, @@ -43,12 +47,14 @@ class Update(TelegramObject): self.update_id = int(update_id) # Optionals self.message = kwargs.get('message') + self.inline_query = kwargs.get('inline_query') + self.chosen_inline_result = kwargs.get('chosen_inline_result') @staticmethod def de_json(data): """ Args: - data (str): + data (dict): Returns: telegram.Update: @@ -56,6 +62,9 @@ class Update(TelegramObject): if not data: return None - data['message'] = Message.de_json(data['message']) + data['message'] = Message.de_json(data.get('message')) + data['inline_query'] = InlineQuery.de_json(data.get('inline_query')) + data['chosen_inline_result'] = \ + ChosenInlineResult.de_json(data.get('chosen_inline_result')) return Update(**data) From 77ca036d021e98a9a184c4c7942f9e2c0f256e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sat, 9 Jan 2016 14:42:47 +0100 Subject: [PATCH 03/34] update inline query results after api change --- telegram/inlinequeryresult.py | 42 ++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py index b2c03229a..3c0e4b36b 100644 --- a/telegram/inlinequeryresult.py +++ b/telegram/inlinequeryresult.py @@ -32,7 +32,7 @@ class InlineQueryResult(TelegramObject): Args: type (str): - id (str): + id (str): Unique identifier for this result, 1-64 Bytes """ @@ -75,7 +75,7 @@ class InlineQueryResultArticle(InlineQueryResult): thumb_height (int): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes title (str): message_text (str): @@ -147,14 +147,14 @@ class InlineQueryResultPhoto(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes photo_url (str): + thumb_url (str): Keyword Args: mime_type (Optional[str]): photo_width (Optional[int]): photo_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): description (Optional[str]): caption (Optional[str]): @@ -166,10 +166,12 @@ class InlineQueryResultPhoto(InlineQueryResult): def __init__(self, id, photo_url, + thumb_url, **kwargs): # Required super(InlineQueryResultPhoto, self).__init__('photo', id) self.photo_url = photo_url + self.thumb_url = thumb_url # Optional self.mime_type = kwargs.get('mime_type', 'image/jpeg') @@ -177,7 +179,6 @@ class InlineQueryResultPhoto(InlineQueryResult): self.photo_width = int(kwargs['photo_width']) if 'photo_height' in kwargs: self.photo_height = int(kwargs['photo_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.description = kwargs.get('description', '') self.caption = kwargs.get('caption', '') @@ -217,13 +218,13 @@ class InlineQueryResultGif(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes gif_url (str): + thumb_url (str): Keyword Args: gif_width (Optional[int]): gif_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): caption (Optional[str]): message_text (Optional[str]): @@ -234,17 +235,18 @@ class InlineQueryResultGif(InlineQueryResult): def __init__(self, id, gif_url, + thumb_url, **kwargs): # Required super(InlineQueryResultGif, self).__init__('gif', id) self.gif_url = gif_url + self.thumb_url = thumb_url # Optional if 'gif_width' in kwargs: self.gif_width = int(kwargs['gif_width']) if 'gif_height' in kwargs: self.gif_height = int(kwargs['gif_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.caption = kwargs.get('caption', '') self.message_text = kwargs.get('message_text', '') @@ -283,13 +285,13 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes mpeg4_url (str): + thumb_url (str): Keyword Args: mpeg4_width (Optional[int]): mpeg4_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): caption (Optional[str]): message_text (Optional[str]): @@ -300,17 +302,18 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): def __init__(self, id, mpeg4_url, + thumb_url, **kwargs): # Required super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) self.mpeg4_url = mpeg4_url + self.thumb_url = thumb_url # Optional if 'mpeg4_width' in kwargs: self.mpeg4_width = int(kwargs['mpeg4_width']) if 'mpeg4_height' in kwargs: self.mpeg4_height = int(kwargs['mpeg4_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.caption = kwargs.get('caption', '') self.message_text = kwargs.get('message_text', '') @@ -352,19 +355,19 @@ class InlineQueryResultVideo(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes video_url (str): mime_type (str): + thumb_url (str): + title (str): + message_text (str): Keyword Args: video_width (Optional[int]): video_height (Optional[int]): video_duration (Optional[int]): - thumb_url (Optional[str]): - title (Optional[str]): description (Optional[str]): caption (Optional[str]): - message_text (Optional[str]): parse_mode (Optional[str]): disable_web_page_preview (Optional[bool]): """ @@ -373,11 +376,17 @@ class InlineQueryResultVideo(InlineQueryResult): id, video_url, mime_type, + thumb_url, + title, + message_text, **kwargs): # Required super(InlineQueryResultVideo, self).__init__('video', id) self.video_url = video_url self.mime_type = mime_type + self.thumb_url = thumb_url + self.title = title + self.message_text = message_text # Optional if 'video_width' in kwargs: @@ -386,11 +395,8 @@ class InlineQueryResultVideo(InlineQueryResult): self.video_height = int(kwargs['video_height']) if 'video_duration' in kwargs: self.video_duration = int(kwargs['video_duration']) - self.thumb_url = kwargs.get('thumb_url', '') - self.title = kwargs.get('title', '') self.description = kwargs.get('description', '') self.caption = kwargs.get('caption', '') - self.message_text = kwargs.get('message_text', '') self.parse_mode = kwargs.get('parse_mode', '') self.disable_web_page_preview = kwargs.get('disable_web_page_preview', False) From c69cdfd1846c43fda0cdcda30369c8551f4e257a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Mon, 4 Jan 2016 17:31:06 +0100 Subject: [PATCH 04/34] Initial commit for inline bot support --- docs/source/telegram.choseninlineresult.rst | 7 + docs/source/telegram.inlinequery.rst | 7 + docs/source/telegram.inlinequeryresult.rst | 7 + docs/source/telegram.rst | 3 + examples/inlinebot.py | 106 +++++ telegram/__init__.py | 9 +- telegram/bot.py | 50 +++ telegram/choseninlineresult.py | 79 ++++ telegram/dispatcher.py | 58 ++- telegram/inlinequery.py | 82 ++++ telegram/inlinequeryresult.py | 410 ++++++++++++++++++++ telegram/update.py | 15 +- 12 files changed, 818 insertions(+), 15 deletions(-) create mode 100644 docs/source/telegram.choseninlineresult.rst create mode 100644 docs/source/telegram.inlinequery.rst create mode 100644 docs/source/telegram.inlinequeryresult.rst create mode 100644 examples/inlinebot.py create mode 100644 telegram/choseninlineresult.py create mode 100644 telegram/inlinequery.py create mode 100644 telegram/inlinequeryresult.py diff --git a/docs/source/telegram.choseninlineresult.rst b/docs/source/telegram.choseninlineresult.rst new file mode 100644 index 000000000..45ea766c9 --- /dev/null +++ b/docs/source/telegram.choseninlineresult.rst @@ -0,0 +1,7 @@ +telegram.choseninlineresult module +================================== + +.. automodule:: telegram.choseninlineresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequery.rst b/docs/source/telegram.inlinequery.rst new file mode 100644 index 000000000..fd7c90efc --- /dev/null +++ b/docs/source/telegram.inlinequery.rst @@ -0,0 +1,7 @@ +telegram.inlinequery module +=========================== + +.. automodule:: telegram.inlinequery + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.inlinequeryresult.rst b/docs/source/telegram.inlinequeryresult.rst new file mode 100644 index 000000000..1daeba325 --- /dev/null +++ b/docs/source/telegram.inlinequeryresult.rst @@ -0,0 +1,7 @@ +telegram.inlinequeryresult module +================================= + +.. automodule:: telegram.inlinequeryresult + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.rst b/docs/source/telegram.rst index e08c0dee9..793ad6d2b 100644 --- a/docs/source/telegram.rst +++ b/docs/source/telegram.rst @@ -12,6 +12,9 @@ Submodules telegram.updater telegram.dispatcher telegram.jobqueue + telegram.inlinequery + telegram.inlinequeryresult + telegram.choseninlineresult telegram.chataction telegram.contact telegram.document diff --git a/examples/inlinebot.py b/examples/inlinebot.py new file mode 100644 index 000000000..f7bce001a --- /dev/null +++ b/examples/inlinebot.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Simple Bot to reply to Telegram messages +# This program is dedicated to the public domain under the CC0 license. + +""" +This Bot uses the Updater class to handle the bot. + +First, a few handler functions are defined. Then, those functions are passed to +the Dispatcher and registered at their respective places. +Then, the bot is started and runs until we press Ctrl-C on the command line. + +Usage: +Basic inline bot example. Applies different text transformations. +Press Ctrl-C on the command line or send a signal to the process to stop the +bot. +""" +from random import getrandbits + +import re + +from telegram import Updater, Update, InlineQueryResultArticle, ParseMode +import logging + +# Enable logging +logging.basicConfig( + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=logging.INFO) + +logger = logging.getLogger(__name__) + + +# Define a few command handlers. These usually take the two arguments bot and +# update. Error handlers also receive the raised TelegramError object in error. +def start(bot, update): + bot.sendMessage(update.message.chat_id, text='Hi!') + + +def help(bot, update): + bot.sendMessage(update.message.chat_id, text='Help!') + + +def escape_markdown(text): + """Helper function to escape telegram markup symbols""" + escape_chars = '\*_`\[' + return re.sub(r'([%s])' % escape_chars, r'\\\1', text) + + +def inlinequery(bot, update): + if update.inline_query is not None and update.inline_query.query: + query = update.inline_query.query + results = list() + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Caps", + message_text=query.upper())) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Bold", + message_text="*%s*" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + results.append(InlineQueryResultArticle( + id=hex(getrandbits(64))[2:], + title="Italic", + message_text="_%s_" % escape_markdown(query), + parse_mode=ParseMode.MARKDOWN)) + + bot.answerInlineQuery(update.inline_query.id, results=results) + + + +def error(bot, update, error): + logger.warn('Update "%s" caused error "%s"' % (update, error)) + + +def main(): + # Create the Updater and pass it your bot's token. + updater = Updater("TOKEN") + + # Get the dispatcher to register handlers + dp = updater.dispatcher + + # on different commands - answer in Telegram + dp.addTelegramCommandHandler("start", start) + dp.addTelegramCommandHandler("help", help) + + # on noncommand i.e message - echo the message on Telegram + dp.addTelegramInlineHandler(inlinequery) + + # log all errors + dp.addErrorHandler(error) + + # Start the Bot + updater.start_polling() + + # Block until the user presses Ctrl-C or the process receives SIGINT, + # SIGTERM or SIGABRT. This should be used most of the time, since + # start_polling() is non-blocking and will stop the bot gracefully. + updater.idle() + +if __name__ == '__main__': + main() diff --git a/telegram/__init__.py b/telegram/__init__.py index d35258811..3da751e35 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -46,6 +46,10 @@ from .nullhandler import NullHandler from .emoji import Emoji from .parsemode import ParseMode from .message import Message +from .inlinequery import InlineQuery +from .choseninlineresult import ChosenInlineResult +from .inlinequeryresult import InlineQueryResultArticle, InlineQueryResultGif,\ + InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, InlineQueryResultVideo from .update import Update from .bot import Bot from .dispatcher import Dispatcher @@ -57,4 +61,7 @@ __all__ = ['Bot', 'Updater', 'Dispatcher', 'Emoji', 'TelegramError', 'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction', 'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File', 'Audio', 'PhotoSize', 'Chat', 'Update', 'ParseMode', 'Message', - 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue'] + 'User', 'TelegramObject', 'NullHandler', 'Voice', 'JobQueue', + 'InlineQuery', 'ChosenInlineResult', 'InlineQueryResultArticle', + 'InlineQueryResultGif', 'InlineQueryResultPhoto', + 'InlineQueryResultMpeg4Gif', 'InlineQueryResultVideo'] diff --git a/telegram/bot.py b/telegram/bot.py index d7080798b..c7af027eb 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -584,6 +584,56 @@ class Bot(TelegramObject): return url, data + @log + def answerInlineQuery(self, + inline_query_id, + results, + cache_time=None, + is_personal=None, + next_offset=None): + """Use this method to reply to an inline query. + + Args: + inline_query_id (int): + Unique identifier for answered query + results (list[InlineQueryResult]): + A list of results for the inline query + + Keyword Args: + cache_time (Optional[int]): The maximum amount of time the result + of the inline query may be cached on the server + is_personal (Optional[bool]): Pass True, if results may be cached + on the server side only for the user that sent the query. By + default, results may be returned to any user who sends the same + query + next_offset (Optional[str]): Pass the offset that a client should + send in the next query with the same text to receive more + results. Pass an empty string if there are no more results or + if you don't support pagination. Offset length can't exceed 64 + bytes. + + Returns: + A boolean if answering was successful + """ + + url = '%s/answerInlineQuery' % self.base_url + + results = [res.to_dict() for res in results] + + data = {'inline_query_id': inline_query_id, + 'results': results} + + if cache_time is not None: + data['cache_time'] = cache_time + if is_personal is not None: + data['is_personal'] = is_personal + if next_offset is not None: + data['next_offset'] = next_offset + + result = request.post(url, data) + + return result + @log def getUserProfilePhotos(self, user_id, diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py new file mode 100644 index 000000000..03b0f4d25 --- /dev/null +++ b/telegram/choseninlineresult.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains a object that represents a Telegram ChosenInlineResult +""" + + +from telegram import TelegramObject + + +class ChosenInlineResult(TelegramObject): + """This object represents a Telegram ChosenInlineResult. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + Args: + result_id (int): + from_user (:class:`telegram.User`): + query (str): + + """ + + def __init__(self, + result_id, + from_user, + query): + # Required + self.result_id = int(result_id) + self.from_user = from_user + self.query = query + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.ChosenInlineResult: + """ + if not data: + return None + + return ChosenInlineResult(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(ChosenInlineResult, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/dispatcher.py b/telegram/dispatcher.py index 07ea8ecbc..d888597b3 100644 --- a/telegram/dispatcher.py +++ b/telegram/dispatcher.py @@ -130,6 +130,7 @@ class Dispatcher: self.bot = bot self.update_queue = update_queue self.telegram_message_handlers = [] + self.telegram_inline_handlers = [] self.telegram_command_handlers = {} self.telegram_regex_handlers = {} self.string_regex_handlers = {} @@ -236,21 +237,23 @@ class Dispatcher: handled = True # Telegram update (regex) - if isinstance(update, Update): + if isinstance(update, Update) and update.message is not None: self.dispatchRegex(update) handled = True - # Telegram update (command) - if isinstance(update, Update) \ - and update.message.text.startswith('/'): - self.dispatchTelegramCommand(update) - handled = True - - # Telegram update (message) - elif isinstance(update, Update): - self.dispatchTelegramMessage(update) - handled = True + # Telegram update (command) + if update.message.text.startswith('/'): + self.dispatchTelegramCommand(update) + # Telegram update (message) + else: + self.dispatchTelegramMessage(update) + handled = True + elif isinstance(update, Update) and \ + (update.inline_query is not None or + update.chosen_inline_result is not None): + self.dispatchTelegramInline(update) + handled = True # Update not recognized if not handled: self.dispatchError(update, TelegramError( @@ -268,6 +271,17 @@ class Dispatcher: self.telegram_message_handlers.append(handler) + def addTelegramInlineHandler(self, handler): + """ + Registers an inline query handler in the Dispatcher. + + Args: + handler (function): A function that takes (Bot, Update, *args) as + arguments. + """ + + self.telegram_inline_handlers.append(handler) + def addTelegramCommandHandler(self, command, handler): """ Registers a command handler in the Dispatcher. @@ -397,6 +411,17 @@ class Dispatcher: if handler in self.telegram_message_handlers: self.telegram_message_handlers.remove(handler) + def removeTelegramInlineHandler(self, handler): + """ + De-registers an inline query handler. + + Args: + handler (any): + """ + + if handler in self.telegram_inline_handlers: + self.telegram_inline_handlers.remove(handler) + def removeTelegramCommandHandler(self, command, handler): """ De-registers a command handler. @@ -574,6 +599,17 @@ class Dispatcher: self.dispatchTo(self.telegram_message_handlers, update) + def dispatchTelegramInline(self, update): + """ + Dispatches an update that contains an inline update. + + Args: + update (telegram.Update): The Telegram update that contains the + message. + """ + + self.dispatchTo(self.telegram_inline_handlers, update) + def dispatchError(self, update, error): """ Dispatches an error. diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py new file mode 100644 index 000000000..7a365a632 --- /dev/null +++ b/telegram/inlinequery.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# pylint: disable=R0902,R0912,R0913 +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +"""This module contains a object that represents a Telegram InlineQuery""" + +from telegram import TelegramObject, User + + +class InlineQuery(TelegramObject): + """This object represents a Telegram InlineQuery. + + Note: + * In Python `from` is a reserved word, use `from_user` instead. + + Attributes: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + Args: + id (int): + from_user (:class:`telegram.User`): + query (str): + offset (str): + + """ + + def __init__(self, + id, + from_user, + query, + offset): + # Required + self.id = int(id) + self.from_user = from_user + self.query = query + self.offset = offset + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQuery: + """ + if not data: + return None + + data['from_user'] = User.de_json(data.pop('from')) + + return InlineQuery(**data) + + def to_dict(self): + """ + Returns: + dict: + """ + data = super(InlineQuery, self).to_dict() + + # Required + data['from'] = data.pop('from_user', None) + + return data diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py new file mode 100644 index 000000000..b2c03229a --- /dev/null +++ b/telegram/inlinequeryresult.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015 Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +""" +This module contains the classes that represent Telegram InlineQueryResults +""" + +from telegram import TelegramObject + + +class InlineQueryResult(TelegramObject): + """This object represents a Telegram InlineQueryResult. + + Attributes: + type (str): + id (str): + + Args: + type (str): + id (str): + + """ + + def __init__(self, + type, + id): + # Required + self.type = str(type) + self.id = str(id) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResult: + """ + if not data: + return None + + return InlineQueryResult(**data) + + +class InlineQueryResultArticle(InlineQueryResult): + """This object represents a Telegram InlineQueryResultArticle. + + Attributes: + id (str): + title (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + url (str): + hide_url (bool): + description (str): + thumb_url (str): + thumb_width (int): + thumb_height (int): + + Args: + id (str): + title (str): + message_text (str): + + Keyword Args: + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + url (Optional[str]): + hide_url (Optional[bool]): + description (Optional[str]): + thumb_url (Optional[str]): + thumb_width (Optional[int]): + thumb_height (Optional[int]): + """ + + def __init__(self, + id, + title, + message_text, + **kwargs): + # Required + super(InlineQueryResultArticle, self).__init__('article', id) + self.title = title + self.message_text = message_text + + # Optional + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + self.url = kwargs.get('url', '') + self.hide_url = kwargs.get('hide_url', False) + self.description = kwargs.get('description', '') + self.thumb_url = kwargs.get('thumb_url', '') + self.parse_mode = kwargs.get('parse_mode', '') + if 'thumb_width' in kwargs: + self.thumb_width = int(kwargs['thumb_width']) + if 'thumb_height' in kwargs: + self.thumb_height = int(kwargs['thumb_height']) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultArticle: + """ + if not data: + return None + + return InlineQueryResultArticle(**data) + + +class InlineQueryResultPhoto(InlineQueryResult): + """This object represents a Telegram InlineQueryResultPhoto. + + Attributes: + id (str): + photo_url (str): + mime_type (str): + photo_width (int): + photo_height (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + photo_url (str): + + Keyword Args: + mime_type (Optional[str]): + photo_width (Optional[int]): + photo_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + photo_url, + **kwargs): + # Required + super(InlineQueryResultPhoto, self).__init__('photo', id) + self.photo_url = photo_url + + # Optional + self.mime_type = kwargs.get('mime_type', 'image/jpeg') + if 'photo_width' in kwargs: + self.photo_width = int(kwargs['photo_width']) + if 'photo_height' in kwargs: + self.photo_height = int(kwargs['photo_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultPhoto: + """ + if not data: + return None + + return InlineQueryResultPhoto(**data) + + +class InlineQueryResultGif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultGif. + + Attributes: + id (str): + gif_url (str): + gif_width (int): + gif_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + gif_url (str): + + Keyword Args: + gif_width (Optional[int]): + gif_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + gif_url, + **kwargs): + # Required + super(InlineQueryResultGif, self).__init__('gif', id) + self.gif_url = gif_url + + # Optional + if 'gif_width' in kwargs: + self.gif_width = int(kwargs['gif_width']) + if 'gif_height' in kwargs: + self.gif_height = int(kwargs['gif_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultGif: + """ + if not data: + return None + + return InlineQueryResultGif(**data) + + +class InlineQueryResultMpeg4Gif(InlineQueryResult): + """This object represents a Telegram InlineQueryResultMpeg4Gif. + + Attributes: + id (str): + mpeg4_url (str): + mpeg4_width (int): + mpeg4_height (int): + thumb_url (str): + title (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + mpeg4_url (str): + + Keyword Args: + mpeg4_width (Optional[int]): + mpeg4_height (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + mpeg4_url, + **kwargs): + # Required + super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) + self.mpeg4_url = mpeg4_url + + # Optional + if 'mpeg4_width' in kwargs: + self.mpeg4_width = int(kwargs['mpeg4_width']) + if 'mpeg4_height' in kwargs: + self.mpeg4_height = int(kwargs['mpeg4_height']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultMpeg4Gif: + """ + if not data: + return None + + return InlineQueryResultMpeg4Gif(**data) + + +class InlineQueryResultVideo(InlineQueryResult): + """This object represents a Telegram InlineQueryResultVideo. + + Attributes: + id (str): + video_url (str): + mime_type (str): + video_width (int): + video_height (int): + video_duration (int): + thumb_url (str): + title (str): + description (str): + caption (str): + message_text (str): + parse_mode (str): + disable_web_page_preview (bool): + + Args: + id (str): + video_url (str): + mime_type (str): + + Keyword Args: + video_width (Optional[int]): + video_height (Optional[int]): + video_duration (Optional[int]): + thumb_url (Optional[str]): + title (Optional[str]): + description (Optional[str]): + caption (Optional[str]): + message_text (Optional[str]): + parse_mode (Optional[str]): + disable_web_page_preview (Optional[bool]): + """ + + def __init__(self, + id, + video_url, + mime_type, + **kwargs): + # Required + super(InlineQueryResultVideo, self).__init__('video', id) + self.video_url = video_url + self.mime_type = mime_type + + # Optional + if 'video_width' in kwargs: + self.video_width = int(kwargs['video_width']) + if 'video_height' in kwargs: + self.video_height = int(kwargs['video_height']) + if 'video_duration' in kwargs: + self.video_duration = int(kwargs['video_duration']) + self.thumb_url = kwargs.get('thumb_url', '') + self.title = kwargs.get('title', '') + self.description = kwargs.get('description', '') + self.caption = kwargs.get('caption', '') + self.message_text = kwargs.get('message_text', '') + self.parse_mode = kwargs.get('parse_mode', '') + self.disable_web_page_preview = kwargs.get('disable_web_page_preview', + False) + + @staticmethod + def de_json(data): + """ + Args: + data (dict): + + Returns: + telegram.InlineQueryResultVideo: + """ + if not data: + return None + + return InlineQueryResultVideo(**data) diff --git a/telegram/update.py b/telegram/update.py index 4df1076d3..2ba169b11 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -19,7 +19,7 @@ """This module contains a object that represents a Telegram Update""" -from telegram import Message, TelegramObject +from telegram import Message, TelegramObject, InlineQuery, ChosenInlineResult class Update(TelegramObject): @@ -28,6 +28,8 @@ class Update(TelegramObject): Attributes: update_id (int): message (:class:`telegram.Message`): + inline_query (:class:`telegram.InlineQuery`): + chosen_inline_result (:class:`telegram.ChosenInlineResult`): Args: update_id (int): @@ -35,6 +37,8 @@ class Update(TelegramObject): Keyword Args: message (Optional[:class:`telegram.Message`]): + inline_query (Optional[:class:`telegram.InlineQuery`]): + chosen_inline_result (Optional[:class:`telegram.ChosenInlineResult`]) """ def __init__(self, update_id, @@ -43,12 +47,14 @@ class Update(TelegramObject): self.update_id = int(update_id) # Optionals self.message = kwargs.get('message') + self.inline_query = kwargs.get('inline_query') + self.chosen_inline_result = kwargs.get('chosen_inline_result') @staticmethod def de_json(data): """ Args: - data (str): + data (dict): Returns: telegram.Update: @@ -56,6 +62,9 @@ class Update(TelegramObject): if not data: return None - data['message'] = Message.de_json(data['message']) + data['message'] = Message.de_json(data.get('message')) + data['inline_query'] = InlineQuery.de_json(data.get('inline_query')) + data['chosen_inline_result'] = \ + ChosenInlineResult.de_json(data.get('chosen_inline_result')) return Update(**data) From 6ece89bc561f9ab1b7f3ff5a77503afd5c7d2a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sat, 9 Jan 2016 14:42:47 +0100 Subject: [PATCH 05/34] update inline query results after api change --- telegram/inlinequeryresult.py | 42 ++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py index b2c03229a..3c0e4b36b 100644 --- a/telegram/inlinequeryresult.py +++ b/telegram/inlinequeryresult.py @@ -32,7 +32,7 @@ class InlineQueryResult(TelegramObject): Args: type (str): - id (str): + id (str): Unique identifier for this result, 1-64 Bytes """ @@ -75,7 +75,7 @@ class InlineQueryResultArticle(InlineQueryResult): thumb_height (int): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes title (str): message_text (str): @@ -147,14 +147,14 @@ class InlineQueryResultPhoto(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes photo_url (str): + thumb_url (str): Keyword Args: mime_type (Optional[str]): photo_width (Optional[int]): photo_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): description (Optional[str]): caption (Optional[str]): @@ -166,10 +166,12 @@ class InlineQueryResultPhoto(InlineQueryResult): def __init__(self, id, photo_url, + thumb_url, **kwargs): # Required super(InlineQueryResultPhoto, self).__init__('photo', id) self.photo_url = photo_url + self.thumb_url = thumb_url # Optional self.mime_type = kwargs.get('mime_type', 'image/jpeg') @@ -177,7 +179,6 @@ class InlineQueryResultPhoto(InlineQueryResult): self.photo_width = int(kwargs['photo_width']) if 'photo_height' in kwargs: self.photo_height = int(kwargs['photo_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.description = kwargs.get('description', '') self.caption = kwargs.get('caption', '') @@ -217,13 +218,13 @@ class InlineQueryResultGif(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes gif_url (str): + thumb_url (str): Keyword Args: gif_width (Optional[int]): gif_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): caption (Optional[str]): message_text (Optional[str]): @@ -234,17 +235,18 @@ class InlineQueryResultGif(InlineQueryResult): def __init__(self, id, gif_url, + thumb_url, **kwargs): # Required super(InlineQueryResultGif, self).__init__('gif', id) self.gif_url = gif_url + self.thumb_url = thumb_url # Optional if 'gif_width' in kwargs: self.gif_width = int(kwargs['gif_width']) if 'gif_height' in kwargs: self.gif_height = int(kwargs['gif_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.caption = kwargs.get('caption', '') self.message_text = kwargs.get('message_text', '') @@ -283,13 +285,13 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes mpeg4_url (str): + thumb_url (str): Keyword Args: mpeg4_width (Optional[int]): mpeg4_height (Optional[int]): - thumb_url (Optional[str]): title (Optional[str]): caption (Optional[str]): message_text (Optional[str]): @@ -300,17 +302,18 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): def __init__(self, id, mpeg4_url, + thumb_url, **kwargs): # Required super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) self.mpeg4_url = mpeg4_url + self.thumb_url = thumb_url # Optional if 'mpeg4_width' in kwargs: self.mpeg4_width = int(kwargs['mpeg4_width']) if 'mpeg4_height' in kwargs: self.mpeg4_height = int(kwargs['mpeg4_height']) - self.thumb_url = kwargs.get('thumb_url', '') self.title = kwargs.get('title', '') self.caption = kwargs.get('caption', '') self.message_text = kwargs.get('message_text', '') @@ -352,19 +355,19 @@ class InlineQueryResultVideo(InlineQueryResult): disable_web_page_preview (bool): Args: - id (str): + id (str): Unique identifier for this result, 1-64 Bytes video_url (str): mime_type (str): + thumb_url (str): + title (str): + message_text (str): Keyword Args: video_width (Optional[int]): video_height (Optional[int]): video_duration (Optional[int]): - thumb_url (Optional[str]): - title (Optional[str]): description (Optional[str]): caption (Optional[str]): - message_text (Optional[str]): parse_mode (Optional[str]): disable_web_page_preview (Optional[bool]): """ @@ -373,11 +376,17 @@ class InlineQueryResultVideo(InlineQueryResult): id, video_url, mime_type, + thumb_url, + title, + message_text, **kwargs): # Required super(InlineQueryResultVideo, self).__init__('video', id) self.video_url = video_url self.mime_type = mime_type + self.thumb_url = thumb_url + self.title = title + self.message_text = message_text # Optional if 'video_width' in kwargs: @@ -386,11 +395,8 @@ class InlineQueryResultVideo(InlineQueryResult): self.video_height = int(kwargs['video_height']) if 'video_duration' in kwargs: self.video_duration = int(kwargs['video_duration']) - self.thumb_url = kwargs.get('thumb_url', '') - self.title = kwargs.get('title', '') self.description = kwargs.get('description', '') self.caption = kwargs.get('caption', '') - self.message_text = kwargs.get('message_text', '') self.parse_mode = kwargs.get('parse_mode', '') self.disable_web_page_preview = kwargs.get('disable_web_page_preview', False) From 48c1673d7ce4e05a162d85ee33cd4cdb3135b498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sat, 9 Jan 2016 15:30:47 +0100 Subject: [PATCH 06/34] fix additional args for inline queries --- telegram/dispatcher.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/telegram/dispatcher.py b/telegram/dispatcher.py index d888597b3..6674f9af4 100644 --- a/telegram/dispatcher.py +++ b/telegram/dispatcher.py @@ -108,6 +108,8 @@ class Dispatcher: a list that contains the content of the message split on spaces, except the first word (usually the command). Example: '/add item1 item2 item3' -> ['item1', 'item2', 'item3'] + For updates that contain inline queries, they will contain the + whole query split on spaces. For other updates, args will be None For regex-based handlers, you can also request information about the match. @@ -658,8 +660,10 @@ class Dispatcher: target_kwargs['update_queue'] = self.update_queue if is_async or 'args' in fargs: - if isinstance(update, Update): + if isinstance(update, Update) and update.message: args = update.message.text.split(' ')[1:] + elif isinstance(update, Update) and update.inline_query: + args = update.inline_query.query.split(' ') elif isinstance(update, str): args = update.split(' ')[1:] else: From 5fd7a4fe0d57e504f22e64c61d549de681a26186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sat, 9 Jan 2016 15:50:19 +0100 Subject: [PATCH 07/34] release v3.3b1 --- CHANGES.rst | 6 ++++++ docs/source/conf.py | 4 ++-- setup.py | 2 +- telegram/__init__.py | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 07db7988d..7b4c47e69 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +**2016-01-09** + +*Released 3.3b1* + +- Implement inline bots (beta) + **2016-01-05** *Released 3.2.0* diff --git a/docs/source/conf.py b/docs/source/conf.py index 067dd71bd..8b2feea43 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -58,9 +58,9 @@ author = u'Leandro Toledo' # built documents. # # The short X.Y version. -version = '3.2' +version = '3.3' # The full version, including alpha/beta/rc tags. -release = '3.2.0' +release = '3.3b1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index e0cc49c0a..09d198297 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def requirements(): setup( name='python-telegram-bot', - version='3.2.0', + version='3.3b1', author='Leandro Toledo', author_email='devs@python-telegram-bot.org', license='LGPLv3', diff --git a/telegram/__init__.py b/telegram/__init__.py index 3da751e35..bab9c04f4 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -20,7 +20,7 @@ """A library that provides a Python interface to the Telegram Bot API""" __author__ = 'devs@python-telegram-bot.org' -__version__ = '3.2.0' +__version__ = '3.3b1' from .base import TelegramObject from .user import User From ef1012b7227e23d44361bb1faa22f39224815aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 10 Jan 2016 15:11:17 +0100 Subject: [PATCH 08/34] enable sending by URL for all sendX methods --- telegram/inputfile.py | 34 +++++++++++++++++++++------------- tests/test_document.py | 2 +- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/telegram/inputfile.py b/telegram/inputfile.py index 7c43bfd72..e82e75d01 100644 --- a/telegram/inputfile.py +++ b/telegram/inputfile.py @@ -27,6 +27,7 @@ try: except ImportError: from mimetools import choose_boundary from urllib2 import urlopen + import mimetypes import os import sys @@ -69,19 +70,29 @@ class InputFile(object): self.input_name = 'certificate' self.input_file = data.pop('certificate') - if isinstance(self.input_file, file): + if str(self.input_file).startswith('http'): + from_url = True + self.input_file = urlopen(self.input_file) + else: + from_url = False + + if isinstance(self.input_file, file) or from_url: self.input_file_content = self.input_file.read() if 'filename' in data: self.filename = self.data.pop('filename') - else: + elif isinstance(self.input_file, file): self.filename = os.path.basename(self.input_file.name) - self.mimetype = mimetypes.guess_type(self.filename)[0] or \ - DEFAULT_MIME_TYPE + elif from_url: + self.filename = self.input_file.url.split('/')[-1].split('?')[0].split('&')[0] + + try: + self.mimetype = InputFile.is_image(self.input_file_content) + if 'filename' not in dir(self): + self.filename = self.mimetype.replace('/', '.') + except TelegramError: + self.mimetype = mimetypes.guess_type(self.filename)[0] or \ + DEFAULT_MIME_TYPE - if 'http' in self.input_file: - self.input_file_content = urlopen(self.input_file).read() - self.mimetype = InputFile.is_image(self.input_file_content) - self.filename = self.mimetype.replace('/', '.') @property def headers(self): @@ -185,10 +196,7 @@ class InputFile(object): if file_type: file_content = data[file_type[0]] - if file_type[0] == 'photo' or file_type[0] == 'document': - return isinstance(file_content, file) or \ - str(file_content).startswith('http') - - return isinstance(file_content, file) + return isinstance(file_content, file) or \ + str(file_content).startswith('http') return False diff --git a/tests/test_document.py b/tests/test_document.py index dd778dff0..ea48f136b 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -96,7 +96,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(document.file_id, str)) self.assertNotEqual(document.file_id, '') self.assertTrue(isinstance(document.thumb, telegram.PhotoSize)) - self.assertEqual(document.file_name, 'image.gif') + self.assertEqual(document.file_name, 'fff.gif') self.assertEqual(document.mime_type, 'image/gif') self.assertEqual(document.file_size, 3878) From 142cc6e6ada0279853882a09e023289d553e78c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Fri, 29 Jan 2016 23:54:07 +0100 Subject: [PATCH 09/34] add test for dispatching inline queries/results --- tests/test_updater.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/tests/test_updater.py b/tests/test_updater.py index 3c1472a43..4a3e89f09 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -87,6 +87,11 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.received_message = update.message.text self.message_count += 1 + def telegramInlineHandlerTest(self, bot, update): + self.received_message = (update.inline_query, + update.chosen_inline_result) + self.message_count += 1 + @run_async def asyncHandlerTest(self, bot, update, **kwargs): sleep(1) @@ -294,8 +299,7 @@ class UpdaterTest(BaseTest, unittest.TestCase): print('Testing error in Handler') self._setup_updater('', messages=0) d = self.updater.dispatcher - d.addStringRegexHandler('.*', - self.errorRaisingHandlerTest) + d.addStringRegexHandler('.*', self.errorRaisingHandlerTest) self.updater.dispatcher.addErrorHandler(self.errorHandlerTest) queue = self.updater.start_polling(0.01) @@ -331,6 +335,30 @@ class UpdaterTest(BaseTest, unittest.TestCase): sleep(.1) self.assertTrue(None is self.received_message) + def test_addRemoveInlineHandlerQuery(self): + print('Testing add/removeInlineHandler') + self._setup_updater('', messages=0) + d = self.updater.dispatcher + d.addTelegramInlineHandler(self.telegramInlineHandlerTest) + queue = self.updater.start_polling(0.01) + update = Update(update_id=0, inline_query="testquery") + update2 = Update(update_id=0, chosen_inline_result="testresult") + queue.put(update) + sleep(.1) + self.assertEqual(self.received_message[0], "testquery") + + queue.put(update2) + sleep(.1) + self.assertEqual(self.received_message[1], "testresult") + + # Remove handler + d.removeTelegramInlineHandler(self.telegramInlineHandlerTest) + self.reset() + + queue.put(update) + sleep(.1) + self.assertTrue(None is self.received_message) + def test_runAsync(self): print('Testing @run_async') self._setup_updater('Test5', messages=2) @@ -503,7 +531,7 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.updater.idle() # If we get this far, idle() ran through sleep(1) - self.updater.running = False + self.assertFalse(self.updater.running) def test_createBot(self): updater = Updater('123:abcd') From 69183d85f71fe062f811fb75d564d3eaf9307b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Fri, 29 Jan 2016 23:54:38 +0100 Subject: [PATCH 10/34] add test for InlineQueryResultArticle --- tests/test_inlineresult.py | 112 +++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 tests/test_inlineresult.py diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py new file mode 100644 index 000000000..0dbf9d64a --- /dev/null +++ b/tests/test_inlineresult.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2016 +# Leandro Toledo de Souza +# +# 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/]. + +"""This module contains a object that represents Tests for Telegram +InlineResults""" + +import os +import unittest +import sys +sys.path.append('.') + +import telegram +from tests.base import BaseTest + + +class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQueryResultArticle.""" + + def setUp(self): + self.id = 'id' + self.title = 'title' + self.message_text = 'message text' + self.parse_mode = 'HTML' + self.disable_web_page_preview = True + self.url = 'url' + self.hide_url = True + self.description = 'description' + self.thumb_url = 'thumb url' + self.thumb_height = 10 + self.thumb_width = 15 + + self.json_dict = { + 'type': 'article', + 'id': self.id, + 'title': self.title, + 'message_text': self.message_text, + 'parse_mode': self.parse_mode, + 'disable_web_page_preview': self.disable_web_page_preview, + 'url': self.url, + 'hide_url': self.hide_url, + 'description': self.description, + 'thumb_url': self.thumb_url, + 'thumb_height': self.thumb_height, + 'thumb_width': self.thumb_width + } + + def test_article_de_json(self): + """Test InlineQueryResultArticle.de_json() method""" + print('Testing InlineQueryResultArticle.de_json()') + + article = telegram.InlineQueryResultArticle.de_json(self.json_dict) + + self.assertEqual(article.type, 'article') + self.assertEqual(article.id, self.id) + self.assertEqual(article.title, self.title) + self.assertEqual(article.message_text, self.message_text) + self.assertEqual(article.parse_mode, self.parse_mode) + self.assertEqual(article.disable_web_page_preview, + self.disable_web_page_preview) + self.assertEqual(article.url, self.url) + self.assertEqual(article.hide_url, self.hide_url) + self.assertEqual(article.description, self.description) + self.assertEqual(article.thumb_url, self.thumb_url) + self.assertEqual(article.thumb_height, self.thumb_height) + self.assertEqual(article.thumb_width, self.thumb_width) + + def test_article_to_json(self): + """Test InlineQueryResultArticle.to_json() method""" + print('Testing InlineQueryResultArticle.to_json()') + + article = telegram.InlineQueryResultArticle.de_json(self.json_dict) + + self.assertTrue(self.is_json(article.to_json())) + + def test_article_to_dict(self): + """Test InlineQueryResultArticle.to_dict() method""" + print('Testing InlineQueryResultArticle.to_dict()') + + article = telegram.InlineQueryResultArticle.de_json(self.json_dict) + + self.assertTrue(self.is_dict(article.to_dict())) + self.assertEqual(article['type'], 'article') + self.assertEqual(article['id'], self.id) + self.assertEqual(article['title'], self.title) + self.assertEqual(article['message_text'], self.message_text) + self.assertEqual(article['parse_mode'], self.parse_mode) + self.assertEqual(article['disable_web_page_preview'], self.disable_web_page_preview) + self.assertEqual(article['url'], self.url) + self.assertEqual(article['hide_url'], self.hide_url) + self.assertEqual(article['description'], self.description) + self.assertEqual(article['thumb_url'], self.thumb_url) + self.assertEqual(article['thumb_height'], self.thumb_height) + self.assertEqual(article['thumb_width'], self.thumb_width) + +if __name__ == '__main__': + unittest.main() From 08836c60cab3361cd1afe66ac181d64573117186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 31 Jan 2016 10:52:04 +0100 Subject: [PATCH 11/34] tests for InlineQueryResultPhoto --- tests/test_inlineresult.py | 87 +++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index 0dbf9d64a..1fc1c3442 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -100,7 +100,8 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): self.assertEqual(article['title'], self.title) self.assertEqual(article['message_text'], self.message_text) self.assertEqual(article['parse_mode'], self.parse_mode) - self.assertEqual(article['disable_web_page_preview'], self.disable_web_page_preview) + self.assertEqual(article['disable_web_page_preview'], + self.disable_web_page_preview) self.assertEqual(article['url'], self.url) self.assertEqual(article['hide_url'], self.hide_url) self.assertEqual(article['description'], self.description) @@ -108,5 +109,89 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): self.assertEqual(article['thumb_height'], self.thumb_height) self.assertEqual(article['thumb_width'], self.thumb_width) + +class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQueryResultPhoto.""" + + def setUp(self): + self.id = 'id' + self.photo_url = 'photo url' + self.mime_type = 'mime type' + self.photo_width = 10 + self.photo_height = 15 + self.thumb_url = 'thumb url' + self.title = 'title' + self.caption = 'caption' + self.message_text = 'message text' + self.parse_mode = 'parse mode' + self.disable_web_page_preview = True + + self.json_dict = { + 'type': 'photo', + 'id': self.id, + 'photo_url': self.photo_url, + 'mime_type': self.mime_type, + 'photo_width': self.photo_width, + 'photo_height': self.photo_height, + 'thumb_url': self.thumb_url, + 'title': self.title, + 'caption': self.caption, + 'message_text': self.message_text, + 'parse_mode': self.parse_mode, + 'disable_web_page_preview': self.disable_web_page_preview + } + + def test_photo_de_json(self): + """Test InlineQueryResultPhoto.de_json() method""" + print('Testing InlineQueryResultPhoto.de_json()') + + photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) + + self.assertEqual(photo.type, 'photo') + self.assertEqual(photo.id, self.id) + self.assertEqual(photo.photo_url, self.photo_url) + self.assertEqual(photo.mime_type, self.mime_type) + self.assertEqual(photo.photo_width, self.photo_width) + self.assertEqual(photo.photo_height, + self.photo_height) + self.assertEqual(photo.thumb_url, self.thumb_url) + self.assertEqual(photo.title, self.title) + self.assertEqual(photo.caption, self.caption) + self.assertEqual(photo.message_text, self.message_text) + self.assertEqual(photo.parse_mode, self.parse_mode) + self.assertEqual(photo.disable_web_page_preview, + self.disable_web_page_preview) + + def test_photo_to_json(self): + """Test InlineQueryResultPhoto.to_json() method""" + print('Testing InlineQueryResultPhoto.to_json()') + + photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) + + self.assertTrue(self.is_json(photo.to_json())) + + def test_photo_to_dict(self): + """Test InlineQueryResultPhoto.to_dict() method""" + print('Testing InlineQueryResultPhoto.to_dict()') + + photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) + + self.assertTrue(self.is_dict(photo.to_dict())) + self.assertEqual(photo['type'], 'photo') + self.assertEqual(photo['id'], self.id) + self.assertEqual(photo['photo_url'], self.photo_url) + self.assertEqual(photo['mime_type'], self.mime_type) + self.assertEqual(photo['photo_width'], self.photo_width) + self.assertEqual(photo['photo_height'], + self.photo_height) + self.assertEqual(photo['thumb_url'], self.thumb_url) + self.assertEqual(photo['title'], self.title) + self.assertEqual(photo['caption'], self.caption) + self.assertEqual(photo['message_text'], self.message_text) + self.assertEqual(photo['parse_mode'], self.parse_mode) + self.assertEqual(photo['disable_web_page_preview'], + self.disable_web_page_preview) + + if __name__ == '__main__': unittest.main() From 2436cab2e57c5e46542c88d17dfde1b40b2a0768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 3 Feb 2016 02:09:05 +0100 Subject: [PATCH 12/34] tests for gif and mpeg4 --- tests/test_inlineresult.py | 158 +++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index 1fc1c3442..ff6b135fe 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -193,5 +193,163 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) +class InlineQueryResultGifTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQueryResultGif.""" + + def setUp(self): + self.id = 'id' + self.gif_url = 'gif url' + self.gif_width = 10 + self.gif_height = 15 + self.thumb_url = 'thumb url' + self.title = 'title' + self.caption = 'caption' + self.message_text = 'message text' + self.parse_mode = 'parse mode' + self.disable_web_page_preview = True + + self.json_dict = { + 'type': 'gif', + 'id': self.id, + 'gif_url': self.gif_url, + 'gif_width': self.gif_width, + 'gif_height': self.gif_height, + 'thumb_url': self.thumb_url, + 'title': self.title, + 'caption': self.caption, + 'message_text': self.message_text, + 'parse_mode': self.parse_mode, + 'disable_web_page_preview': self.disable_web_page_preview + } + + def test_gif_de_json(self): + """Test InlineQueryResultGif.de_json() method""" + print('Testing InlineQueryResultGif.de_json()') + + gif = telegram.InlineQueryResultGif.de_json(self.json_dict) + + self.assertEqual(gif.type, 'gif') + self.assertEqual(gif.id, self.id) + self.assertEqual(gif.gif_url, self.gif_url) + self.assertEqual(gif.gif_width, self.gif_width) + self.assertEqual(gif.gif_height, + self.gif_height) + self.assertEqual(gif.thumb_url, self.thumb_url) + self.assertEqual(gif.title, self.title) + self.assertEqual(gif.caption, self.caption) + self.assertEqual(gif.message_text, self.message_text) + self.assertEqual(gif.parse_mode, self.parse_mode) + self.assertEqual(gif.disable_web_page_preview, + self.disable_web_page_preview) + + def test_gif_to_json(self): + """Test InlineQueryResultGif.to_json() method""" + print('Testing InlineQueryResultGif.to_json()') + + gif = telegram.InlineQueryResultGif.de_json(self.json_dict) + + self.assertTrue(self.is_json(gif.to_json())) + + def test_gif_to_dict(self): + """Test InlineQueryResultGif.to_dict() method""" + print('Testing InlineQueryResultGif.to_dict()') + + gif = telegram.InlineQueryResultGif.de_json(self.json_dict) + + self.assertTrue(self.is_dict(gif.to_dict())) + self.assertEqual(gif['type'], 'gif') + self.assertEqual(gif['id'], self.id) + self.assertEqual(gif['gif_url'], self.gif_url) + self.assertEqual(gif['gif_width'], self.gif_width) + self.assertEqual(gif['gif_height'], + self.gif_height) + self.assertEqual(gif['thumb_url'], self.thumb_url) + self.assertEqual(gif['title'], self.title) + self.assertEqual(gif['caption'], self.caption) + self.assertEqual(gif['message_text'], self.message_text) + self.assertEqual(gif['parse_mode'], self.parse_mode) + self.assertEqual(gif['disable_web_page_preview'], + self.disable_web_page_preview) + + +class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQueryResultMpeg4Gif.""" + + def setUp(self): + self.id = 'id' + self.mpeg4_url = 'mpeg4 url' + self.mpeg4_width = 10 + self.mpeg4_height = 15 + self.thumb_url = 'thumb url' + self.title = 'title' + self.caption = 'caption' + self.message_text = 'message text' + self.parse_mode = 'parse mode' + self.disable_web_page_preview = True + + self.json_dict = { + 'type': 'gif', + 'id': self.id, + 'mpeg4_url': self.mpeg4_url, + 'mpeg4_width': self.mpeg4_width, + 'mpeg4_height': self.mpeg4_height, + 'thumb_url': self.thumb_url, + 'title': self.title, + 'caption': self.caption, + 'message_text': self.message_text, + 'parse_mode': self.parse_mode, + 'disable_web_page_preview': self.disable_web_page_preview + } + + def test_mpeg4_de_json(self): + """Test InlineQueryResultMpeg4Gif.de_json() method""" + print('Testing InlineQueryResultMpeg4Gif.de_json()') + + mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) + + self.assertEqual(mpeg4.type, 'mpeg4_gif') + self.assertEqual(mpeg4.id, self.id) + self.assertEqual(mpeg4.mpeg4_url, self.mpeg4_url) + self.assertEqual(mpeg4.mpeg4_width, self.mpeg4_width) + self.assertEqual(mpeg4.mpeg4_height, + self.mpeg4_height) + self.assertEqual(mpeg4.thumb_url, self.thumb_url) + self.assertEqual(mpeg4.title, self.title) + self.assertEqual(mpeg4.caption, self.caption) + self.assertEqual(mpeg4.message_text, self.message_text) + self.assertEqual(mpeg4.parse_mode, self.parse_mode) + self.assertEqual(mpeg4.disable_web_page_preview, + self.disable_web_page_preview) + + def test_mpeg4_to_json(self): + """Test InlineQueryResultMpeg4Gif.to_json() method""" + print('Testing InlineQueryResultMpeg4Gif.to_json()') + + mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) + + self.assertTrue(self.is_json(mpeg4.to_json())) + + def test_mpeg4_to_dict(self): + """Test InlineQueryResultMpeg4Gif.to_dict() method""" + print('Testing InlineQueryResultMpeg4Gif.to_dict()') + + mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) + + self.assertTrue(self.is_dict(mpeg4.to_dict())) + self.assertEqual(mpeg4['type'], 'mpeg4_gif') + self.assertEqual(mpeg4['id'], self.id) + self.assertEqual(mpeg4['mpeg4_url'], self.mpeg4_url) + self.assertEqual(mpeg4['mpeg4_width'], self.mpeg4_width) + self.assertEqual(mpeg4['mpeg4_height'], + self.mpeg4_height) + self.assertEqual(mpeg4['thumb_url'], self.thumb_url) + self.assertEqual(mpeg4['title'], self.title) + self.assertEqual(mpeg4['caption'], self.caption) + self.assertEqual(mpeg4['message_text'], self.message_text) + self.assertEqual(mpeg4['parse_mode'], self.parse_mode) + self.assertEqual(mpeg4['disable_web_page_preview'], + self.disable_web_page_preview) + + if __name__ == '__main__': unittest.main() From 70dfb88eb529625ac696f7c2e51e42e5ea2e9e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 7 Feb 2016 22:56:25 +0100 Subject: [PATCH 13/34] complete tests for inline results --- tests/test_inlineresult.py | 107 ++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 12 deletions(-) diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index ff6b135fe..30007aa44 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -152,8 +152,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.photo_url, self.photo_url) self.assertEqual(photo.mime_type, self.mime_type) self.assertEqual(photo.photo_width, self.photo_width) - self.assertEqual(photo.photo_height, - self.photo_height) + self.assertEqual(photo.photo_height, self.photo_height) self.assertEqual(photo.thumb_url, self.thumb_url) self.assertEqual(photo.title, self.title) self.assertEqual(photo.caption, self.caption) @@ -182,8 +181,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo['photo_url'], self.photo_url) self.assertEqual(photo['mime_type'], self.mime_type) self.assertEqual(photo['photo_width'], self.photo_width) - self.assertEqual(photo['photo_height'], - self.photo_height) + self.assertEqual(photo['photo_height'], self.photo_height) self.assertEqual(photo['thumb_url'], self.thumb_url) self.assertEqual(photo['title'], self.title) self.assertEqual(photo['caption'], self.caption) @@ -232,8 +230,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): self.assertEqual(gif.id, self.id) self.assertEqual(gif.gif_url, self.gif_url) self.assertEqual(gif.gif_width, self.gif_width) - self.assertEqual(gif.gif_height, - self.gif_height) + self.assertEqual(gif.gif_height, self.gif_height) self.assertEqual(gif.thumb_url, self.thumb_url) self.assertEqual(gif.title, self.title) self.assertEqual(gif.caption, self.caption) @@ -261,8 +258,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): self.assertEqual(gif['id'], self.id) self.assertEqual(gif['gif_url'], self.gif_url) self.assertEqual(gif['gif_width'], self.gif_width) - self.assertEqual(gif['gif_height'], - self.gif_height) + self.assertEqual(gif['gif_height'], self.gif_height) self.assertEqual(gif['thumb_url'], self.thumb_url) self.assertEqual(gif['title'], self.title) self.assertEqual(gif['caption'], self.caption) @@ -311,8 +307,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): self.assertEqual(mpeg4.id, self.id) self.assertEqual(mpeg4.mpeg4_url, self.mpeg4_url) self.assertEqual(mpeg4.mpeg4_width, self.mpeg4_width) - self.assertEqual(mpeg4.mpeg4_height, - self.mpeg4_height) + self.assertEqual(mpeg4.mpeg4_height, self.mpeg4_height) self.assertEqual(mpeg4.thumb_url, self.thumb_url) self.assertEqual(mpeg4.title, self.title) self.assertEqual(mpeg4.caption, self.caption) @@ -340,8 +335,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): self.assertEqual(mpeg4['id'], self.id) self.assertEqual(mpeg4['mpeg4_url'], self.mpeg4_url) self.assertEqual(mpeg4['mpeg4_width'], self.mpeg4_width) - self.assertEqual(mpeg4['mpeg4_height'], - self.mpeg4_height) + self.assertEqual(mpeg4['mpeg4_height'], self.mpeg4_height) self.assertEqual(mpeg4['thumb_url'], self.thumb_url) self.assertEqual(mpeg4['title'], self.title) self.assertEqual(mpeg4['caption'], self.caption) @@ -351,5 +345,94 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) +class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQueryResultVideo.""" + + def setUp(self): + self.id = 'id' + self.video_url = 'mpeg4 url' + self.mime_type = 'mime type' + self.video_width = 10 + self.video_height = 15 + self.video_duration = 15 + self.thumb_url = 'thumb url' + self.title = 'title' + self.caption = 'caption' + self.description = 'description' + self.message_text = 'message text' + self.parse_mode = 'parse mode' + self.disable_web_page_preview = True + + self.json_dict = { + 'type': 'video', + 'id': self.id, + 'video_url': self.video_url, + 'mime_type': self.mime_type, + 'video_width': self.video_width, + 'video_height': self.video_height, + 'video_duration': self.video_duration, + 'thumb_url': self.thumb_url, + 'title': self.title, + 'caption': self.caption, + 'description': self.description, + 'message_text': self.message_text, + 'parse_mode': self.parse_mode, + 'disable_web_page_preview': self.disable_web_page_preview + } + + def test_video_de_json(self): + """Test InlineQueryResultVideo.de_json() method""" + print('Testing InlineQueryResultVideo.de_json()') + + video = telegram.InlineQueryResultVideo.de_json(self.json_dict) + + self.assertEqual(video.type, 'video') + self.assertEqual(video.id, self.id) + self.assertEqual(video.video_url, self.video_url) + self.assertEqual(video.mime_type, self.mime_type) + self.assertEqual(video.video_width, self.video_width) + self.assertEqual(video.video_height, self.video_height) + self.assertEqual(video.video_duration, self.video_duration) + self.assertEqual(video.thumb_url, self.thumb_url) + self.assertEqual(video.title, self.title) + self.assertEqual(video.description, self.description) + self.assertEqual(video.caption, self.caption) + self.assertEqual(video.message_text, self.message_text) + self.assertEqual(video.parse_mode, self.parse_mode) + self.assertEqual(video.disable_web_page_preview, + self.disable_web_page_preview) + + def test_video_to_json(self): + """Test InlineQueryResultVideo.to_json() method""" + print('Testing InlineQueryResultVideo.to_json()') + + video = telegram.InlineQueryResultVideo.de_json(self.json_dict) + + self.assertTrue(self.is_json(video.to_json())) + + def test_video_to_dict(self): + """Test InlineQueryResultVideo.to_dict() method""" + print('Testing InlineQueryResultVideo.to_dict()') + + video = telegram.InlineQueryResultVideo.de_json(self.json_dict) + + self.assertTrue(self.is_dict(video.to_dict())) + self.assertEqual(video['type'], 'video') + self.assertEqual(video['id'], self.id) + self.assertEqual(video['video_url'], self.video_url) + self.assertEqual(video['mime_type'], self.mime_type) + self.assertEqual(video['video_width'], self.video_width) + self.assertEqual(video['video_height'], self.video_height) + self.assertEqual(video['video_duration'], self.video_duration) + self.assertEqual(video['thumb_url'], self.thumb_url) + self.assertEqual(video['title'], self.title) + self.assertEqual(video['description'], self.description) + self.assertEqual(video['caption'], self.caption) + self.assertEqual(video['message_text'], self.message_text) + self.assertEqual(video['parse_mode'], self.parse_mode) + self.assertEqual(video['disable_web_page_preview'], + self.disable_web_page_preview) + + if __name__ == '__main__': unittest.main() From fc73948c820f33195719d022878f4039216a2a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 7 Feb 2016 23:25:48 +0100 Subject: [PATCH 14/34] fix to_dict tests --- tests/test_inlineresult.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index 30007aa44..604775906 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -92,9 +92,10 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): """Test InlineQueryResultArticle.to_dict() method""" print('Testing InlineQueryResultArticle.to_dict()') - article = telegram.InlineQueryResultArticle.de_json(self.json_dict) + article = \ + telegram.InlineQueryResultArticle.de_json(self.json_dict).to_dict() - self.assertTrue(self.is_dict(article.to_dict())) + self.assertTrue(self.is_dict(article)) self.assertEqual(article['type'], 'article') self.assertEqual(article['id'], self.id) self.assertEqual(article['title'], self.title) @@ -173,9 +174,10 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): """Test InlineQueryResultPhoto.to_dict() method""" print('Testing InlineQueryResultPhoto.to_dict()') - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) + photo = \ + telegram.InlineQueryResultPhoto.de_json(self.json_dict).to_dict() - self.assertTrue(self.is_dict(photo.to_dict())) + self.assertTrue(self.is_dict(photo)) self.assertEqual(photo['type'], 'photo') self.assertEqual(photo['id'], self.id) self.assertEqual(photo['photo_url'], self.photo_url) @@ -251,9 +253,9 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): """Test InlineQueryResultGif.to_dict() method""" print('Testing InlineQueryResultGif.to_dict()') - gif = telegram.InlineQueryResultGif.de_json(self.json_dict) + gif = telegram.InlineQueryResultGif.de_json(self.json_dict).to_dict() - self.assertTrue(self.is_dict(gif.to_dict())) + self.assertTrue(self.is_dict(gif)) self.assertEqual(gif['type'], 'gif') self.assertEqual(gif['id'], self.id) self.assertEqual(gif['gif_url'], self.gif_url) @@ -328,9 +330,10 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): """Test InlineQueryResultMpeg4Gif.to_dict() method""" print('Testing InlineQueryResultMpeg4Gif.to_dict()') - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) + mpeg4 = \ + telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict).to_dict() - self.assertTrue(self.is_dict(mpeg4.to_dict())) + self.assertTrue(self.is_dict(mpeg4)) self.assertEqual(mpeg4['type'], 'mpeg4_gif') self.assertEqual(mpeg4['id'], self.id) self.assertEqual(mpeg4['mpeg4_url'], self.mpeg4_url) @@ -414,9 +417,10 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): """Test InlineQueryResultVideo.to_dict() method""" print('Testing InlineQueryResultVideo.to_dict()') - video = telegram.InlineQueryResultVideo.de_json(self.json_dict) + video = \ + telegram.InlineQueryResultVideo.de_json(self.json_dict).to_dict() - self.assertTrue(self.is_dict(video.to_dict())) + self.assertTrue(self.is_dict(video)) self.assertEqual(video['type'], 'video') self.assertEqual(video['id'], self.id) self.assertEqual(video['video_url'], self.video_url) From d1dc32d8497a630f9d7f7e3a3384c0e4be36c5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 7 Feb 2016 23:26:38 +0100 Subject: [PATCH 15/34] tests and corrections for choseninlineresult --- telegram/choseninlineresult.py | 9 ++-- tests/test_choseninlineresult.py | 80 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 tests/test_choseninlineresult.py diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py index 03b0f4d25..9a6df72df 100644 --- a/telegram/choseninlineresult.py +++ b/telegram/choseninlineresult.py @@ -22,7 +22,7 @@ This module contains a object that represents a Telegram ChosenInlineResult """ -from telegram import TelegramObject +from telegram import TelegramObject, User class ChosenInlineResult(TelegramObject): @@ -46,9 +46,10 @@ class ChosenInlineResult(TelegramObject): def __init__(self, result_id, from_user, - query): + query, + **kwargs): # Required - self.result_id = int(result_id) + self.result_id = result_id self.from_user = from_user self.query = query @@ -64,6 +65,8 @@ class ChosenInlineResult(TelegramObject): if not data: return None + data['from_user'] = User.de_json(data.get('from')) + return ChosenInlineResult(**data) def to_dict(self): diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py new file mode 100644 index 000000000..d059d1350 --- /dev/null +++ b/tests/test_choseninlineresult.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2016 +# Leandro Toledo de Souza +# +# 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/]. + +"""This module contains a object that represents Tests for Telegram +ChosenInlineResult""" + +import os +import unittest +import sys +sys.path.append('.') + +import telegram +from tests.base import BaseTest + + +class ChosenInlineResultTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram ChosenInlineResult.""" + + def setUp(self): + + user = telegram.User(1, 'First name') + + self.result_id = 'result id' + self.from_user = user + self.query = 'query text' + + self.json_dict = { + 'result_id': self.result_id, + 'from': self.from_user.to_dict(), + 'query': self.query + } + + def test_choseninlineresult_de_json(self): + """Test ChosenInlineResult.de_json() method""" + print('Testing ChosenInlineResult.de_json()') + + result = telegram.ChosenInlineResult.de_json(self.json_dict) + + self.assertEqual(result.result_id, self.result_id) + self.assertEqual(result.from_user.to_dict(), self.from_user.to_dict()) + self.assertEqual(result.query, self.query) + + def test_choseninlineresult_to_json(self): + """Test ChosenInlineResult.to_json() method""" + print('Testing ChosenInlineResult.to_json()') + + result = telegram.ChosenInlineResult.de_json(self.json_dict) + + self.assertTrue(self.is_json(result.to_json())) + + def test_choseninlineresult_to_dict(self): + """Test ChosenInlineResult.to_dict() method""" + print('Testing ChosenInlineResult.to_dict()') + + result = telegram.ChosenInlineResult.de_json(self.json_dict).to_dict() + + self.assertTrue(self.is_dict(result)) + self.assertEqual(result['result_id'], self.result_id) + self.assertEqual(result['from'], self.from_user.to_dict()) + self.assertEqual(result['query'], self.query) + + +if __name__ == '__main__': + unittest.main() From c55c5408b1fe3c4f17869801454de014e52a47d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 7 Feb 2016 23:34:15 +0100 Subject: [PATCH 16/34] tests and corrections for inlinequery --- telegram/inlinequery.py | 4 +- tests/test_inlinequery.py | 84 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tests/test_inlinequery.py diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py index 7a365a632..ceb3a5997 100644 --- a/telegram/inlinequery.py +++ b/telegram/inlinequery.py @@ -29,7 +29,7 @@ class InlineQuery(TelegramObject): * In Python `from` is a reserved word, use `from_user` instead. Attributes: - id (int): + id (str): from_user (:class:`telegram.User`): query (str): offset (str): @@ -48,7 +48,7 @@ class InlineQuery(TelegramObject): query, offset): # Required - self.id = int(id) + self.id = id self.from_user = from_user self.query = query self.offset = offset diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py new file mode 100644 index 000000000..55b491f81 --- /dev/null +++ b/tests/test_inlinequery.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2016 +# Leandro Toledo de Souza +# +# 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/]. + +"""This module contains a object that represents Tests for Telegram +InlineQuery""" + +import os +import unittest +import sys +sys.path.append('.') + +import telegram +from tests.base import BaseTest + + +class InlineQueryTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram InlineQuery.""" + + def setUp(self): + + user = telegram.User(1, 'First name') + + self.id = 'id' + self.from_user = user + self.query = 'query text' + self.offset = 'offset' + + self.json_dict = { + 'id': self.id, + 'from': self.from_user.to_dict(), + 'query': self.query, + 'offset': self.offset + } + + def test_inlinequery_de_json(self): + """Test InlineQuery.de_json() method""" + print('Testing InlineQuery.de_json()') + + inlinequery = telegram.InlineQuery.de_json(self.json_dict) + + self.assertEqual(inlinequery.id, self.id) + self.assertEqual(inlinequery.from_user.to_dict(), self.from_user.to_dict()) + self.assertEqual(inlinequery.query, self.query) + self.assertEqual(inlinequery.offset, self.offset) + + def test_inlinequery_to_json(self): + """Test InlineQuery.to_json() method""" + print('Testing InlineQuery.to_json()') + + inlinequery = telegram.InlineQuery.de_json(self.json_dict) + + self.assertTrue(self.is_json(inlinequery.to_json())) + + def test_inlinequery_to_dict(self): + """Test InlineQuery.to_dict() method""" + print('Testing InlineQuery.to_dict()') + + inlinequery = telegram.InlineQuery.de_json(self.json_dict).to_dict() + + self.assertTrue(self.is_dict(inlinequery)) + self.assertEqual(inlinequery['id'], self.id) + self.assertEqual(inlinequery['from'], self.from_user.to_dict()) + self.assertEqual(inlinequery['query'], self.query) + self.assertEqual(inlinequery['offset'], self.offset) + + +if __name__ == '__main__': + unittest.main() From edf4e8abbe81f79c6d8fd2cc21e3b385b5497b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 7 Feb 2016 23:34:26 +0100 Subject: [PATCH 17/34] fix docstring --- telegram/choseninlineresult.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py index 9a6df72df..16cc7cb24 100644 --- a/telegram/choseninlineresult.py +++ b/telegram/choseninlineresult.py @@ -32,12 +32,12 @@ class ChosenInlineResult(TelegramObject): * In Python `from` is a reserved word, use `from_user` instead. Attributes: - result_id (int): + result_id (str): from_user (:class:`telegram.User`): query (str): Args: - result_id (int): + result_id (str): from_user (:class:`telegram.User`): query (str): From ca526fba73029a403358bc8772135090ad60445a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sat, 20 Feb 2016 12:14:34 +0100 Subject: [PATCH 18/34] improve unit tests according to comments --- telegram/inlinequery.py | 5 +- telegram/inlinequeryresult.py | 1 + tests/test_choseninlineresult.py | 11 +++- tests/test_inlinequery.py | 16 ++--- tests/test_inlineresult.py | 105 ++++++++----------------------- 5 files changed, 48 insertions(+), 90 deletions(-) diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py index ceb3a5997..0997e2eac 100644 --- a/telegram/inlinequery.py +++ b/telegram/inlinequery.py @@ -65,9 +65,10 @@ class InlineQuery(TelegramObject): if not data: return None - data['from_user'] = User.de_json(data.pop('from')) + data_ = data.copy() # Copy data so we can pop 'from' + data_['from_user'] = User.de_json(data_.pop('from')) - return InlineQuery(**data) + return InlineQuery(**data_) def to_dict(self): """ diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py index 3c0e4b36b..547f46ec1 100644 --- a/telegram/inlinequeryresult.py +++ b/telegram/inlinequeryresult.py @@ -18,6 +18,7 @@ """ This module contains the classes that represent Telegram InlineQueryResults +https://core.telegram.org/bots/api#inline-mode """ from telegram import TelegramObject diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index d059d1350..6da4811dc 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -20,9 +20,13 @@ """This module contains a object that represents Tests for Telegram ChosenInlineResult""" -import os -import unittest import sys + +if sys.version_info[0:2] == (2, 6): + import unittest2 as unittest +else: + import unittest + sys.path.append('.') import telegram @@ -53,7 +57,8 @@ class ChosenInlineResultTest(BaseTest, unittest.TestCase): result = telegram.ChosenInlineResult.de_json(self.json_dict) self.assertEqual(result.result_id, self.result_id) - self.assertEqual(result.from_user.to_dict(), self.from_user.to_dict()) + self.assertDictEqual(result.from_user.to_dict(), + self.from_user.to_dict()) self.assertEqual(result.query, self.query) def test_choseninlineresult_to_json(self): diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 55b491f81..ec18eefdb 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -20,9 +20,13 @@ """This module contains a object that represents Tests for Telegram InlineQuery""" -import os -import unittest import sys + +if sys.version_info[0:2] == (2, 6): + import unittest2 as unittest +else: + import unittest + sys.path.append('.') import telegram @@ -55,7 +59,8 @@ class InlineQueryTest(BaseTest, unittest.TestCase): inlinequery = telegram.InlineQuery.de_json(self.json_dict) self.assertEqual(inlinequery.id, self.id) - self.assertEqual(inlinequery.from_user.to_dict(), self.from_user.to_dict()) + self.assertDictEqual(inlinequery.from_user.to_dict(), + self.from_user.to_dict()) self.assertEqual(inlinequery.query, self.query) self.assertEqual(inlinequery.offset, self.offset) @@ -74,10 +79,7 @@ class InlineQueryTest(BaseTest, unittest.TestCase): inlinequery = telegram.InlineQuery.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(inlinequery)) - self.assertEqual(inlinequery['id'], self.id) - self.assertEqual(inlinequery['from'], self.from_user.to_dict()) - self.assertEqual(inlinequery['query'], self.query) - self.assertEqual(inlinequery['offset'], self.offset) + self.assertDictEqual(inlinequery, self.json_dict) if __name__ == '__main__': diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index 604775906..7abd0d4bd 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -20,9 +20,13 @@ """This module contains a object that represents Tests for Telegram InlineResults""" -import os -import unittest import sys + +if sys.version_info[0:2] == (2, 6): + import unittest2 as unittest +else: + import unittest + sys.path.append('.') import telegram @@ -34,6 +38,7 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): def setUp(self): self.id = 'id' + self.type = 'article' self.title = 'title' self.message_text = 'message text' self.parse_mode = 'HTML' @@ -46,7 +51,7 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): self.thumb_width = 15 self.json_dict = { - 'type': 'article', + 'type': self.type, 'id': self.id, 'title': self.title, 'message_text': self.message_text, @@ -66,7 +71,7 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): article = telegram.InlineQueryResultArticle.de_json(self.json_dict) - self.assertEqual(article.type, 'article') + self.assertEqual(article.type, self.type) self.assertEqual(article.id, self.id) self.assertEqual(article.title, self.title) self.assertEqual(article.message_text, self.message_text) @@ -96,19 +101,7 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): telegram.InlineQueryResultArticle.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(article)) - self.assertEqual(article['type'], 'article') - self.assertEqual(article['id'], self.id) - self.assertEqual(article['title'], self.title) - self.assertEqual(article['message_text'], self.message_text) - self.assertEqual(article['parse_mode'], self.parse_mode) - self.assertEqual(article['disable_web_page_preview'], - self.disable_web_page_preview) - self.assertEqual(article['url'], self.url) - self.assertEqual(article['hide_url'], self.hide_url) - self.assertEqual(article['description'], self.description) - self.assertEqual(article['thumb_url'], self.thumb_url) - self.assertEqual(article['thumb_height'], self.thumb_height) - self.assertEqual(article['thumb_width'], self.thumb_width) + self.assertDictEqual(self.json_dict, article) class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): @@ -116,6 +109,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): def setUp(self): self.id = 'id' + self.type = 'photo' self.photo_url = 'photo url' self.mime_type = 'mime type' self.photo_width = 10 @@ -128,7 +122,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): self.disable_web_page_preview = True self.json_dict = { - 'type': 'photo', + 'type': self.type, 'id': self.id, 'photo_url': self.photo_url, 'mime_type': self.mime_type, @@ -148,7 +142,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) - self.assertEqual(photo.type, 'photo') + self.assertEqual(photo.type, self.type) self.assertEqual(photo.id, self.id) self.assertEqual(photo.photo_url, self.photo_url) self.assertEqual(photo.mime_type, self.mime_type) @@ -178,19 +172,7 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): telegram.InlineQueryResultPhoto.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(photo)) - self.assertEqual(photo['type'], 'photo') - self.assertEqual(photo['id'], self.id) - self.assertEqual(photo['photo_url'], self.photo_url) - self.assertEqual(photo['mime_type'], self.mime_type) - self.assertEqual(photo['photo_width'], self.photo_width) - self.assertEqual(photo['photo_height'], self.photo_height) - self.assertEqual(photo['thumb_url'], self.thumb_url) - self.assertEqual(photo['title'], self.title) - self.assertEqual(photo['caption'], self.caption) - self.assertEqual(photo['message_text'], self.message_text) - self.assertEqual(photo['parse_mode'], self.parse_mode) - self.assertEqual(photo['disable_web_page_preview'], - self.disable_web_page_preview) + self.assertDictEqual(self.json_dict, photo) class InlineQueryResultGifTest(BaseTest, unittest.TestCase): @@ -198,6 +180,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): def setUp(self): self.id = 'id' + self.type = 'gif' self.gif_url = 'gif url' self.gif_width = 10 self.gif_height = 15 @@ -209,7 +192,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): self.disable_web_page_preview = True self.json_dict = { - 'type': 'gif', + 'type': self.type, 'id': self.id, 'gif_url': self.gif_url, 'gif_width': self.gif_width, @@ -228,7 +211,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): gif = telegram.InlineQueryResultGif.de_json(self.json_dict) - self.assertEqual(gif.type, 'gif') + self.assertEqual(gif.type, self.type) self.assertEqual(gif.id, self.id) self.assertEqual(gif.gif_url, self.gif_url) self.assertEqual(gif.gif_width, self.gif_width) @@ -256,18 +239,7 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): gif = telegram.InlineQueryResultGif.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(gif)) - self.assertEqual(gif['type'], 'gif') - self.assertEqual(gif['id'], self.id) - self.assertEqual(gif['gif_url'], self.gif_url) - self.assertEqual(gif['gif_width'], self.gif_width) - self.assertEqual(gif['gif_height'], self.gif_height) - self.assertEqual(gif['thumb_url'], self.thumb_url) - self.assertEqual(gif['title'], self.title) - self.assertEqual(gif['caption'], self.caption) - self.assertEqual(gif['message_text'], self.message_text) - self.assertEqual(gif['parse_mode'], self.parse_mode) - self.assertEqual(gif['disable_web_page_preview'], - self.disable_web_page_preview) + self.assertDictEqual(self.json_dict, gif) class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): @@ -275,6 +247,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): def setUp(self): self.id = 'id' + self.type = 'mpeg4_gif' self.mpeg4_url = 'mpeg4 url' self.mpeg4_width = 10 self.mpeg4_height = 15 @@ -286,7 +259,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): self.disable_web_page_preview = True self.json_dict = { - 'type': 'gif', + 'type': self.type, 'id': self.id, 'mpeg4_url': self.mpeg4_url, 'mpeg4_width': self.mpeg4_width, @@ -305,7 +278,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) - self.assertEqual(mpeg4.type, 'mpeg4_gif') + self.assertEqual(mpeg4.type, self.type) self.assertEqual(mpeg4.id, self.id) self.assertEqual(mpeg4.mpeg4_url, self.mpeg4_url) self.assertEqual(mpeg4.mpeg4_width, self.mpeg4_width) @@ -334,18 +307,7 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(mpeg4)) - self.assertEqual(mpeg4['type'], 'mpeg4_gif') - self.assertEqual(mpeg4['id'], self.id) - self.assertEqual(mpeg4['mpeg4_url'], self.mpeg4_url) - self.assertEqual(mpeg4['mpeg4_width'], self.mpeg4_width) - self.assertEqual(mpeg4['mpeg4_height'], self.mpeg4_height) - self.assertEqual(mpeg4['thumb_url'], self.thumb_url) - self.assertEqual(mpeg4['title'], self.title) - self.assertEqual(mpeg4['caption'], self.caption) - self.assertEqual(mpeg4['message_text'], self.message_text) - self.assertEqual(mpeg4['parse_mode'], self.parse_mode) - self.assertEqual(mpeg4['disable_web_page_preview'], - self.disable_web_page_preview) + self.assertDictEqual(self.json_dict, mpeg4) class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): @@ -353,7 +315,8 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): def setUp(self): self.id = 'id' - self.video_url = 'mpeg4 url' + self.type = 'video' + self.video_url = 'video url' self.mime_type = 'mime type' self.video_width = 10 self.video_height = 15 @@ -367,7 +330,7 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): self.disable_web_page_preview = True self.json_dict = { - 'type': 'video', + 'type': self.type, 'id': self.id, 'video_url': self.video_url, 'mime_type': self.mime_type, @@ -389,7 +352,7 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): video = telegram.InlineQueryResultVideo.de_json(self.json_dict) - self.assertEqual(video.type, 'video') + self.assertEqual(video.type, self.type) self.assertEqual(video.id, self.id) self.assertEqual(video.video_url, self.video_url) self.assertEqual(video.mime_type, self.mime_type) @@ -421,21 +384,7 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): telegram.InlineQueryResultVideo.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(video)) - self.assertEqual(video['type'], 'video') - self.assertEqual(video['id'], self.id) - self.assertEqual(video['video_url'], self.video_url) - self.assertEqual(video['mime_type'], self.mime_type) - self.assertEqual(video['video_width'], self.video_width) - self.assertEqual(video['video_height'], self.video_height) - self.assertEqual(video['video_duration'], self.video_duration) - self.assertEqual(video['thumb_url'], self.thumb_url) - self.assertEqual(video['title'], self.title) - self.assertEqual(video['description'], self.description) - self.assertEqual(video['caption'], self.caption) - self.assertEqual(video['message_text'], self.message_text) - self.assertEqual(video['parse_mode'], self.parse_mode) - self.assertEqual(video['disable_web_page_preview'], - self.disable_web_page_preview) + self.assertDictEqual(self.json_dict, video) if __name__ == '__main__': From efd10507d038def35a268795a163a05a238a37bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 21 Feb 2016 11:33:34 +0100 Subject: [PATCH 19/34] remove kwargs in favor of named keyword arguments, validate argument types --- telegram/bot.py | 10 +- telegram/choseninlineresult.py | 7 +- telegram/inlinequery.py | 7 +- telegram/inlinequeryresult.py | 202 ++++++++++++++++++++++--------- telegram/utils/validate.py | 38 ++++++ tests/test_choseninlineresult.py | 9 -- tests/test_inlinequery.py | 9 -- tests/test_inlineresult.py | 45 ------- 8 files changed, 193 insertions(+), 134 deletions(-) create mode 100644 telegram/utils/validate.py diff --git a/telegram/bot.py b/telegram/bot.py index e82c543f8..b498eedd9 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -27,6 +27,7 @@ from telegram import (User, Message, Update, UserProfilePhotos, File, TelegramError, ReplyMarkup, TelegramObject, NullHandler) from telegram.error import InvalidToken from telegram.utils import request +from telegram.utils.validate import validate_string H = NullHandler() logging.getLogger(__name__).addHandler(H) @@ -595,7 +596,7 @@ class Bot(TelegramObject): """Use this method to reply to an inline query. Args: - inline_query_id (int): + inline_query_id (str): Unique identifier for answered query results (list[InlineQueryResult]): A list of results for the inline query @@ -617,6 +618,9 @@ class Bot(TelegramObject): A boolean if answering was successful """ + validate_string(inline_query_id, 'inline_query_id') + validate_string(inline_query_id, 'next_offset') + url = '%s/answerInlineQuery' % self.base_url results = [res.to_dict() for res in results] @@ -625,9 +629,9 @@ class Bot(TelegramObject): 'results': results} if cache_time is not None: - data['cache_time'] = cache_time + data['cache_time'] = int(cache_time) if is_personal is not None: - data['is_personal'] = is_personal + data['is_personal'] = bool(is_personal) if next_offset is not None: data['next_offset'] = next_offset diff --git a/telegram/choseninlineresult.py b/telegram/choseninlineresult.py index 16cc7cb24..87071833e 100644 --- a/telegram/choseninlineresult.py +++ b/telegram/choseninlineresult.py @@ -46,8 +46,7 @@ class ChosenInlineResult(TelegramObject): def __init__(self, result_id, from_user, - query, - **kwargs): + query): # Required self.result_id = result_id self.from_user = from_user @@ -64,8 +63,8 @@ class ChosenInlineResult(TelegramObject): """ if not data: return None - - data['from_user'] = User.de_json(data.get('from')) + data = data.copy() + data['from_user'] = User.de_json(data.pop('from')) return ChosenInlineResult(**data) diff --git a/telegram/inlinequery.py b/telegram/inlinequery.py index 0997e2eac..f5165cff7 100644 --- a/telegram/inlinequery.py +++ b/telegram/inlinequery.py @@ -64,11 +64,10 @@ class InlineQuery(TelegramObject): """ if not data: return None + data = data.copy() + data['from_user'] = User.de_json(data.pop('from')) - data_ = data.copy() # Copy data so we can pop 'from' - data_['from_user'] = User.de_json(data_.pop('from')) - - return InlineQuery(**data_) + return InlineQuery(**data) def to_dict(self): """ diff --git a/telegram/inlinequeryresult.py b/telegram/inlinequeryresult.py index 547f46ec1..bc6385ce8 100644 --- a/telegram/inlinequeryresult.py +++ b/telegram/inlinequeryresult.py @@ -22,6 +22,7 @@ https://core.telegram.org/bots/api#inline-mode """ from telegram import TelegramObject +from telegram.utils.validate import validate_string class InlineQueryResult(TelegramObject): @@ -95,25 +96,38 @@ class InlineQueryResultArticle(InlineQueryResult): id, title, message_text, - **kwargs): + parse_mode=None, + disable_web_page_preview=None, + url=None, + hide_url=None, + description=None, + thumb_url=None, + thumb_width=None, + thumb_height=None): + + validate_string(title, 'title') + validate_string(message_text, 'message_text') + validate_string(url, 'url') + validate_string(description, 'description') + validate_string(thumb_url, 'thumb_url') + validate_string(parse_mode, 'parse_mode') + # Required super(InlineQueryResultArticle, self).__init__('article', id) self.title = title self.message_text = message_text # Optional - self.parse_mode = kwargs.get('parse_mode', '') - self.disable_web_page_preview = kwargs.get('disable_web_page_preview', - False) - self.url = kwargs.get('url', '') - self.hide_url = kwargs.get('hide_url', False) - self.description = kwargs.get('description', '') - self.thumb_url = kwargs.get('thumb_url', '') - self.parse_mode = kwargs.get('parse_mode', '') - if 'thumb_width' in kwargs: - self.thumb_width = int(kwargs['thumb_width']) - if 'thumb_height' in kwargs: - self.thumb_height = int(kwargs['thumb_height']) + self.parse_mode = parse_mode + self.disable_web_page_preview = bool(disable_web_page_preview) + self.url = url + self.hide_url = bool(hide_url) + self.description = description + self.thumb_url = thumb_url + if thumb_width is not None: + self.thumb_width = int(thumb_width) + if thumb_height is not None: + self.thumb_height = int(thumb_height) @staticmethod def de_json(data): @@ -126,6 +140,8 @@ class InlineQueryResultArticle(InlineQueryResult): """ if not data: return None + data = data.copy() + data.pop('type', None) return InlineQueryResultArticle(**data) @@ -168,25 +184,42 @@ class InlineQueryResultPhoto(InlineQueryResult): id, photo_url, thumb_url, - **kwargs): + mime_type=None, + photo_width=None, + photo_height=None, + title=None, + description=None, + caption=None, + message_text=None, + parse_mode=None, + disable_web_page_preview=None): + + validate_string(photo_url, 'photo_url') + validate_string(thumb_url, 'thumb_url') + validate_string(mime_type, 'mime_type') + validate_string(title, 'title') + validate_string(description, 'description') + validate_string(caption, 'caption') + validate_string(message_text, 'message_text') + validate_string(parse_mode, 'parse_mode') + # Required super(InlineQueryResultPhoto, self).__init__('photo', id) self.photo_url = photo_url self.thumb_url = thumb_url # Optional - self.mime_type = kwargs.get('mime_type', 'image/jpeg') - if 'photo_width' in kwargs: - self.photo_width = int(kwargs['photo_width']) - if 'photo_height' in kwargs: - self.photo_height = int(kwargs['photo_height']) - self.title = kwargs.get('title', '') - self.description = kwargs.get('description', '') - self.caption = kwargs.get('caption', '') - self.message_text = kwargs.get('message_text', '') - self.parse_mode = kwargs.get('parse_mode', '') - self.disable_web_page_preview = kwargs.get('disable_web_page_preview', - False) + self.mime_type = mime_type + if photo_width is not None: + self.photo_width = int(photo_width) + if photo_height is not None: + self.photo_height = int(photo_height) + self.title = title + self.description = description + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = bool(disable_web_page_preview) @staticmethod def de_json(data): @@ -199,6 +232,8 @@ class InlineQueryResultPhoto(InlineQueryResult): """ if not data: return None + data = data.copy() + data.pop('type', None) return InlineQueryResultPhoto(**data) @@ -237,23 +272,36 @@ class InlineQueryResultGif(InlineQueryResult): id, gif_url, thumb_url, - **kwargs): + gif_width=None, + gif_height=None, + title=None, + caption=None, + message_text=None, + parse_mode=None, + disable_web_page_preview=None): + + validate_string(gif_url, 'gif_url') + validate_string(thumb_url, 'thumb_url') + validate_string(title, 'title') + validate_string(caption, 'caption') + validate_string(message_text, 'message_text') + validate_string(parse_mode, 'parse_mode') + # Required super(InlineQueryResultGif, self).__init__('gif', id) self.gif_url = gif_url self.thumb_url = thumb_url # Optional - if 'gif_width' in kwargs: - self.gif_width = int(kwargs['gif_width']) - if 'gif_height' in kwargs: - self.gif_height = int(kwargs['gif_height']) - self.title = kwargs.get('title', '') - self.caption = kwargs.get('caption', '') - self.message_text = kwargs.get('message_text', '') - self.parse_mode = kwargs.get('parse_mode', '') - self.disable_web_page_preview = kwargs.get('disable_web_page_preview', - False) + if gif_width is not None: + self.gif_width = int(gif_width) + if gif_height is not None: + self.gif_height = int(gif_height) + self.title = title + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = bool(disable_web_page_preview) @staticmethod def de_json(data): @@ -266,6 +314,8 @@ class InlineQueryResultGif(InlineQueryResult): """ if not data: return None + data = data.copy() + data.pop('type', None) return InlineQueryResultGif(**data) @@ -304,23 +354,36 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): id, mpeg4_url, thumb_url, - **kwargs): + mpeg4_width=None, + mpeg4_height=None, + title=None, + caption=None, + message_text=None, + parse_mode=None, + disable_web_page_preview=None): + + validate_string(mpeg4_url, 'mpeg4_url') + validate_string(thumb_url, 'thumb_url') + validate_string(title, 'title') + validate_string(caption, 'caption') + validate_string(message_text, 'message_text') + validate_string(parse_mode, 'parse_mode') + # Required super(InlineQueryResultMpeg4Gif, self).__init__('mpeg4_gif', id) self.mpeg4_url = mpeg4_url self.thumb_url = thumb_url # Optional - if 'mpeg4_width' in kwargs: - self.mpeg4_width = int(kwargs['mpeg4_width']) - if 'mpeg4_height' in kwargs: - self.mpeg4_height = int(kwargs['mpeg4_height']) - self.title = kwargs.get('title', '') - self.caption = kwargs.get('caption', '') - self.message_text = kwargs.get('message_text', '') - self.parse_mode = kwargs.get('parse_mode', '') - self.disable_web_page_preview = kwargs.get('disable_web_page_preview', - False) + if mpeg4_width is not None: + self.mpeg4_width = int(mpeg4_width) + if mpeg4_height is not None: + self.mpeg4_height = int(mpeg4_height) + self.title = title + self.caption = caption + self.message_text = message_text + self.parse_mode = parse_mode + self.disable_web_page_preview = bool(disable_web_page_preview) @staticmethod def de_json(data): @@ -333,6 +396,8 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): """ if not data: return None + data = data.copy() + data.pop('type', None) return InlineQueryResultMpeg4Gif(**data) @@ -380,7 +445,23 @@ class InlineQueryResultVideo(InlineQueryResult): thumb_url, title, message_text, - **kwargs): + video_width=None, + video_height=None, + video_duration=None, + description=None, + caption=None, + parse_mode=None, + disable_web_page_preview=None): + + validate_string(video_url, 'video_url') + validate_string(mime_type, 'mime_type') + validate_string(thumb_url, 'thumb_url') + validate_string(title, 'title') + validate_string(message_text, 'message_text') + validate_string(description, 'description') + validate_string(caption, 'caption') + validate_string(parse_mode, 'parse_mode') + # Required super(InlineQueryResultVideo, self).__init__('video', id) self.video_url = video_url @@ -390,17 +471,16 @@ class InlineQueryResultVideo(InlineQueryResult): self.message_text = message_text # Optional - if 'video_width' in kwargs: - self.video_width = int(kwargs['video_width']) - if 'video_height' in kwargs: - self.video_height = int(kwargs['video_height']) - if 'video_duration' in kwargs: - self.video_duration = int(kwargs['video_duration']) - self.description = kwargs.get('description', '') - self.caption = kwargs.get('caption', '') - self.parse_mode = kwargs.get('parse_mode', '') - self.disable_web_page_preview = kwargs.get('disable_web_page_preview', - False) + if video_width is not None: + self.video_width = int(video_width) + if video_height is not None: + self.video_height = int(video_height) + if video_duration is not None: + self.video_duration = int(video_duration) + self.description = description + self.caption = caption + self.parse_mode = parse_mode + self.disable_web_page_preview = bool(disable_web_page_preview) @staticmethod def de_json(data): @@ -413,5 +493,7 @@ class InlineQueryResultVideo(InlineQueryResult): """ if not data: return None + data = data.copy() + data.pop('type', None) return InlineQueryResultVideo(**data) diff --git a/telegram/utils/validate.py b/telegram/utils/validate.py new file mode 100644 index 000000000..3b6f7c092 --- /dev/null +++ b/telegram/utils/validate.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2016 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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/]. + +"""This module contains functions to validate function arguments""" + +try: + type(basestring) +except NameError: + basestring = str + + +def validate_string(arg, name): + """ + Validate a string argument. Raises a ValueError if `arg` is neither an + instance of basestring (Python 2) or str (Python 3) nor None. + + Args: + arg (basestring): The value to be tested + name (str): The name of the argument, for the error message + """ + if not isinstance(arg, basestring) and arg is not None: + raise ValueError(name + " is not a string") diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 6da4811dc..872037aae 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -51,9 +51,6 @@ class ChosenInlineResultTest(BaseTest, unittest.TestCase): } def test_choseninlineresult_de_json(self): - """Test ChosenInlineResult.de_json() method""" - print('Testing ChosenInlineResult.de_json()') - result = telegram.ChosenInlineResult.de_json(self.json_dict) self.assertEqual(result.result_id, self.result_id) @@ -62,17 +59,11 @@ class ChosenInlineResultTest(BaseTest, unittest.TestCase): self.assertEqual(result.query, self.query) def test_choseninlineresult_to_json(self): - """Test ChosenInlineResult.to_json() method""" - print('Testing ChosenInlineResult.to_json()') - result = telegram.ChosenInlineResult.de_json(self.json_dict) self.assertTrue(self.is_json(result.to_json())) def test_choseninlineresult_to_dict(self): - """Test ChosenInlineResult.to_dict() method""" - print('Testing ChosenInlineResult.to_dict()') - result = telegram.ChosenInlineResult.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(result)) diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index ec18eefdb..df08998f0 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -53,9 +53,6 @@ class InlineQueryTest(BaseTest, unittest.TestCase): } def test_inlinequery_de_json(self): - """Test InlineQuery.de_json() method""" - print('Testing InlineQuery.de_json()') - inlinequery = telegram.InlineQuery.de_json(self.json_dict) self.assertEqual(inlinequery.id, self.id) @@ -65,17 +62,11 @@ class InlineQueryTest(BaseTest, unittest.TestCase): self.assertEqual(inlinequery.offset, self.offset) def test_inlinequery_to_json(self): - """Test InlineQuery.to_json() method""" - print('Testing InlineQuery.to_json()') - inlinequery = telegram.InlineQuery.de_json(self.json_dict) self.assertTrue(self.is_json(inlinequery.to_json())) def test_inlinequery_to_dict(self): - """Test InlineQuery.to_dict() method""" - print('Testing InlineQuery.to_dict()') - inlinequery = telegram.InlineQuery.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(inlinequery)) diff --git a/tests/test_inlineresult.py b/tests/test_inlineresult.py index 7abd0d4bd..5e73189f4 100644 --- a/tests/test_inlineresult.py +++ b/tests/test_inlineresult.py @@ -66,9 +66,6 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): } def test_article_de_json(self): - """Test InlineQueryResultArticle.de_json() method""" - print('Testing InlineQueryResultArticle.de_json()') - article = telegram.InlineQueryResultArticle.de_json(self.json_dict) self.assertEqual(article.type, self.type) @@ -86,17 +83,11 @@ class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): self.assertEqual(article.thumb_width, self.thumb_width) def test_article_to_json(self): - """Test InlineQueryResultArticle.to_json() method""" - print('Testing InlineQueryResultArticle.to_json()') - article = telegram.InlineQueryResultArticle.de_json(self.json_dict) self.assertTrue(self.is_json(article.to_json())) def test_article_to_dict(self): - """Test InlineQueryResultArticle.to_dict() method""" - print('Testing InlineQueryResultArticle.to_dict()') - article = \ telegram.InlineQueryResultArticle.de_json(self.json_dict).to_dict() @@ -137,9 +128,6 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): } def test_photo_de_json(self): - """Test InlineQueryResultPhoto.de_json() method""" - print('Testing InlineQueryResultPhoto.de_json()') - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) self.assertEqual(photo.type, self.type) @@ -157,17 +145,11 @@ class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) def test_photo_to_json(self): - """Test InlineQueryResultPhoto.to_json() method""" - print('Testing InlineQueryResultPhoto.to_json()') - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict) self.assertTrue(self.is_json(photo.to_json())) def test_photo_to_dict(self): - """Test InlineQueryResultPhoto.to_dict() method""" - print('Testing InlineQueryResultPhoto.to_dict()') - photo = \ telegram.InlineQueryResultPhoto.de_json(self.json_dict).to_dict() @@ -206,9 +188,6 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): } def test_gif_de_json(self): - """Test InlineQueryResultGif.de_json() method""" - print('Testing InlineQueryResultGif.de_json()') - gif = telegram.InlineQueryResultGif.de_json(self.json_dict) self.assertEqual(gif.type, self.type) @@ -225,17 +204,11 @@ class InlineQueryResultGifTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) def test_gif_to_json(self): - """Test InlineQueryResultGif.to_json() method""" - print('Testing InlineQueryResultGif.to_json()') - gif = telegram.InlineQueryResultGif.de_json(self.json_dict) self.assertTrue(self.is_json(gif.to_json())) def test_gif_to_dict(self): - """Test InlineQueryResultGif.to_dict() method""" - print('Testing InlineQueryResultGif.to_dict()') - gif = telegram.InlineQueryResultGif.de_json(self.json_dict).to_dict() self.assertTrue(self.is_dict(gif)) @@ -273,9 +246,6 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): } def test_mpeg4_de_json(self): - """Test InlineQueryResultMpeg4Gif.de_json() method""" - print('Testing InlineQueryResultMpeg4Gif.de_json()') - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) self.assertEqual(mpeg4.type, self.type) @@ -292,17 +262,11 @@ class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) def test_mpeg4_to_json(self): - """Test InlineQueryResultMpeg4Gif.to_json() method""" - print('Testing InlineQueryResultMpeg4Gif.to_json()') - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict) self.assertTrue(self.is_json(mpeg4.to_json())) def test_mpeg4_to_dict(self): - """Test InlineQueryResultMpeg4Gif.to_dict() method""" - print('Testing InlineQueryResultMpeg4Gif.to_dict()') - mpeg4 = \ telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict).to_dict() @@ -347,9 +311,6 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): } def test_video_de_json(self): - """Test InlineQueryResultVideo.de_json() method""" - print('Testing InlineQueryResultVideo.de_json()') - video = telegram.InlineQueryResultVideo.de_json(self.json_dict) self.assertEqual(video.type, self.type) @@ -369,17 +330,11 @@ class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): self.disable_web_page_preview) def test_video_to_json(self): - """Test InlineQueryResultVideo.to_json() method""" - print('Testing InlineQueryResultVideo.to_json()') - video = telegram.InlineQueryResultVideo.de_json(self.json_dict) self.assertTrue(self.is_json(video.to_json())) def test_video_to_dict(self): - """Test InlineQueryResultVideo.to_dict() method""" - print('Testing InlineQueryResultVideo.to_dict()') - video = \ telegram.InlineQueryResultVideo.de_json(self.json_dict).to_dict() From d05fa1275a6d27b1d7f01ff5198a94963d7b3b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 21 Feb 2016 12:52:47 +0100 Subject: [PATCH 20/34] use timed tests and flaky --- requirements-dev.txt | 1 + tests/test_audio.py | 21 +++++++++++++++++++++ tests/test_bot.py | 24 ++++++++++++++++++++++++ tests/test_document.py | 17 +++++++++++++++++ tests/test_photo.py | 17 +++++++++++++++++ tests/test_sticker.py | 13 +++++++++++++ tests/test_video.py | 21 +++++++++++++++++++++ tests/test_voice.py | 21 +++++++++++++++++++++ 8 files changed, 135 insertions(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 99bad0940..3cd235bb0 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,3 +3,4 @@ nose pep257 pylint unittest2 +flaky \ No newline at end of file diff --git a/tests/test_audio.py b/tests/test_audio.py index bbffe815e..eda192248 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -50,6 +53,8 @@ class AudioTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_send_audio_required_args_only(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - With required arguments only') @@ -67,6 +72,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) + @flaky + @timed(10) def test_send_audio_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - With all arguments') @@ -89,6 +96,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) + @flaky + @timed(10) def test_send_audio_mp3_file(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File') @@ -109,6 +118,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) + @flaky + @timed(10) def test_send_audio_mp3_file_custom_filename(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File with custom filename') @@ -130,6 +141,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) + @flaky + @timed(10) def test_send_audio_mp3_url_file(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File by URL') @@ -150,6 +163,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) + @flaky + @timed(10) def test_send_audio_resend(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - Resend by file_id') @@ -203,6 +218,8 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio['mime_type'], self.mime_type) self.assertEqual(audio['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_audio_empty_file(self): print('Testing bot.sendAudio - Null file') @@ -215,6 +232,8 @@ class AudioTest(BaseTest, unittest.TestCase): lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_audio_empty_file_id(self): print('Testing bot.sendAudio - Empty file_id') @@ -227,6 +246,8 @@ class AudioTest(BaseTest, unittest.TestCase): lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_audio_without_required_args(self): print('Testing bot.sendAudio - Without required arguments') diff --git a/tests/test_bot.py b/tests/test_bot.py index 6e6fd02fb..e902359aa 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -23,6 +23,7 @@ import os from datetime import datetime import sys +from flaky import flaky if sys.version_info[0:2] == (2, 6): import unittest2 as unittest @@ -33,11 +34,14 @@ sys.path.append('.') import telegram from tests.base import BaseTest +from nose.tools import timed class BotTest(BaseTest, unittest.TestCase): """This object represents Tests for Telegram Bot.""" + @flaky + @timed(10) def testGetMe(self): '''Test the telegram.Bot getMe method''' print('Testing getMe') @@ -50,6 +54,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(bot.username, 'PythonTelegramBot') self.assertEqual(bot.name, '@PythonTelegramBot') + @flaky + @timed(10) def testSendMessage(self): '''Test the telegram.Bot sendMessage method''' print('Testing sendMessage') @@ -60,6 +66,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') self.assertTrue(isinstance(message.date, datetime)) + @flaky + @timed(10) def testGetUpdates(self): '''Test the telegram.Bot getUpdates method''' print('Testing getUpdates') @@ -69,6 +77,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(updates[0].to_json())) self.assertTrue(isinstance(updates[0], telegram.Update)) + @flaky + @timed(10) def testForwardMessage(self): '''Test the telegram.Bot forwardMessage method''' print('Testing forwardMessage') @@ -81,6 +91,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.forward_from.username, 'leandrotoledo') self.assertTrue(isinstance(message.forward_date, datetime)) + @flaky + @timed(10) def testSendPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing sendPhoto - File') @@ -92,6 +104,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_size, 1451) self.assertEqual(message.caption, 'testSendPhoto') + @flaky + @timed(10) def testResendPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing sendPhoto - Resend') @@ -101,6 +115,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_id, 'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI') + @flaky + @timed(10) def testSendJPGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendJPGURLPhoto - URL') @@ -110,6 +126,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 822) + @flaky + @timed(10) def testSendPNGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendPNGURLPhoto - URL') @@ -119,6 +137,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 684) + @flaky + @timed(10) def testSendGIFURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendGIFURLPhoto - URL') @@ -128,6 +148,8 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 684) + @flaky + @timed(10) def testSendChatAction(self): '''Test the telegram.Bot sendChatAction method''' print('Testing sendChatAction - ChatAction.TYPING') @@ -135,6 +157,8 @@ class BotTest(BaseTest, unittest.TestCase): self._bot.sendChatAction(action=telegram.ChatAction.TYPING, chat_id=self._chat_id) + @flaky + @timed(10) def testGetUserProfilePhotos(self): '''Test the telegram.Bot getUserProfilePhotos method''' print('Testing getUserProfilePhotos') diff --git a/tests/test_document.py b/tests/test_document.py index 9c5a4c116..a33100e35 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -51,6 +54,8 @@ class DocumentTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_send_document_png_file(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - PNG File') @@ -67,6 +72,8 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, self.mime_type) self.assertEqual(document.file_size, self.file_size) + @flaky + @timed(10) def test_send_document_png_file_with_custom_file_name(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - PNG File with custom filename') @@ -84,6 +91,8 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, self.mime_type) self.assertEqual(document.file_size, self.file_size) + @flaky + @timed(10) def test_send_document_url_gif_file(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - GIF File by URL') @@ -100,6 +109,8 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, 'image/gif') self.assertEqual(document.file_size, 3878) + @flaky + @timed(10) def test_send_document_resend(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - Resend by file_id') @@ -147,6 +158,8 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document['mime_type'], self.mime_type) self.assertEqual(document['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_document_empty_file(self): print('Testing bot.sendDocument - Null file') @@ -159,6 +172,8 @@ class DocumentTest(BaseTest, unittest.TestCase): lambda: self._bot.sendDocument(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_document_empty_file_id(self): print('Testing bot.sendDocument - Empty file_id') @@ -171,6 +186,8 @@ class DocumentTest(BaseTest, unittest.TestCase): lambda: self._bot.sendDocument(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_document_without_required_args(self): print('Testing bot.sendDocument - Without required arguments') diff --git a/tests/test_photo.py b/tests/test_photo.py index 0cb71309f..06ccba2fb 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -53,6 +56,8 @@ class PhotoTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_sendphotoo_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendPhoto - With all arguments') @@ -79,6 +84,8 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) + @flaky + @timed(10) def test_send_photo_jpg_file(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - JPG File') @@ -102,6 +109,8 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.height, self.height) self.assertEqual(photo.file_size, self.file_size) + @flaky + @timed(10) def test_send_photo_url_jpg_file(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - JPG File by URL') @@ -125,6 +134,8 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.height, self.height) self.assertEqual(photo.file_size, self.file_size) + @flaky + @timed(10) def test_send_photo_resend(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - Resend by file_id') @@ -177,6 +188,8 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo['height'], self.height) self.assertEqual(photo['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_photo_empty_file(self): print('Testing bot.sendPhoto - Null file') @@ -189,6 +202,8 @@ class PhotoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendPhoto(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_photo_empty_file_id(self): print('Testing bot.sendPhoto - Empty file_id') @@ -201,6 +216,8 @@ class PhotoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendPhoto(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_photo_without_required_args(self): print('Testing bot.sendPhoto - Without required arguments') diff --git a/tests/test_sticker.py b/tests/test_sticker.py index aafa0b23c..b2609612e 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -49,9 +52,13 @@ class StickerTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_send_sticker_file(self): pass + @flaky + @timed(10) def test_send_sticker_resend(self): """Test telegram.Bot sendSticker method""" print('Testing bot.sendSticker - Resend by file_id') @@ -99,6 +106,8 @@ class StickerTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(sticker['thumb'], telegram.PhotoSize)) self.assertEqual(sticker['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_sticker_empty_file(self): print('Testing bot.sendSticker - Null file') @@ -111,6 +120,8 @@ class StickerTest(BaseTest, unittest.TestCase): lambda: self._bot.sendSticker(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_sticker_empty_file_id(self): print('Testing bot.sendSticker - Empty file_id') @@ -123,6 +134,8 @@ class StickerTest(BaseTest, unittest.TestCase): lambda: self._bot.sendSticker(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_sticker_without_required_args(self): print('Testing bot.sendSticker - Without required arguments') diff --git a/tests/test_video.py b/tests/test_video.py index 4e0a1dad7..c58a56942 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -55,6 +58,8 @@ class VideoTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_send_video_required_args_only(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - With required arguments only') @@ -73,6 +78,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) + @flaky + @timed(10) def test_send_video_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendVideo - With all arguments') @@ -95,6 +102,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) + @flaky + @timed(10) def test_send_video_mp4_file(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File') @@ -117,6 +126,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) + @flaky + @timed(10) def test_send_video_mp4_file_with_custom_filename(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File with custom filename') @@ -140,6 +151,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) + @flaky + @timed(10) def test_send_video_mp4_file_url(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File by URL') @@ -162,6 +175,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) + @flaky + @timed(10) def test_send_video_resend(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - Resend by file_id') @@ -216,6 +231,8 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video['mime_type'], self.mime_type) self.assertEqual(video['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_video_empty_file(self): print('Testing bot.sendVideo - Null file') @@ -228,6 +245,8 @@ class VideoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVideo(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_video_empty_file_id(self): print('Testing bot.sendVideo - Empty file_id') @@ -240,6 +259,8 @@ class VideoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVideo(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_video_without_required_args(self): print('Testing bot.sendVideo - Without required arguments') diff --git a/tests/test_voice.py b/tests/test_voice.py index cde7340cd..6150c6855 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -22,6 +22,9 @@ import os import unittest import sys +from nose.tools import timed +from flaky import flaky + sys.path.append('.') import telegram @@ -46,6 +49,8 @@ class VoiceTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } + @flaky + @timed(10) def test_send_voice_required_args_only(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - With required arguments only') @@ -61,6 +66,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) + @flaky + @timed(10) def test_send_voice_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendVoice - With all arguments') @@ -79,6 +86,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) + @flaky + @timed(10) def test_send_voice_ogg_file(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File') @@ -95,6 +104,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) + @flaky + @timed(10) def test_send_voice_ogg_file_with_custom_filename(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File with custom filename') @@ -112,6 +123,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) + @flaky + @timed(10) def test_send_voice_ogg_url_file(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File by URL') @@ -128,6 +141,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) + @flaky + @timed(10) def test_send_voice_resend(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Resend by file_id') @@ -173,6 +188,8 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice['mime_type'], self.mime_type) self.assertEqual(voice['file_size'], self.file_size) + @flaky + @timed(10) def test_error_send_voice_empty_file(self): print('Testing bot.sendVoice - Null file') @@ -185,6 +202,8 @@ class VoiceTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVoice(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_send_voice_empty_file_id(self): print('Testing bot.sendVoice - Empty file_id') @@ -197,6 +216,8 @@ class VoiceTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVoice(chat_id=self._chat_id, **json_dict)) + @flaky + @timed(10) def test_error_voice_without_required_args(self): print('Testing bot.sendVoice - Without required arguments') From ec13a36bdd8409c1fb506a0806f9dd3fc1f1e151 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Mon, 22 Feb 2016 01:38:26 +0200 Subject: [PATCH 21/34] unitests: use home brewed timeout for tests --- tests/base.py | 35 +++++++++++++++++++++++++++++++++++ tests/test_audio.py | 21 ++++++++++----------- tests/test_bot.py | 25 ++++++++++++------------- tests/test_document.py | 17 ++++++++--------- tests/test_photo.py | 17 ++++++++--------- tests/test_sticker.py | 13 ++++++------- tests/test_video.py | 21 ++++++++++----------- tests/test_voice.py | 21 ++++++++++----------- 8 files changed, 99 insertions(+), 71 deletions(-) diff --git a/tests/base.py b/tests/base.py index 398f64bad..58b44f58d 100644 --- a/tests/base.py +++ b/tests/base.py @@ -21,6 +21,11 @@ import os import sys +import signal +import traceback + +from nose.tools import make_decorator, TimeExpired + sys.path.append('.') import json @@ -54,3 +59,33 @@ class BaseTest(object): return True return False + + +class TestTimedOut(AssertionError): + + def __init__(self, time_limit, frame): + super(TestTimedOut, self).__init__('time_limit={0}\n{1}'.format( + time_limit, ''.join(traceback.format_stack(frame)))) + self.time_limit = time_limit + self.frame = frame + + +def timeout(time_limit): + def decorator(func): + def timed_out(_signum, frame): + raise TestTimedOut(time_limit, frame) + + def newfunc(*args, **kwargs): + orig_handler = signal.signal(signal.SIGALRM, timed_out) + signal.alarm(time_limit) + try: + rc = func(*args, **kwargs) + finally: + signal.alarm(0) + signal.signal(signal.SIGALRM, orig_handler) + return rc + + newfunc = make_decorator(func)(newfunc) + return newfunc + + return decorator diff --git a/tests/test_audio.py b/tests/test_audio.py index eda192248..e9cda6198 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class AudioTest(BaseTest, unittest.TestCase): @@ -54,7 +53,7 @@ class AudioTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_send_audio_required_args_only(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - With required arguments only') @@ -73,7 +72,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_audio_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - With all arguments') @@ -97,7 +96,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_audio_mp3_file(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File') @@ -119,7 +118,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_audio_mp3_file_custom_filename(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File with custom filename') @@ -142,7 +141,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_audio_mp3_url_file(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - MP3 File by URL') @@ -164,7 +163,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_audio_resend(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendAudio - Resend by file_id') @@ -219,7 +218,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_audio_empty_file(self): print('Testing bot.sendAudio - Null file') @@ -233,7 +232,7 @@ class AudioTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_audio_empty_file_id(self): print('Testing bot.sendAudio - Empty file_id') @@ -247,7 +246,7 @@ class AudioTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_audio_without_required_args(self): print('Testing bot.sendAudio - Without required arguments') diff --git a/tests/test_bot.py b/tests/test_bot.py index e902359aa..698eee9a9 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -33,15 +33,14 @@ else: sys.path.append('.') import telegram -from tests.base import BaseTest -from nose.tools import timed +from tests.base import BaseTest, timeout class BotTest(BaseTest, unittest.TestCase): """This object represents Tests for Telegram Bot.""" @flaky - @timed(10) + @timeout(10) def testGetMe(self): '''Test the telegram.Bot getMe method''' print('Testing getMe') @@ -55,7 +54,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(bot.name, '@PythonTelegramBot') @flaky - @timed(10) + @timeout(10) def testSendMessage(self): '''Test the telegram.Bot sendMessage method''' print('Testing sendMessage') @@ -67,7 +66,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(message.date, datetime)) @flaky - @timed(10) + @timeout(10) def testGetUpdates(self): '''Test the telegram.Bot getUpdates method''' print('Testing getUpdates') @@ -78,7 +77,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(updates[0], telegram.Update)) @flaky - @timed(10) + @timeout(10) def testForwardMessage(self): '''Test the telegram.Bot forwardMessage method''' print('Testing forwardMessage') @@ -92,7 +91,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(message.forward_date, datetime)) @flaky - @timed(10) + @timeout(10) def testSendPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing sendPhoto - File') @@ -105,7 +104,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, 'testSendPhoto') @flaky - @timed(10) + @timeout(10) def testResendPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing sendPhoto - Resend') @@ -116,7 +115,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_id, 'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI') @flaky - @timed(10) + @timeout(10) def testSendJPGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendJPGURLPhoto - URL') @@ -127,7 +126,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_size, 822) @flaky - @timed(10) + @timeout(10) def testSendPNGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendPNGURLPhoto - URL') @@ -138,7 +137,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_size, 684) @flaky - @timed(10) + @timeout(10) def testSendGIFURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' print('Testing testSendGIFURLPhoto - URL') @@ -149,7 +148,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_size, 684) @flaky - @timed(10) + @timeout(10) def testSendChatAction(self): '''Test the telegram.Bot sendChatAction method''' print('Testing sendChatAction - ChatAction.TYPING') @@ -158,7 +157,7 @@ class BotTest(BaseTest, unittest.TestCase): chat_id=self._chat_id) @flaky - @timed(10) + @timeout(10) def testGetUserProfilePhotos(self): '''Test the telegram.Bot getUserProfilePhotos method''' print('Testing getUserProfilePhotos') diff --git a/tests/test_document.py b/tests/test_document.py index a33100e35..a6f659ba2 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class DocumentTest(BaseTest, unittest.TestCase): @@ -55,7 +54,7 @@ class DocumentTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_send_document_png_file(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - PNG File') @@ -73,7 +72,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_document_png_file_with_custom_file_name(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - PNG File with custom filename') @@ -92,7 +91,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_document_url_gif_file(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - GIF File by URL') @@ -110,7 +109,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.file_size, 3878) @flaky - @timed(10) + @timeout(10) def test_send_document_resend(self): """Test telegram.Bot sendDocument method""" print('Testing bot.sendDocument - Resend by file_id') @@ -159,7 +158,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_document_empty_file(self): print('Testing bot.sendDocument - Null file') @@ -173,7 +172,7 @@ class DocumentTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_document_empty_file_id(self): print('Testing bot.sendDocument - Empty file_id') @@ -187,7 +186,7 @@ class DocumentTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_document_without_required_args(self): print('Testing bot.sendDocument - Without required arguments') diff --git a/tests/test_photo.py b/tests/test_photo.py index 06ccba2fb..6e76ff08b 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class PhotoTest(BaseTest, unittest.TestCase): @@ -57,7 +56,7 @@ class PhotoTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_sendphotoo_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendPhoto - With all arguments') @@ -85,7 +84,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) @flaky - @timed(10) + @timeout(10) def test_send_photo_jpg_file(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - JPG File') @@ -110,7 +109,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_photo_url_jpg_file(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - JPG File by URL') @@ -135,7 +134,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_photo_resend(self): """Test telegram.Bot sendPhoto method""" print('Testing bot.sendPhoto - Resend by file_id') @@ -189,7 +188,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_photo_empty_file(self): print('Testing bot.sendPhoto - Null file') @@ -203,7 +202,7 @@ class PhotoTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_photo_empty_file_id(self): print('Testing bot.sendPhoto - Empty file_id') @@ -217,7 +216,7 @@ class PhotoTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_photo_without_required_args(self): print('Testing bot.sendPhoto - Without required arguments') diff --git a/tests/test_sticker.py b/tests/test_sticker.py index b2609612e..9cf29c4e1 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class StickerTest(BaseTest, unittest.TestCase): @@ -53,12 +52,12 @@ class StickerTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_send_sticker_file(self): pass @flaky - @timed(10) + @timeout(10) def test_send_sticker_resend(self): """Test telegram.Bot sendSticker method""" print('Testing bot.sendSticker - Resend by file_id') @@ -107,7 +106,7 @@ class StickerTest(BaseTest, unittest.TestCase): self.assertEqual(sticker['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_sticker_empty_file(self): print('Testing bot.sendSticker - Null file') @@ -121,7 +120,7 @@ class StickerTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_sticker_empty_file_id(self): print('Testing bot.sendSticker - Empty file_id') @@ -135,7 +134,7 @@ class StickerTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_sticker_without_required_args(self): print('Testing bot.sendSticker - Without required arguments') diff --git a/tests/test_video.py b/tests/test_video.py index c58a56942..b06aa2196 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class VideoTest(BaseTest, unittest.TestCase): @@ -59,7 +58,7 @@ class VideoTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_send_video_required_args_only(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - With required arguments only') @@ -79,7 +78,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_video_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendVideo - With all arguments') @@ -103,7 +102,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) @flaky - @timed(10) + @timeout(10) def test_send_video_mp4_file(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File') @@ -127,7 +126,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) @flaky - @timed(10) + @timeout(10) def test_send_video_mp4_file_with_custom_filename(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File with custom filename') @@ -152,7 +151,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) @flaky - @timed(10) + @timeout(10) def test_send_video_mp4_file_url(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - MP4 File by URL') @@ -176,7 +175,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) @flaky - @timed(10) + @timeout(10) def test_send_video_resend(self): """Test telegram.Bot sendVideo method""" print('Testing bot.sendVideo - Resend by file_id') @@ -232,7 +231,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_video_empty_file(self): print('Testing bot.sendVideo - Null file') @@ -246,7 +245,7 @@ class VideoTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_video_empty_file_id(self): print('Testing bot.sendVideo - Empty file_id') @@ -260,7 +259,7 @@ class VideoTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_video_without_required_args(self): print('Testing bot.sendVideo - Without required arguments') diff --git a/tests/test_voice.py b/tests/test_voice.py index 6150c6855..0ddfcf88a 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -22,13 +22,12 @@ import os import unittest import sys -from nose.tools import timed from flaky import flaky sys.path.append('.') import telegram -from tests.base import BaseTest +from tests.base import BaseTest, timeout class VoiceTest(BaseTest, unittest.TestCase): @@ -50,7 +49,7 @@ class VoiceTest(BaseTest, unittest.TestCase): } @flaky - @timed(10) + @timeout(10) def test_send_voice_required_args_only(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - With required arguments only') @@ -67,7 +66,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_voice_all_args(self): """Test telegram.Bot sendAudio method""" print('Testing bot.sendVoice - With all arguments') @@ -87,7 +86,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_voice_ogg_file(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File') @@ -105,7 +104,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_voice_ogg_file_with_custom_filename(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File with custom filename') @@ -124,7 +123,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_voice_ogg_url_file(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Ogg File by URL') @@ -142,7 +141,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) @flaky - @timed(10) + @timeout(10) def test_send_voice_resend(self): """Test telegram.Bot sendVoice method""" print('Testing bot.sendVoice - Resend by file_id') @@ -189,7 +188,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice['file_size'], self.file_size) @flaky - @timed(10) + @timeout(10) def test_error_send_voice_empty_file(self): print('Testing bot.sendVoice - Null file') @@ -203,7 +202,7 @@ class VoiceTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_send_voice_empty_file_id(self): print('Testing bot.sendVoice - Empty file_id') @@ -217,7 +216,7 @@ class VoiceTest(BaseTest, unittest.TestCase): **json_dict)) @flaky - @timed(10) + @timeout(10) def test_error_voice_without_required_args(self): print('Testing bot.sendVoice - Without required arguments') From e0cf0abb1b0405ada8bc08c79ed9efe9abb7dd46 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Mon, 22 Feb 2016 01:52:31 +0200 Subject: [PATCH 22/34] flaky tests: try up to 3 times, need to succeed once --- tests/base.py | 5 ++--- tests/test_audio.py | 18 +++++++++--------- tests/test_bot.py | 22 +++++++++++----------- tests/test_document.py | 14 +++++++------- tests/test_photo.py | 14 +++++++------- tests/test_sticker.py | 10 +++++----- tests/test_video.py | 18 +++++++++--------- tests/test_voice.py | 18 +++++++++--------- 8 files changed, 59 insertions(+), 60 deletions(-) diff --git a/tests/base.py b/tests/base.py index 58b44f58d..75187face 100644 --- a/tests/base.py +++ b/tests/base.py @@ -24,7 +24,7 @@ import sys import signal import traceback -from nose.tools import make_decorator, TimeExpired +from nose.tools import make_decorator sys.path.append('.') @@ -64,8 +64,7 @@ class BaseTest(object): class TestTimedOut(AssertionError): def __init__(self, time_limit, frame): - super(TestTimedOut, self).__init__('time_limit={0}\n{1}'.format( - time_limit, ''.join(traceback.format_stack(frame)))) + super(TestTimedOut, self).__init__('time_limit={0}'.format(time_limit)) self.time_limit = time_limit self.frame = frame diff --git a/tests/test_audio.py b/tests/test_audio.py index e9cda6198..0a767ae7b 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -52,7 +52,7 @@ class AudioTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_required_args_only(self): """Test telegram.Bot sendAudio method""" @@ -71,7 +71,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_all_args(self): """Test telegram.Bot sendAudio method""" @@ -95,7 +95,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_mp3_file(self): """Test telegram.Bot sendAudio method""" @@ -117,7 +117,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_mp3_file_custom_filename(self): """Test telegram.Bot sendAudio method""" @@ -140,7 +140,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_mp3_url_file(self): """Test telegram.Bot sendAudio method""" @@ -162,7 +162,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) self.assertEqual(audio.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_audio_resend(self): """Test telegram.Bot sendAudio method""" @@ -217,7 +217,7 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio['mime_type'], self.mime_type) self.assertEqual(audio['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_audio_empty_file(self): print('Testing bot.sendAudio - Null file') @@ -231,7 +231,7 @@ class AudioTest(BaseTest, unittest.TestCase): lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_audio_empty_file_id(self): print('Testing bot.sendAudio - Empty file_id') @@ -245,7 +245,7 @@ class AudioTest(BaseTest, unittest.TestCase): lambda: self._bot.sendAudio(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_audio_without_required_args(self): print('Testing bot.sendAudio - Without required arguments') diff --git a/tests/test_bot.py b/tests/test_bot.py index 698eee9a9..fcb1680c8 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -39,7 +39,7 @@ from tests.base import BaseTest, timeout class BotTest(BaseTest, unittest.TestCase): """This object represents Tests for Telegram Bot.""" - @flaky + @flaky(3, 1) @timeout(10) def testGetMe(self): '''Test the telegram.Bot getMe method''' @@ -53,7 +53,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(bot.username, 'PythonTelegramBot') self.assertEqual(bot.name, '@PythonTelegramBot') - @flaky + @flaky(3, 1) @timeout(10) def testSendMessage(self): '''Test the telegram.Bot sendMessage method''' @@ -65,7 +65,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') self.assertTrue(isinstance(message.date, datetime)) - @flaky + @flaky(3, 1) @timeout(10) def testGetUpdates(self): '''Test the telegram.Bot getUpdates method''' @@ -76,7 +76,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(updates[0].to_json())) self.assertTrue(isinstance(updates[0], telegram.Update)) - @flaky + @flaky(3, 1) @timeout(10) def testForwardMessage(self): '''Test the telegram.Bot forwardMessage method''' @@ -90,7 +90,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.forward_from.username, 'leandrotoledo') self.assertTrue(isinstance(message.forward_date, datetime)) - @flaky + @flaky(3, 1) @timeout(10) def testSendPhoto(self): '''Test the telegram.Bot sendPhoto method''' @@ -103,7 +103,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertEqual(message.photo[0].file_size, 1451) self.assertEqual(message.caption, 'testSendPhoto') - @flaky + @flaky(3, 1) @timeout(10) def testResendPhoto(self): '''Test the telegram.Bot sendPhoto method''' @@ -114,7 +114,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_id, 'AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI') - @flaky + @flaky(3, 1) @timeout(10) def testSendJPGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' @@ -125,7 +125,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 822) - @flaky + @flaky(3, 1) @timeout(10) def testSendPNGURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' @@ -136,7 +136,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 684) - @flaky + @flaky(3, 1) @timeout(10) def testSendGIFURLPhoto(self): '''Test the telegram.Bot sendPhoto method''' @@ -147,7 +147,7 @@ class BotTest(BaseTest, unittest.TestCase): self.assertTrue(self.is_json(message.to_json())) self.assertEqual(message.photo[0].file_size, 684) - @flaky + @flaky(3, 1) @timeout(10) def testSendChatAction(self): '''Test the telegram.Bot sendChatAction method''' @@ -156,7 +156,7 @@ class BotTest(BaseTest, unittest.TestCase): self._bot.sendChatAction(action=telegram.ChatAction.TYPING, chat_id=self._chat_id) - @flaky + @flaky(3, 1) @timeout(10) def testGetUserProfilePhotos(self): '''Test the telegram.Bot getUserProfilePhotos method''' diff --git a/tests/test_document.py b/tests/test_document.py index a6f659ba2..a1b7887bf 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -53,7 +53,7 @@ class DocumentTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_send_document_png_file(self): """Test telegram.Bot sendDocument method""" @@ -71,7 +71,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, self.mime_type) self.assertEqual(document.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_document_png_file_with_custom_file_name(self): """Test telegram.Bot sendDocument method""" @@ -90,7 +90,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, self.mime_type) self.assertEqual(document.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_document_url_gif_file(self): """Test telegram.Bot sendDocument method""" @@ -108,7 +108,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, 'image/gif') self.assertEqual(document.file_size, 3878) - @flaky + @flaky(3, 1) @timeout(10) def test_send_document_resend(self): """Test telegram.Bot sendDocument method""" @@ -157,7 +157,7 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document['mime_type'], self.mime_type) self.assertEqual(document['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_document_empty_file(self): print('Testing bot.sendDocument - Null file') @@ -171,7 +171,7 @@ class DocumentTest(BaseTest, unittest.TestCase): lambda: self._bot.sendDocument(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_document_empty_file_id(self): print('Testing bot.sendDocument - Empty file_id') @@ -185,7 +185,7 @@ class DocumentTest(BaseTest, unittest.TestCase): lambda: self._bot.sendDocument(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_document_without_required_args(self): print('Testing bot.sendDocument - Without required arguments') diff --git a/tests/test_photo.py b/tests/test_photo.py index 6e76ff08b..23b46f8d6 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -55,7 +55,7 @@ class PhotoTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_sendphotoo_all_args(self): """Test telegram.Bot sendAudio method""" @@ -83,7 +83,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) - @flaky + @flaky(3, 1) @timeout(10) def test_send_photo_jpg_file(self): """Test telegram.Bot sendPhoto method""" @@ -108,7 +108,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.height, self.height) self.assertEqual(photo.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_photo_url_jpg_file(self): """Test telegram.Bot sendPhoto method""" @@ -133,7 +133,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.height, self.height) self.assertEqual(photo.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_photo_resend(self): """Test telegram.Bot sendPhoto method""" @@ -187,7 +187,7 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo['height'], self.height) self.assertEqual(photo['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_photo_empty_file(self): print('Testing bot.sendPhoto - Null file') @@ -201,7 +201,7 @@ class PhotoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendPhoto(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_photo_empty_file_id(self): print('Testing bot.sendPhoto - Empty file_id') @@ -215,7 +215,7 @@ class PhotoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendPhoto(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_photo_without_required_args(self): print('Testing bot.sendPhoto - Without required arguments') diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 9cf29c4e1..a62881441 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -51,12 +51,12 @@ class StickerTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_send_sticker_file(self): pass - @flaky + @flaky(3, 1) @timeout(10) def test_send_sticker_resend(self): """Test telegram.Bot sendSticker method""" @@ -105,7 +105,7 @@ class StickerTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(sticker['thumb'], telegram.PhotoSize)) self.assertEqual(sticker['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_sticker_empty_file(self): print('Testing bot.sendSticker - Null file') @@ -119,7 +119,7 @@ class StickerTest(BaseTest, unittest.TestCase): lambda: self._bot.sendSticker(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_sticker_empty_file_id(self): print('Testing bot.sendSticker - Empty file_id') @@ -133,7 +133,7 @@ class StickerTest(BaseTest, unittest.TestCase): lambda: self._bot.sendSticker(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_sticker_without_required_args(self): print('Testing bot.sendSticker - Without required arguments') diff --git a/tests/test_video.py b/tests/test_video.py index b06aa2196..685f756c5 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -57,7 +57,7 @@ class VideoTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_required_args_only(self): """Test telegram.Bot sendVideo method""" @@ -77,7 +77,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_all_args(self): """Test telegram.Bot sendAudio method""" @@ -101,7 +101,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_mp4_file(self): """Test telegram.Bot sendVideo method""" @@ -125,7 +125,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_mp4_file_with_custom_filename(self): """Test telegram.Bot sendVideo method""" @@ -150,7 +150,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_mp4_file_url(self): """Test telegram.Bot sendVideo method""" @@ -174,7 +174,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) - @flaky + @flaky(3, 1) @timeout(10) def test_send_video_resend(self): """Test telegram.Bot sendVideo method""" @@ -230,7 +230,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video['mime_type'], self.mime_type) self.assertEqual(video['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_video_empty_file(self): print('Testing bot.sendVideo - Null file') @@ -244,7 +244,7 @@ class VideoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVideo(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_video_empty_file_id(self): print('Testing bot.sendVideo - Empty file_id') @@ -258,7 +258,7 @@ class VideoTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVideo(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_video_without_required_args(self): print('Testing bot.sendVideo - Without required arguments') diff --git a/tests/test_voice.py b/tests/test_voice.py index 0ddfcf88a..68fb50d46 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -48,7 +48,7 @@ class VoiceTest(BaseTest, unittest.TestCase): 'file_size': self.file_size } - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_required_args_only(self): """Test telegram.Bot sendVoice method""" @@ -65,7 +65,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_all_args(self): """Test telegram.Bot sendAudio method""" @@ -85,7 +85,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_ogg_file(self): """Test telegram.Bot sendVoice method""" @@ -103,7 +103,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_ogg_file_with_custom_filename(self): """Test telegram.Bot sendVoice method""" @@ -122,7 +122,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_ogg_url_file(self): """Test telegram.Bot sendVoice method""" @@ -140,7 +140,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) self.assertEqual(voice.file_size, self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_send_voice_resend(self): """Test telegram.Bot sendVoice method""" @@ -187,7 +187,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice['mime_type'], self.mime_type) self.assertEqual(voice['file_size'], self.file_size) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_voice_empty_file(self): print('Testing bot.sendVoice - Null file') @@ -201,7 +201,7 @@ class VoiceTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVoice(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_send_voice_empty_file_id(self): print('Testing bot.sendVoice - Empty file_id') @@ -215,7 +215,7 @@ class VoiceTest(BaseTest, unittest.TestCase): lambda: self._bot.sendVoice(chat_id=self._chat_id, **json_dict)) - @flaky + @flaky(3, 1) @timeout(10) def test_error_voice_without_required_args(self): print('Testing bot.sendVoice - Without required arguments') From a2632b777ae4ef7cbad5ebd29e50249a0b8dff37 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Mon, 22 Feb 2016 02:03:10 +0200 Subject: [PATCH 23/34] travis.yml: enable nosetests --with-flaky --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a7627958f..ac7a00212 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: - pip install -r requirements.txt - pip install -r requirements-dev.txt script: - - nosetests -v --with-coverage --cover-package telegram/ + - nosetests -v --with-coverage --cover-package --with-flaky telegram/ - flake8 telegram - 'if [[ $TRAVIS_PYTHON_VERSION != 2.6 ]]; then pylint -E telegram --disable=no-name-in-module,import-error; fi' after_success: From df8e38818938337b48a10f3c1e1a03f9581c9391 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Tue, 23 Feb 2016 23:32:32 +0200 Subject: [PATCH 24/34] travis.yml: fix nosetests command line --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ac7a00212..51577ef7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: - pip install -r requirements.txt - pip install -r requirements-dev.txt script: - - nosetests -v --with-coverage --cover-package --with-flaky telegram/ + - nosetests -v --with-coverage --cover-package --with-flaky - flake8 telegram - 'if [[ $TRAVIS_PYTHON_VERSION != 2.6 ]]; then pylint -E telegram --disable=no-name-in-module,import-error; fi' after_success: From d5b35e7e1d86a3c05bde2577f066c9cf1416c9ab Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Wed, 24 Feb 2016 00:45:49 +0200 Subject: [PATCH 25/34] unitests: remove docstrings & prints - not needed with nosetests --- tests/test_audio.py | 33 ----------------------------- tests/test_bot.py | 26 ----------------------- tests/test_botan.py | 8 ------- tests/test_chat.py | 12 ----------- tests/test_contact.py | 9 -------- tests/test_document.py | 27 ----------------------- tests/test_emoji.py | 3 --- tests/test_file.py | 29 ------------------------- tests/test_force_replay.py | 12 ----------- tests/test_jobqueue.py | 6 ------ tests/test_location.py | 19 ----------------- tests/test_parse_mode.py | 6 +----- tests/test_photo.py | 27 ----------------------- tests/test_reply_keyboard_hide.py | 12 ----------- tests/test_reply_keyboard_markup.py | 12 ----------- tests/test_sticker.py | 18 ---------------- tests/test_update.py | 9 -------- tests/test_updater.py | 20 ----------------- tests/test_user.py | 15 ------------- tests/test_video.py | 33 ----------------------------- tests/test_voice.py | 33 ----------------------------- 21 files changed, 1 insertion(+), 368 deletions(-) diff --git a/tests/test_audio.py b/tests/test_audio.py index 0a767ae7b..da7ebeb6f 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -55,9 +55,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_required_args_only(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - With required arguments only') - message = self._bot.sendAudio(self._chat_id, self.audio_file) @@ -74,9 +71,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_all_args(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - With all arguments') - message = self._bot.sendAudio(self._chat_id, self.audio_file, duration=self.duration, @@ -98,9 +92,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_mp3_file(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - MP3 File') - message = self._bot.sendAudio(chat_id=self._chat_id, audio=self.audio_file, duration=self.duration, @@ -120,9 +111,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_mp3_file_custom_filename(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - MP3 File with custom filename') - message = self._bot.sendAudio(chat_id=self._chat_id, audio=self.audio_file, duration=self.duration, @@ -143,9 +131,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_mp3_url_file(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - MP3 File by URL') - message = self._bot.sendAudio(chat_id=self._chat_id, audio=self.audio_file_url, duration=self.duration, @@ -165,9 +150,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_audio_resend(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendAudio - Resend by file_id') - message = self._bot.sendAudio(chat_id=self._chat_id, audio=self.audio_file_id, duration=self.duration, @@ -183,9 +165,6 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.mime_type, self.mime_type) def test_audio_de_json(self): - """Test Audio.de_json() method""" - print('Testing Audio.de_json()') - audio = telegram.Audio.de_json(self.json_dict) self.assertEqual(audio.file_id, self.audio_file_id) @@ -196,17 +175,11 @@ class AudioTest(BaseTest, unittest.TestCase): self.assertEqual(audio.file_size, self.file_size) def test_audio_to_json(self): - """Test Audio.to_json() method""" - print('Testing Audio.to_json()') - audio = telegram.Audio.de_json(self.json_dict) self.assertTrue(self.is_json(audio.to_json())) def test_audio_to_dict(self): - """Test Audio.to_dict() method""" - print('Testing Audio.to_dict()') - audio = telegram.Audio.de_json(self.json_dict) self.assertTrue(self.is_dict(audio.to_dict())) @@ -220,8 +193,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_audio_empty_file(self): - print('Testing bot.sendAudio - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -234,8 +205,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_audio_empty_file_id(self): - print('Testing bot.sendAudio - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -248,8 +217,6 @@ class AudioTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_audio_without_required_args(self): - print('Testing bot.sendAudio - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_bot.py b/tests/test_bot.py index fcb1680c8..d861df198 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -42,8 +42,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testGetMe(self): - '''Test the telegram.Bot getMe method''' - print('Testing getMe') bot = self._bot.getMe() self.assertTrue(self.is_json(bot.to_json())) @@ -56,8 +54,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendMessage(self): - '''Test the telegram.Bot sendMessage method''' - print('Testing sendMessage') message = self._bot.sendMessage(chat_id=self._chat_id, text='Моё судно на воздушной подушке полно угрей') @@ -68,8 +64,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testGetUpdates(self): - '''Test the telegram.Bot getUpdates method''' - print('Testing getUpdates') updates = self._bot.getUpdates() if updates: @@ -79,8 +73,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testForwardMessage(self): - '''Test the telegram.Bot forwardMessage method''' - print('Testing forwardMessage') message = self._bot.forwardMessage(chat_id=self._chat_id, from_chat_id=self._chat_id, message_id=2398) @@ -93,8 +85,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendPhoto(self): - '''Test the telegram.Bot sendPhoto method''' - print('Testing sendPhoto - File') message = self._bot.sendPhoto(photo=open('tests/data/telegram.png', 'rb'), caption='testSendPhoto', chat_id=self._chat_id) @@ -106,8 +96,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testResendPhoto(self): - '''Test the telegram.Bot sendPhoto method''' - print('Testing sendPhoto - Resend') message = self._bot.sendPhoto(photo='AgADAQADyKcxGx8j9Qdp6d-gpUsw4Gja1i8ABEVJsVqQk8LfJ3wAAgI', chat_id=self._chat_id) @@ -117,8 +105,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendJPGURLPhoto(self): - '''Test the telegram.Bot sendPhoto method''' - print('Testing testSendJPGURLPhoto - URL') message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.jpg&text=telegram', chat_id=self._chat_id) @@ -128,8 +114,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendPNGURLPhoto(self): - '''Test the telegram.Bot sendPhoto method''' - print('Testing testSendPNGURLPhoto - URL') message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=self._chat_id) @@ -139,8 +123,6 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendGIFURLPhoto(self): - '''Test the telegram.Bot sendPhoto method''' - print('Testing testSendGIFURLPhoto - URL') message = self._bot.sendPhoto(photo='http://dummyimage.com/600x400/000/fff.gif&text=telegram', chat_id=self._chat_id) @@ -150,24 +132,18 @@ class BotTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def testSendChatAction(self): - '''Test the telegram.Bot sendChatAction method''' - print('Testing sendChatAction - ChatAction.TYPING') - self._bot.sendChatAction(action=telegram.ChatAction.TYPING, chat_id=self._chat_id) @flaky(3, 1) @timeout(10) def testGetUserProfilePhotos(self): - '''Test the telegram.Bot getUserProfilePhotos method''' - print('Testing getUserProfilePhotos') upf = self._bot.getUserProfilePhotos(user_id=self._chat_id) self.assertTrue(self.is_json(upf.to_json())) self.assertEqual(upf.photos[0][0].file_size, 12421) def _test_invalid_token(self, token): - print('Testing invalid token: {0}'.format(token)) self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', telegram.Bot, token) def testInvalidToken1(self): @@ -180,13 +156,11 @@ class BotTest(BaseTest, unittest.TestCase): self._test_invalid_token('12:') def testUnauthToken(self): - print('Testing unauthorized token') with self.assertRaisesRegexp(telegram.error.Unauthorized, 'Unauthorized'): bot = telegram.Bot('1234:abcd1234') bot.getMe() def testInvalidSrvResp(self): - print('Testing invalid server response') with self.assertRaisesRegexp(telegram.TelegramError, 'Invalid server response'): # bypass the valid token check bot_cls = type('bot_cls', (telegram.Bot, ), {'_valid_token': lambda self, token: token}) diff --git a/tests/test_botan.py b/tests/test_botan.py index 34a142e83..c20a13d74 100644 --- a/tests/test_botan.py +++ b/tests/test_botan.py @@ -27,16 +27,12 @@ class BotanTest(BaseTest, unittest.TestCase): token = os.environ.get('BOTAN_TOKEN') def test_track(self): - """Test sending event to botan""" - print('Test sending event to botan') botan = Botan(self.token) message = MessageMock(self._chat_id) result = botan.track(message, 'named event') self.assertTrue(result) def test_track_fail(self): - """Test fail when sending event to botan""" - print('Test fail when sending event to botan') botan = Botan(self.token) botan.url_template = 'https://api.botan.io/traccc?token={token}&uid={uid}&name={name}' message = MessageMock(self._chat_id) @@ -44,8 +40,6 @@ class BotanTest(BaseTest, unittest.TestCase): self.assertFalse(result) def test_wrong_message(self): - """Test sending wrong message""" - print('Test sending wrong message') botan = Botan(self.token) message = MessageMock(self._chat_id) message = delattr(message, 'chat_id') @@ -53,8 +47,6 @@ class BotanTest(BaseTest, unittest.TestCase): self.assertFalse(result) def test_wrong_endpoint(self): - """Test wrong endpoint""" - print('Test wrong endpoint') botan = Botan(self.token) botan.url_template = 'https://api.botaaaaan.io/traccc?token={token}&uid={uid}&name={name}' message = MessageMock(self._chat_id) diff --git a/tests/test_chat.py b/tests/test_chat.py index de8eec90a..b5dd626b4 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -43,17 +43,11 @@ class ChatTest(BaseTest, unittest.TestCase): } def test_group_chat_de_json_empty_json(self): - """Test Chat.de_json() method""" - print('Testing Chat.de_json() - Empty JSON') - group_chat = telegram.Chat.de_json({}) self.assertEqual(group_chat, None) def test_group_chat_de_json(self): - """Test Chat.de_json() method""" - print('Testing Chat.de_json()') - group_chat = telegram.Chat.de_json(self.json_dict) self.assertEqual(group_chat.id, self.id) @@ -61,17 +55,11 @@ class ChatTest(BaseTest, unittest.TestCase): self.assertEqual(group_chat.type, self.type) def test_group_chat_to_json(self): - """Test Chat.to_json() method""" - print('Testing Chat.to_json()') - group_chat = telegram.Chat.de_json(self.json_dict) self.assertTrue(self.is_json(group_chat.to_json())) def test_group_chat_to_dict(self): - """Test Chat.to_dict() method""" - print('Testing Chat.to_dict()') - group_chat = telegram.Chat.de_json(self.json_dict) self.assertTrue(self.is_dict(group_chat.to_dict())) diff --git a/tests/test_contact.py b/tests/test_contact.py index ccb7805e9..38e6cdca7 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -45,9 +45,6 @@ class ContactTest(BaseTest, unittest.TestCase): } def test_contact_de_json(self): - """Test Contact.de_json() method""" - print('Testing Contact.de_json()') - contact = telegram.Contact.de_json(self.json_dict) self.assertEqual(contact.phone_number, self.phone_number) @@ -56,17 +53,11 @@ class ContactTest(BaseTest, unittest.TestCase): self.assertEqual(contact.user_id, self.user_id) def test_contact_to_json(self): - """Test Contact.to_json() method""" - print('Testing Contact.to_json()') - contact = telegram.Contact.de_json(self.json_dict) self.assertTrue(self.is_json(contact.to_json())) def test_contact_to_dict(self): - """Test Contact.to_dict() method""" - print('Testing Contact.to_dict()') - contact = telegram.Contact.de_json(self.json_dict) self.assertTrue(self.is_dict(contact.to_dict())) diff --git a/tests/test_document.py b/tests/test_document.py index a1b7887bf..a7f9e8dad 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -56,9 +56,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_document_png_file(self): - """Test telegram.Bot sendDocument method""" - print('Testing bot.sendDocument - PNG File') - message = self._bot.sendDocument(self._chat_id, self.document_file) @@ -74,9 +71,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_document_png_file_with_custom_file_name(self): - """Test telegram.Bot sendDocument method""" - print('Testing bot.sendDocument - PNG File with custom filename') - message = self._bot.sendDocument(self._chat_id, self.document_file, filename='telegram_custom.png') @@ -93,9 +87,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_document_url_gif_file(self): - """Test telegram.Bot sendDocument method""" - print('Testing bot.sendDocument - GIF File by URL') - message = self._bot.sendDocument(self._chat_id, self.document_file_url) @@ -111,9 +102,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_document_resend(self): - """Test telegram.Bot sendDocument method""" - print('Testing bot.sendDocument - Resend by file_id') - message = self._bot.sendDocument(chat_id=self._chat_id, document=self.document_file_id) @@ -125,9 +113,6 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.mime_type, self.mime_type) def test_document_de_json(self): - """Test Document.de_json() method""" - print('Testing Document.de_json()') - document = telegram.Document.de_json(self.json_dict) self.assertEqual(document.file_id, self.document_file_id) @@ -137,17 +122,11 @@ class DocumentTest(BaseTest, unittest.TestCase): self.assertEqual(document.file_size, self.file_size) def test_document_to_json(self): - """Test Document.to_json() method""" - print('Testing Document.to_json()') - document = telegram.Document.de_json(self.json_dict) self.assertTrue(self.is_json(document.to_json())) def test_document_to_dict(self): - """Test Document.to_dict() method""" - print('Testing Document.to_dict()') - document = telegram.Document.de_json(self.json_dict) self.assertTrue(self.is_dict(document.to_dict())) @@ -160,8 +139,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_document_empty_file(self): - print('Testing bot.sendDocument - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -174,8 +151,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_document_empty_file_id(self): - print('Testing bot.sendDocument - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -188,8 +163,6 @@ class DocumentTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_document_without_required_args(self): - print('Testing bot.sendDocument - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_emoji.py b/tests/test_emoji.py index c8245af44..d15bd2747 100644 --- a/tests/test_emoji.py +++ b/tests/test_emoji.py @@ -33,9 +33,6 @@ class EmojiTest(BaseTest, unittest.TestCase): """This object represents Tests for Telegram Emoji.""" def test_emoji(self): - """Test Emoji class""" - print('Testing Emoji class') - for attr in dir(Emoji): if attr[0] != '_': # TODO: dirty way to filter out functions self.assertTrue(type(getattr(Emoji, attr)) is str) diff --git a/tests/test_file.py b/tests/test_file.py index 97864bd61..3347c99ad 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -46,9 +46,6 @@ class FileTest(BaseTest, unittest.TestCase): } def test_get_and_download_file_audio(self): - """Test telegram.Bot getFile method - Audio""" - print('Testing bot.getFile - With Audio.file_id') - newFile = self._bot.getFile(self.audio_file_id) self.assertEqual(newFile.file_size, 28232) @@ -60,9 +57,6 @@ class FileTest(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile('telegram.mp3')) def test_get_and_download_file_document(self): - """Test telegram.Bot getFile method - Document""" - print('Testing bot.getFile - With Document.file_id') - newFile = self._bot.getFile(self.document_file_id) self.assertEqual(newFile.file_size, 12948) @@ -74,9 +68,6 @@ class FileTest(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile('telegram.png')) def test_get_and_download_file_sticker(self): - """Test telegram.Bot getFile method - Sticker""" - print('Testing bot.getFile - With Sticker.file_id') - newFile = self._bot.getFile(self.sticker_file_id) self.assertEqual(newFile.file_size, 39518) @@ -88,9 +79,6 @@ class FileTest(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile('telegram.webp')) def test_get_and_download_file_video(self): - """Test telegram.Bot getFile method - Video""" - print('Testing bot.getFile - With Video.file_id') - newFile = self._bot.getFile(self.video_file_id) self.assertEqual(newFile.file_size, 326534) @@ -102,9 +90,6 @@ class FileTest(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile('telegram.mp4')) def test_get_and_download_file_voice(self): - """Test telegram.Bot getFile method - Voice""" - print('Testing bot.getFile - With Voice.file_id') - newFile = self._bot.getFile(self.voice_file_id) self.assertEqual(newFile.file_size, 9199) @@ -116,9 +101,6 @@ class FileTest(BaseTest, unittest.TestCase): self.assertTrue(os.path.isfile('telegram.ogg')) def test_file_de_json(self): - """Test File.de_json() method""" - print('Testing File.de_json()') - newFile = telegram.File.de_json(self.json_dict) self.assertEqual(newFile.file_id, self.json_dict['file_id']) @@ -126,17 +108,11 @@ class FileTest(BaseTest, unittest.TestCase): self.assertEqual(newFile.file_size, self.json_dict['file_size']) def test_file_to_json(self): - """Test File.to_json() method""" - print('Testing File.to_json()') - newFile = telegram.File.de_json(self.json_dict) self.assertTrue(self.is_json(newFile.to_json())) def test_file_to_dict(self): - """Test File.to_dict() method""" - print('Testing File.to_dict()') - newFile = telegram.File.de_json(self.json_dict) self.assertTrue(self.is_dict(newFile.to_dict())) @@ -145,10 +121,7 @@ class FileTest(BaseTest, unittest.TestCase): self.assertEqual(newFile['file_size'], self.json_dict['file_size']) def test_error_get_empty_file_id(self): - print('Testing bot.getFile - Null file_id') - json_dict = self.json_dict - json_dict['file_id'] = '' del(json_dict['file_path']) del(json_dict['file_size']) @@ -157,8 +130,6 @@ class FileTest(BaseTest, unittest.TestCase): lambda: self._bot.getFile(**json_dict)) def test_error_file_without_required_args(self): - print('Testing bot.getFile - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_force_replay.py b/tests/test_force_replay.py index e0d904f99..dddefb756 100644 --- a/tests/test_force_replay.py +++ b/tests/test_force_replay.py @@ -41,9 +41,6 @@ class ForceReplyTest(BaseTest, unittest.TestCase): } def test_send_message_with_force_reply(self): - """Test telegram.Bot sendMessage method with ForceReply""" - print('Testing bot.sendMessage - with ForceReply') - message = self._bot.sendMessage(self._chat_id, 'Моё судно на воздушной подушке полно угрей', reply_markup=telegram.ForceReply.de_json(self.json_dict)) @@ -52,26 +49,17 @@ class ForceReplyTest(BaseTest, unittest.TestCase): self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') def test_force_reply_de_json(self): - """Test ForceReply.de_json() method""" - print('Testing ForceReply.de_json()') - force_reply = telegram.ForceReply.de_json(self.json_dict) self.assertEqual(force_reply.force_reply, self.force_reply) self.assertEqual(force_reply.selective, self.selective) def test_force_reply_to_json(self): - """Test ForceReply.to_json() method""" - print('Testing ForceReply.to_json()') - force_reply = telegram.ForceReply.de_json(self.json_dict) self.assertTrue(self.is_json(force_reply.to_json())) def test_force_reply_to_dict(self): - """Test ForceReply.to_dict() method""" - print('Testing ForceReply.to_dict()') - force_reply = telegram.ForceReply.de_json(self.json_dict) self.assertEqual(force_reply['force_reply'], self.force_reply) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 0749a6980..a3ea4edea 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -72,19 +72,16 @@ class JobQueueTest(BaseTest, unittest.TestCase): raise Exception("Test Error") def test_basic(self): - print('Testing basic job queue function') self.jq.put(self.job1, 0.1) sleep(1.5) self.assertGreaterEqual(self.result, 10) def test_noRepeat(self): - print('Testing job queue without repeat') self.jq.put(self.job1, 0.1, repeat=False) sleep(0.5) self.assertEqual(1, self.result) def test_nextT(self): - print('Testing job queue with a set next_t value') self.jq.put(self.job1, 0.1, next_t=0.5) sleep(0.45) self.assertEqual(0, self.result) @@ -92,7 +89,6 @@ class JobQueueTest(BaseTest, unittest.TestCase): self.assertEqual(1, self.result) def test_multiple(self): - print('Testing job queue with multiple jobs') self.jq.put(self.job1, 0.1, repeat=False) self.jq.put(self.job1, 0.2, repeat=False) self.jq.put(self.job1, 0.4) @@ -100,7 +96,6 @@ class JobQueueTest(BaseTest, unittest.TestCase): self.assertEqual(4, self.result) def test_error(self): - print('Testing job queue starting twice with an erroneous job') self.jq.put(self.job2, 0.1) self.jq.put(self.job1, 0.2) self.jq.start() @@ -108,7 +103,6 @@ class JobQueueTest(BaseTest, unittest.TestCase): self.assertEqual(1, self.result) def test_inUpdater(self): - print('Testing job queue created by updater') u = Updater(bot="MockBot", job_queue_tick_interval=0.005) u.job_queue.put(self.job1, 0.1) sleep(0.15) diff --git a/tests/test_location.py b/tests/test_location.py index cdc281af8..b219ed337 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -41,9 +41,6 @@ class LocationTest(BaseTest, unittest.TestCase): } def test_send_location_implicit_args(self): - """Test telegram.Bot sendLocation method""" - print('Testing bot.sendLocation - Implicit arguments') - message = self._bot.sendLocation(self._chat_id, self.latitude, self.longitude) @@ -54,9 +51,6 @@ class LocationTest(BaseTest, unittest.TestCase): self.assertEqual(location.longitude, self.longitude) def test_send_location_explicit_args(self): - """Test telegram.Bot sendLocation method""" - print('Testing bot.sendLocation - Explicit arguments') - message = self._bot.sendLocation(chat_id=self._chat_id, latitude=self.latitude, longitude=self.longitude) @@ -67,34 +61,23 @@ class LocationTest(BaseTest, unittest.TestCase): self.assertEqual(location.longitude, self.longitude) def test_location_de_json(self): - """Test Location.de_json() method""" - print('Testing Location.de_json()') - location = telegram.Location.de_json(self.json_dict) self.assertEqual(location.latitude, self.latitude) self.assertEqual(location.longitude, self.longitude) def test_location_to_json(self): - """Test Location.to_json() method""" - print('Testing Location.to_json()') - location = telegram.Location.de_json(self.json_dict) self.assertTrue(self.is_json(location.to_json())) def test_location_to_dict(self): - """Test Location.to_dict() method""" - print('Testing Location.to_dict()') - location = telegram.Location.de_json(self.json_dict) self.assertEqual(location['latitude'], self.latitude) self.assertEqual(location['longitude'], self.longitude) def test_error_send_location_empty_args(self): - print('Testing bot.sendLocation - Empty arguments') - json_dict = self.json_dict json_dict['latitude'] = '' @@ -105,8 +88,6 @@ class LocationTest(BaseTest, unittest.TestCase): **json_dict)) def test_error_location_without_required_args(self): - print('Testing bot.sendLocation - Without required arguments') - json_dict = self.json_dict del(json_dict['latitude']) diff --git a/tests/test_parse_mode.py b/tests/test_parse_mode.py index 7c77219c9..b27117049 100644 --- a/tests/test_parse_mode.py +++ b/tests/test_parse_mode.py @@ -36,8 +36,6 @@ class ParseMode(BaseTest, unittest.TestCase): self.formatted_text_formatted = u'bold italic link.' def test_send_message_with_parse_mode_markdown(self): - '''Test the telegram.Bot sendMessage method with markdown parse mode''' - print('Testing sendMessage - with markdown parsemode') message = self._bot.sendMessage(chat_id=self._chat_id, text=self.markdown_text, parse_mode=telegram.ParseMode.MARKDOWN) @@ -46,8 +44,6 @@ class ParseMode(BaseTest, unittest.TestCase): self.assertEqual(message.text, self.formatted_text_formatted) def test_send_message_with_parse_mode_html(self): - '''Test the telegram.Bot sendMessage method with html parse mode''' - print('Testing sendMessage - with html parse mode') message = self._bot.sendMessage(chat_id=self._chat_id, text=self.html_text, parse_mode=telegram.ParseMode.HTML) @@ -56,4 +52,4 @@ class ParseMode(BaseTest, unittest.TestCase): self.assertEqual(message.text, self.formatted_text_formatted) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/tests/test_photo.py b/tests/test_photo.py index 23b46f8d6..13d0d0e55 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -58,9 +58,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_sendphotoo_all_args(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendPhoto - With all arguments') - message = self._bot.sendPhoto(self._chat_id, self.photo_file, caption=self.caption) @@ -86,9 +83,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_photo_jpg_file(self): - """Test telegram.Bot sendPhoto method""" - print('Testing bot.sendPhoto - JPG File') - message = self._bot.sendPhoto(self._chat_id, self.photo_file) @@ -111,9 +105,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_photo_url_jpg_file(self): - """Test telegram.Bot sendPhoto method""" - print('Testing bot.sendPhoto - JPG File by URL') - message = self._bot.sendPhoto(self._chat_id, self.photo_file_url) @@ -136,9 +127,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_photo_resend(self): - """Test telegram.Bot sendPhoto method""" - print('Testing bot.sendPhoto - Resend by file_id') - message = self._bot.sendPhoto(chat_id=self._chat_id, photo=self.photo_file_id) @@ -155,9 +143,6 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.height, self.height) def test_photo_de_json(self): - """Test Photo.de_json() method""" - print('Testing Photo.de_json()') - photo = telegram.PhotoSize.de_json(self.json_dict) self.assertEqual(photo.file_id, self.photo_file_id) @@ -167,17 +152,11 @@ class PhotoTest(BaseTest, unittest.TestCase): self.assertEqual(photo.file_size, self.file_size) def test_photo_to_json(self): - """Test Photo.to_json() method""" - print('Testing Photo.to_json()') - photo = telegram.PhotoSize.de_json(self.json_dict) self.assertTrue(self.is_json(photo.to_json())) def test_photo_to_dict(self): - """Test Photo.to_dict() method""" - print('Testing Photo.to_dict()') - photo = telegram.PhotoSize.de_json(self.json_dict) self.assertTrue(self.is_dict(photo.to_dict())) @@ -190,8 +169,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_photo_empty_file(self): - print('Testing bot.sendPhoto - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -204,8 +181,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_photo_empty_file_id(self): - print('Testing bot.sendPhoto - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -218,8 +193,6 @@ class PhotoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_photo_without_required_args(self): - print('Testing bot.sendPhoto - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_reply_keyboard_hide.py b/tests/test_reply_keyboard_hide.py index 4ffca8840..1fb1e4042 100644 --- a/tests/test_reply_keyboard_hide.py +++ b/tests/test_reply_keyboard_hide.py @@ -41,9 +41,6 @@ class ReplyKeyboardHideTest(BaseTest, unittest.TestCase): } def test_send_message_with_reply_keyboard_hide(self): - """Test telegram.Bot sendMessage method with ReplyKeyboardHide""" - print('Testing bot.sendMessage - with ReplyKeyboardHide') - message = self._bot.sendMessage(self._chat_id, 'Моё судно на воздушной подушке полно угрей', reply_markup=telegram.ReplyKeyboardHide.de_json(self.json_dict)) @@ -52,26 +49,17 @@ class ReplyKeyboardHideTest(BaseTest, unittest.TestCase): self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') def test_reply_keyboard_hide_de_json(self): - """Test ReplyKeboardHide.de_json() method""" - print('Testing ReplyKeyboardHide.de_json()') - reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict) self.assertEqual(reply_keyboard_hide.hide_keyboard, self.hide_keyboard) self.assertEqual(reply_keyboard_hide.selective, self.selective) def test_reply_keyboard_hide_to_json(self): - """Test ReplyKeyboardHide.to_json() method""" - print('Testing ReplyKeyboardHide.to_json()') - reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict) self.assertTrue(self.is_json(reply_keyboard_hide.to_json())) def test_reply_keyboard_hide_to_dict(self): - """Test ReplyKeyboardHide.to_dict() method""" - print('Testing ReplyKeyboardHide.to_dict()') - reply_keyboard_hide = telegram.ReplyKeyboardHide.de_json(self.json_dict) self.assertEqual(reply_keyboard_hide['hide_keyboard'], self.hide_keyboard) diff --git a/tests/test_reply_keyboard_markup.py b/tests/test_reply_keyboard_markup.py index 90b83c530..02fa1eba0 100644 --- a/tests/test_reply_keyboard_markup.py +++ b/tests/test_reply_keyboard_markup.py @@ -45,9 +45,6 @@ class ReplyKeyboardMarkupTest(BaseTest, unittest.TestCase): } def test_send_message_with_reply_keyboard_markup(self): - """Test telegram.Bot sendMessage method with ReplyKeyboardMarkup""" - print('Testing bot.sendMessage - with ReplyKeyboardMarkup') - message = self._bot.sendMessage(self._chat_id, 'Моё судно на воздушной подушке полно угрей', reply_markup=telegram.ReplyKeyboardMarkup.de_json(self.json_dict)) @@ -56,9 +53,6 @@ class ReplyKeyboardMarkupTest(BaseTest, unittest.TestCase): self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') def test_reply_keyboard_markup_de_json(self): - """Test ReplyKeboardMarkup.de_json() method""" - print('Testing ReplyKeyboardMarkup.de_json()') - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict) self.assertEqual(reply_keyboard_markup.keyboard, self.keyboard) @@ -67,17 +61,11 @@ class ReplyKeyboardMarkupTest(BaseTest, unittest.TestCase): self.assertEqual(reply_keyboard_markup.selective, self.selective) def test_reply_keyboard_markup_to_json(self): - """Test ReplyKeyboardMarkup.to_json() method""" - print('Testing ReplyKeyboardMarkup.to_json()') - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict) self.assertTrue(self.is_json(reply_keyboard_markup.to_json())) def test_reply_keyboard_markup_to_dict(self): - """Test ReplyKeyboardMarkup.to_dict() method""" - print('Testing ReplyKeyboardMarkup.to_dict()') - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict) self.assertEqual(reply_keyboard_markup['keyboard'], self.keyboard) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index a62881441..6f766df3e 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -59,9 +59,6 @@ class StickerTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_sticker_resend(self): - """Test telegram.Bot sendSticker method""" - print('Testing bot.sendSticker - Resend by file_id') - message = self._bot.sendSticker(chat_id=self._chat_id, sticker=self.sticker_file_id) @@ -74,9 +71,6 @@ class StickerTest(BaseTest, unittest.TestCase): self.assertEqual(sticker.file_size, self.file_size) def test_sticker_de_json(self): - """Test Sticker.de_json() method""" - print('Testing Sticker.de_json()') - sticker = telegram.Sticker.de_json(self.json_dict) self.assertEqual(sticker.file_id, self.sticker_file_id) @@ -86,17 +80,11 @@ class StickerTest(BaseTest, unittest.TestCase): self.assertEqual(sticker.file_size, self.file_size) def test_sticker_to_json(self): - """Test Sticker.to_json() method""" - print('Testing Sticker.to_json()') - sticker = telegram.Sticker.de_json(self.json_dict) self.assertTrue(self.is_json(sticker.to_json())) def test_sticker_to_dict(self): - """Test Sticker.to_dict() method""" - print('Testing Sticker.to_dict()') - sticker = telegram.Sticker.de_json(self.json_dict) self.assertEqual(sticker['file_id'], self.sticker_file_id) @@ -108,8 +96,6 @@ class StickerTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_sticker_empty_file(self): - print('Testing bot.sendSticker - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -122,8 +108,6 @@ class StickerTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_sticker_empty_file_id(self): - print('Testing bot.sendSticker - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -136,8 +120,6 @@ class StickerTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_sticker_without_required_args(self): - print('Testing bot.sendSticker - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_update.py b/tests/test_update.py index c03c53a8a..2533985dc 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -52,26 +52,17 @@ class UpdateTest(BaseTest, unittest.TestCase): } def test_update_de_json(self): - """Test Update.de_json() method""" - print('Testing Update.de_json()') - update = telegram.Update.de_json(self.json_dict) self.assertEqual(update.update_id, self.update_id) self.assertTrue(isinstance(update.message, telegram.Message)) def test_update_to_json(self): - """Test Update.to_json() method""" - print('Testing Update.to_json()') - update = telegram.Update.de_json(self.json_dict) self.assertTrue(self.is_json(update.to_json())) def test_update_to_dict(self): - """Test Update.to_dict() method""" - print('Testing Update.to_dict()') - update = telegram.Update.de_json(self.json_dict) self.assertTrue(self.is_dict(update.to_dict())) diff --git a/tests/test_updater.py b/tests/test_updater.py index bcbb69467..12e5e1b78 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -136,7 +136,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.message_count += 1 def test_addRemoveTelegramMessageHandler(self): - print('Testing add/removeTelegramMessageHandler') self._setup_updater('Test') d = self.updater.dispatcher d.addTelegramMessageHandler( @@ -154,7 +153,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addTelegramMessageHandlerMultipleMessages(self): - print('Testing addTelegramMessageHandler and send 100 messages...') self._setup_updater('Multiple', 100) self.updater.dispatcher.addTelegramMessageHandler( self.telegramHandlerTest) @@ -164,7 +162,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.message_count, 100) def test_addRemoveTelegramRegexHandler(self): - print('Testing add/removeStringRegexHandler') self._setup_updater('Test2') d = self.updater.dispatcher regobj = re.compile('Te.*') @@ -183,7 +180,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveTelegramCommandHandler(self): - print('Testing add/removeTelegramCommandHandler') self._setup_updater('/test') d = self.updater.dispatcher self.updater.dispatcher.addTelegramCommandHandler( @@ -201,7 +197,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveUnknownTelegramCommandHandler(self): - print('Testing add/removeUnknownTelegramCommandHandler') self._setup_updater('/test2') d = self.updater.dispatcher self.updater.dispatcher.addUnknownTelegramCommandHandler( @@ -219,7 +214,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveStringRegexHandler(self): - print('Testing add/removeStringRegexHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('Te.*', self.stringHandlerTest) @@ -237,7 +231,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveStringCommandHandler(self): - print('Testing add/removeStringCommandHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringCommandHandler( @@ -257,7 +250,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveUnknownStringCommandHandler(self): - print('Testing add/removeUnknownStringCommandHandler') self._setup_updater('/test') d = self.updater.dispatcher d.addUnknownStringCommandHandler( @@ -276,7 +268,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_addRemoveErrorHandler(self): - print('Testing add/removeErrorHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) @@ -295,7 +286,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_errorInHandler(self): - print('Testing error in Handler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('.*', @@ -308,7 +298,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.received_message, 'Test Error 1') def test_errorOnGetUpdates(self): - print('Testing error on getUpdates') self._setup_updater('', raise_error=True) d = self.updater.dispatcher d.addErrorHandler(self.errorHandlerTest) @@ -317,7 +306,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.received_message, "Test Error 2") def test_addRemoveTypeHandler(self): - print('Testing add/removeTypeHandler') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTypeHandler(dict, self.stringHandlerTest) @@ -336,7 +324,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(None is self.received_message) def test_runAsync(self): - print('Testing @run_async') self._setup_updater('Test5', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler( @@ -347,7 +334,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.message_count, 2) def test_additionalArgs(self): - print('Testing additional arguments for handlers') self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( 'test5', self.additionalArgsTest) @@ -359,7 +345,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.message_count, 2) def test_context(self): - print('Testing context for handlers') context = "context_data" self._setup_updater('', messages=0) self.updater.dispatcher.addStringCommandHandler( @@ -373,7 +358,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.context, context) def test_regexGroupHandler(self): - print('Testing optional groups and groupdict parameters') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addStringRegexHandler('^(This).*?(?Pregex group).*', @@ -386,7 +370,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): def test_runAsyncWithAdditionalArgs(self): - print('Testing @run_async with additional parameters') self._setup_updater('Test6', messages=2) d = self.updater.dispatcher d.addTelegramMessageHandler( @@ -397,7 +380,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertEqual(self.message_count, 2) def test_webhook(self): - print('Testing Webhook') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler( @@ -443,7 +425,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): self.assertTrue(True) def test_webhook_no_ssl(self): - print('Testing Webhook without SSL') self._setup_updater('', messages=0) d = self.updater.dispatcher d.addTelegramMessageHandler( @@ -539,7 +520,6 @@ class UpdaterTest(BaseTest, unittest.TestCase): os.kill(os.getpid(), signal.SIGTERM) def test_idle(self): - print('Testing idle') self._setup_updater('Test6', messages=0) self.updater.start_polling(poll_interval=0.01) Thread(target=self.signalsender).start() diff --git a/tests/test_user.py b/tests/test_user.py index 855ab08b9..bbafe39a9 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -47,9 +47,6 @@ class UserTest(BaseTest, unittest.TestCase): } def test_user_de_json(self): - """Test User.de_json() method""" - print('Testing User.de_json()') - user = telegram.User.de_json(self.json_dict) self.assertEqual(user.id, self.id) @@ -61,9 +58,6 @@ class UserTest(BaseTest, unittest.TestCase): self.assertEqual(user.name, '@leandrotoledo') def test_user_de_json_without_username(self): - """Test User.de_json() method""" - print('Testing User.de_json() - Without username') - json_dict = self.json_dict del(json_dict['username']) @@ -79,9 +73,6 @@ class UserTest(BaseTest, unittest.TestCase): def test_user_de_json_without_username_and_lastname(self): - """Test User.de_json() method""" - print('Testing User.de_json() - Without username and last_name') - json_dict = self.json_dict del(json_dict['username']) @@ -95,17 +86,11 @@ class UserTest(BaseTest, unittest.TestCase): self.assertEqual(user.name, self.first_name) def test_user_to_json(self): - """Test User.to_json() method""" - print('Testing User.to_json()') - user = telegram.User.de_json(self.json_dict) self.assertTrue(self.is_json(user.to_json())) def test_user_to_dict(self): - """Test User.to_dict() method""" - print('Testing User.to_dict()') - user = telegram.User.de_json(self.json_dict) self.assertTrue(self.is_dict(user.to_dict())) diff --git a/tests/test_video.py b/tests/test_video.py index 685f756c5..8dd1d5db5 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -60,9 +60,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_required_args_only(self): - """Test telegram.Bot sendVideo method""" - print('Testing bot.sendVideo - With required arguments only') - message = self._bot.sendVideo(self._chat_id, self.video_file) @@ -80,9 +77,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_all_args(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendVideo - With all arguments') - message = self._bot.sendVideo(self._chat_id, self.video_file, duration=self.duration, @@ -104,9 +98,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_mp4_file(self): - """Test telegram.Bot sendVideo method""" - print('Testing bot.sendVideo - MP4 File') - message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file, duration=self.duration, @@ -128,9 +119,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_mp4_file_with_custom_filename(self): - """Test telegram.Bot sendVideo method""" - print('Testing bot.sendVideo - MP4 File with custom filename') - message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file, duration=self.duration, @@ -153,9 +141,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_mp4_file_url(self): - """Test telegram.Bot sendVideo method""" - print('Testing bot.sendVideo - MP4 File by URL') - message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file_url, duration=self.duration, @@ -177,9 +162,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_video_resend(self): - """Test telegram.Bot sendVideo method""" - print('Testing bot.sendVideo - Resend by file_id') - message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file_id, duration=self.duration, @@ -195,9 +177,6 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(message.caption, self.caption) def test_video_de_json(self): - """Test Video.de_json() method""" - print('Testing Video.de_json()') - video = telegram.Video.de_json(self.json_dict) self.assertEqual(video.file_id, self.video_file_id) @@ -209,17 +188,11 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video.file_size, self.file_size) def test_video_to_json(self): - """Test Video.to_json() method""" - print('Testing Video.to_json()') - video = telegram.Video.de_json(self.json_dict) self.assertTrue(self.is_json(video.to_json())) def test_video_to_dict(self): - """Test Video.to_dict() method""" - print('Testing Video.to_dict()') - video = telegram.Video.de_json(self.json_dict) self.assertTrue(self.is_dict(video.to_dict())) @@ -233,8 +206,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_video_empty_file(self): - print('Testing bot.sendVideo - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -247,8 +218,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_video_empty_file_id(self): - print('Testing bot.sendVideo - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -261,8 +230,6 @@ class VideoTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_video_without_required_args(self): - print('Testing bot.sendVideo - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) diff --git a/tests/test_voice.py b/tests/test_voice.py index 68fb50d46..84954609d 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -51,9 +51,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_required_args_only(self): - """Test telegram.Bot sendVoice method""" - print('Testing bot.sendVoice - With required arguments only') - message = self._bot.sendVoice(self._chat_id, self.voice_file) @@ -68,9 +65,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_all_args(self): - """Test telegram.Bot sendAudio method""" - print('Testing bot.sendVoice - With all arguments') - message = self._bot.sendVoice(self._chat_id, self.voice_file, self.duration, @@ -88,9 +82,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_ogg_file(self): - """Test telegram.Bot sendVoice method""" - print('Testing bot.sendVoice - Ogg File') - message = self._bot.sendVoice(chat_id=self._chat_id, voice=self.voice_file, duration=self.duration) @@ -106,9 +97,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_ogg_file_with_custom_filename(self): - """Test telegram.Bot sendVoice method""" - print('Testing bot.sendVoice - Ogg File with custom filename') - message = self._bot.sendVoice(chat_id=self._chat_id, voice=self.voice_file, duration=self.duration, @@ -125,9 +113,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_ogg_url_file(self): - """Test telegram.Bot sendVoice method""" - print('Testing bot.sendVoice - Ogg File by URL') - message = self._bot.sendVoice(chat_id=self._chat_id, voice=self.voice_file_url, duration=self.duration) @@ -143,9 +128,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_send_voice_resend(self): - """Test telegram.Bot sendVoice method""" - print('Testing bot.sendVoice - Resend by file_id') - message = self._bot.sendVoice(chat_id=self._chat_id, voice=self.voice_file_id, duration=self.duration) @@ -157,9 +139,6 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.mime_type, self.mime_type) def test_voice_de_json(self): - """Test Voice.de_json() method""" - print('Testing Voice.de_json()') - voice = telegram.Voice.de_json(self.json_dict) self.assertEqual(voice.file_id, self.voice_file_id) @@ -168,17 +147,11 @@ class VoiceTest(BaseTest, unittest.TestCase): self.assertEqual(voice.file_size, self.file_size) def test_voice_to_json(self): - """Test Voice.to_json() method""" - print('Testing Voice.to_json()') - voice = telegram.Voice.de_json(self.json_dict) self.assertTrue(self.is_json(voice.to_json())) def test_voice_to_dict(self): - """Test Voice.to_dict() method""" - print('Testing Voice.to_dict()') - voice = telegram.Voice.de_json(self.json_dict) self.assertTrue(self.is_dict(voice.to_dict())) @@ -190,8 +163,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_voice_empty_file(self): - print('Testing bot.sendVoice - Null file') - json_dict = self.json_dict del(json_dict['file_id']) @@ -204,8 +175,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_send_voice_empty_file_id(self): - print('Testing bot.sendVoice - Empty file_id') - json_dict = self.json_dict del(json_dict['file_id']) @@ -218,8 +187,6 @@ class VoiceTest(BaseTest, unittest.TestCase): @flaky(3, 1) @timeout(10) def test_error_voice_without_required_args(self): - print('Testing bot.sendVoice - Without required arguments') - json_dict = self.json_dict del(json_dict['file_id']) From ca8404adb7cd4bb105b1e8e3839ab4535a33e06e Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Wed, 24 Feb 2016 00:55:30 +0200 Subject: [PATCH 26/34] travis.yml: another try to fix nosetests command line --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 51577ef7a..e3323617e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ install: - pip install -r requirements.txt - pip install -r requirements-dev.txt script: - - nosetests -v --with-coverage --cover-package --with-flaky + - nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/ - flake8 telegram - 'if [[ $TRAVIS_PYTHON_VERSION != 2.6 ]]; then pylint -E telegram --disable=no-name-in-module,import-error; fi' after_success: From ec8cd3734532e65add8505361ab40d58063d7967 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 22:49:13 +0200 Subject: [PATCH 27/34] test_video.py: adapt to latest changes in the API --- telegram/photosize.py | 8 ++++++++ tests/test_video.py | 43 +++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/telegram/photosize.py b/telegram/photosize.py index 275cb639c..694cb5252 100644 --- a/telegram/photosize.py +++ b/telegram/photosize.py @@ -53,6 +53,14 @@ class PhotoSize(TelegramObject): # Optionals self.file_size = int(kwargs.get('file_size', 0)) + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + return (self.file_id == other.file_id and + self.width == other.width and + self.height == other.height and + self.file_size == other.file_size) + @staticmethod def de_json(data): """ diff --git a/tests/test_video.py b/tests/test_video.py index 8dd1d5db5..7787cdced 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -39,8 +39,12 @@ class VideoTest(BaseTest, unittest.TestCase): self.video_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.mp4' self.width = 360 self.height = 640 - self.duration = 4 - self.thumb = telegram.PhotoSize.de_json({}) + self.duration = 5 + self.thumb = telegram.PhotoSize.de_json( + {'file_id': 'AAQBABOMsecvAAQqqoY1Pee_MqcyAAIC', + 'file_size': 645, + 'height': 90, + 'width': 51}) self.mime_type = 'video/mp4' self.file_size = 326534 @@ -52,7 +56,7 @@ class VideoTest(BaseTest, unittest.TestCase): 'width': self.width, 'height': self.height, 'duration': self.duration, - 'thumb': self.thumb, + 'thumb': self.thumb.to_dict(), 'mime_type': self.mime_type, 'file_size': self.file_size } @@ -67,10 +71,10 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(video.file_id, str)) self.assertNotEqual(video.file_id, '') - self.assertEqual(video.width, 0) - self.assertEqual(video.height, 0) - self.assertEqual(video.duration, 0) - self.assertEqual(video.thumb, None) + self.assertEqual(video.width, self.width) + self.assertEqual(video.height, self.height) + self.assertEqual(video.duration, self.duration) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) @@ -86,10 +90,10 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(video.file_id, str)) self.assertNotEqual(video.file_id, '') - self.assertEqual(video.width, 0) - self.assertEqual(video.height, 0) + self.assertEqual(video.width, self.width) + self.assertEqual(video.height, self.height) self.assertEqual(video.duration, self.duration) - self.assertEqual(video.thumb, None) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) @@ -107,10 +111,10 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(video.file_id, str)) self.assertNotEqual(video.file_id, '') - self.assertEqual(video.width, 0) - self.assertEqual(video.height, 0) + self.assertEqual(video.width, self.width) + self.assertEqual(video.height, self.height) self.assertEqual(video.duration, self.duration) - self.assertEqual(video.thumb, None) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) @@ -129,10 +133,10 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(video.file_id, str)) self.assertNotEqual(video.file_id, '') - self.assertEqual(video.width, 0) - self.assertEqual(video.height, 0) + self.assertEqual(video.width, self.width) + self.assertEqual(video.height, self.height) self.assertEqual(video.duration, self.duration) - self.assertEqual(video.thumb, None) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) @@ -150,10 +154,9 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertTrue(isinstance(video.file_id, str)) self.assertNotEqual(video.file_id, '') - self.assertEqual(video.width, 0) - self.assertEqual(video.height, 0) + self.assertEqual(video.height, self.height) self.assertEqual(video.duration, self.duration) - self.assertEqual(video.thumb, None) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, '') self.assertEqual(video.file_size, self.file_size) @@ -183,7 +186,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertEqual(video.width, self.width) self.assertEqual(video.height, self.height) self.assertEqual(video.duration, self.duration) - self.assertEqual(video.thumb, None) + self.assertEqual(video.thumb, self.thumb) self.assertEqual(video.mime_type, self.mime_type) self.assertEqual(video.file_size, self.file_size) From d2623d26710d3f0551f1665b9796299cd64f70aa Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 22:53:40 +0200 Subject: [PATCH 28/34] test_voice.py: adapt to latest changes in the API --- tests/test_voice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_voice.py b/tests/test_voice.py index 84954609d..04617ce2b 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -37,7 +37,7 @@ class VoiceTest(BaseTest, unittest.TestCase): self.voice_file = open('tests/data/telegram.ogg', 'rb') self.voice_file_id = 'AwADAQADTgADHyP1B_mbw34svXPHAg' self.voice_file_url = 'https://raw.githubusercontent.com/python-telegram-bot/python-telegram-bot/master/tests/data/telegram.ogg' - self.duration = 0 + self.duration = 3 self.mime_type = 'audio/ogg' self.file_size = 9199 @@ -135,7 +135,7 @@ class VoiceTest(BaseTest, unittest.TestCase): voice = message.voice self.assertEqual(voice.file_id, self.voice_file_id) - self.assertEqual(voice.duration, self.duration) + self.assertEqual(voice.duration, 0) self.assertEqual(voice.mime_type, self.mime_type) def test_voice_de_json(self): From fc618274ae9229e05628ded55d86b607e89a517f Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 23:00:33 +0200 Subject: [PATCH 29/34] bot.py: allow specifying timeout for sendVideo operations --- telegram/bot.py | 59 ++++++++++++++++++++++++--------------- telegram/utils/request.py | 32 ++++++++++++++------- 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/telegram/bot.py b/telegram/bot.py index 31869a555..7d20a3b87 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -142,29 +142,39 @@ class Bot(TelegramObject): decorator """ url, data = func(self, *args, **kwargs) - - if not data.get('chat_id'): - raise TelegramError('Invalid chat_id') - - if kwargs.get('reply_to_message_id'): - reply_to_message_id = kwargs.get('reply_to_message_id') - data['reply_to_message_id'] = reply_to_message_id - - if kwargs.get('reply_markup'): - reply_markup = kwargs.get('reply_markup') - if isinstance(reply_markup, ReplyMarkup): - data['reply_markup'] = reply_markup.to_json() - else: - data['reply_markup'] = reply_markup - - result = request.post(url, data) - - if result is True: - return result - - return Message.de_json(result) + return Bot._post_message(url, data, kwargs) return decorator + @staticmethod + def _post_message(url, data, kwargs, timeout=None, network_delay=2.): + """Posts a message to the telegram servers. + + Returns: + telegram.Message + + """ + if not data.get('chat_id'): + raise TelegramError('Invalid chat_id') + + if kwargs.get('reply_to_message_id'): + reply_to_message_id = kwargs.get('reply_to_message_id') + data['reply_to_message_id'] = reply_to_message_id + + if kwargs.get('reply_markup'): + reply_markup = kwargs.get('reply_markup') + if isinstance(reply_markup, ReplyMarkup): + data['reply_markup'] = reply_markup.to_json() + else: + data['reply_markup'] = reply_markup + + result = request.post(url, data, timeout=timeout, + network_delay=network_delay) + + if result is True: + return result + + return Message.de_json(result) + @log def getMe(self): """A simple method for testing your bot's auth token. @@ -430,12 +440,12 @@ class Bot(TelegramObject): return url, data @log - @message def sendVideo(self, chat_id, video, duration=None, caption=None, + timeout=None, **kwargs): """Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as telegram.Document). @@ -452,6 +462,9 @@ class Bot(TelegramObject): caption: Video caption (may also be used when resending videos by file_id). [Optional] + timeout: + float. If this value is specified, use it as the definitive timeout + (in seconds) for urlopen() operations. [Optional] reply_to_message_id: If the message is a reply, ID of the original message. [Optional] reply_markup: @@ -473,7 +486,7 @@ class Bot(TelegramObject): if caption: data['caption'] = caption - return url, data + return self._post_message(url, data, kwargs, timeout=timeout) @log @message diff --git a/telegram/utils/request.py b/telegram/utils/request.py index 17b53324c..6968d74ca 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -127,6 +127,7 @@ def get(url): @_try_except_req def post(url, data, + timeout=None, network_delay=2.): """Request an URL. Args: @@ -134,20 +135,29 @@ def post(url, The web location we want to retrieve. data: A dict of (str, unicode) key/value pairs. + timeout: + float. If this value is specified, use it as the definitive timeout (in + seconds) for urlopen() operations. [Optional] network_delay: - Additional timeout in seconds to allow the response from Telegram to - take some time. + float. If using the timeout specified in `data` (which is a timeout for + the Telegram servers operation), then `network_delay` as an extra delay + (in seconds) to compensate for network latency. + default: 2 [Optional] + + Notes: + If neither `timeout` nor `data['timeout']` is specified. The underlying + defaults are used. Returns: A JSON object. - """ - # Add time to the timeout of urlopen to allow data to be transferred over - # the network. - if 'timeout' in data: - timeout = data['timeout'] + network_delay - else: - timeout = None + """ + urlopen_kwargs = {} + + if timeout is not None: + urlopen_kwargs['timeout'] = timeout + elif 'timeout' in data: + urlopen_kwargs['timeout'] = data['timeout'] + network_delay if InputFile.is_inputfile(data): data = InputFile(data) @@ -160,7 +170,9 @@ def post(url, data=data.encode(), headers={'Content-Type': 'application/json'}) - result = urlopen(request, timeout=timeout).read() + with urlopen(request, **urlopen_kwargs) as handle: + result = handle.read() + return _parse(result) From 26f87c48731c4f921e7255cd86d33ed875e0f058 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 23:01:22 +0200 Subject: [PATCH 30/34] test_video.py: specify timeout for the sendVideo operation itself --- tests/test_video.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_video.py b/tests/test_video.py index 7787cdced..fc9dd92be 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -65,7 +65,8 @@ class VideoTest(BaseTest, unittest.TestCase): @timeout(10) def test_send_video_required_args_only(self): message = self._bot.sendVideo(self._chat_id, - self.video_file) + self.video_file, + timeout=10) video = message.video @@ -83,6 +84,7 @@ class VideoTest(BaseTest, unittest.TestCase): def test_send_video_all_args(self): message = self._bot.sendVideo(self._chat_id, self.video_file, + timeout=10, duration=self.duration, caption=self.caption) @@ -104,6 +106,7 @@ class VideoTest(BaseTest, unittest.TestCase): def test_send_video_mp4_file(self): message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file, + timeout=10, duration=self.duration, caption=self.caption) @@ -125,6 +128,7 @@ class VideoTest(BaseTest, unittest.TestCase): def test_send_video_mp4_file_with_custom_filename(self): message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file, + timeout=10, duration=self.duration, caption=self.caption, filename='telegram_custom.mp4') @@ -147,6 +151,7 @@ class VideoTest(BaseTest, unittest.TestCase): def test_send_video_mp4_file_url(self): message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file_url, + timeout=10, duration=self.duration, caption=self.caption) @@ -167,6 +172,7 @@ class VideoTest(BaseTest, unittest.TestCase): def test_send_video_resend(self): message = self._bot.sendVideo(chat_id=self._chat_id, video=self.video_file_id, + timeout=10, duration=self.duration, caption=self.caption) @@ -216,6 +222,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertRaises(telegram.TelegramError, lambda: self._bot.sendVideo(chat_id=self._chat_id, + timeout=10, **json_dict)) @flaky(3, 1) @@ -228,6 +235,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertRaises(telegram.TelegramError, lambda: self._bot.sendVideo(chat_id=self._chat_id, + timeout=10, **json_dict)) @flaky(3, 1) @@ -240,6 +248,7 @@ class VideoTest(BaseTest, unittest.TestCase): self.assertRaises(TypeError, lambda: self._bot.sendVideo(chat_id=self._chat_id, + timeout=10, **json_dict)) if __name__ == '__main__': From ccb24d128833e53a56736d8b4395dfdd4011381c Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 23:13:29 +0200 Subject: [PATCH 31/34] request.py: fix for python2.7 --- telegram/utils/request.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/telegram/utils/request.py b/telegram/utils/request.py index 6968d74ca..7bc4f8cd6 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -170,9 +170,7 @@ def post(url, data=data.encode(), headers={'Content-Type': 'application/json'}) - with urlopen(request, **urlopen_kwargs) as handle: - result = handle.read() - + result = urlopen(request, **urlopen_kwargs).read() return _parse(result) From 2e6db1330f287f678dcf1931794add479a21cb28 Mon Sep 17 00:00:00 2001 From: Noam Meltzer Date: Sat, 27 Feb 2016 23:39:03 +0200 Subject: [PATCH 32/34] test_botan.py: another flaky test --- tests/test_botan.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_botan.py b/tests/test_botan.py index c20a13d74..7120c9097 100644 --- a/tests/test_botan.py +++ b/tests/test_botan.py @@ -5,6 +5,8 @@ import os import unittest import sys +from flaky import flaky + sys.path.append('.') from telegram.utils.botan import Botan @@ -21,6 +23,7 @@ class MessageMock(object): return "{}" +@flaky(3, 1) class BotanTest(BaseTest, unittest.TestCase): """This object represents Tests for Botan analytics integration.""" From 139cbc657daac478a53be2fd1ec66686a57ff786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 28 Feb 2016 01:51:14 +0100 Subject: [PATCH 33/34] add inline bot handler example --- README.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.rst b/README.rst index 2f9d9f162..f75e216ac 100644 --- a/README.rst +++ b/README.rst @@ -227,6 +227,20 @@ Let's add some functionality to our bot. We want to add the ``/caps`` command, t ... >>> dispatcher.addTelegramCommandHandler('caps', caps) +To enable our bot to respond to inline queries, we can add the following (you will also have to talk to BotFather):: + + >>> from telegram import InlineQueryResultArticle + >>> def inline_caps(bot, update): + ... # If you activated inline feedback, updates might either contain + ... # inline_query or chosen_inline_result, the other one will be None + ... if update.inline_query: + ... query = bot.update.inline_query.query + ... results = list() + ... results.append(InlineQueryResultArticle(query.upper(), 'Caps', text_caps)) + ... bot.answerInlineQuery(update.inline_query.id, results) + ... + >>> dispatcher.addTelegramInlineHandler(inline_caps) + Now it's time to stop the bot:: >>> updater.stop() From b5875a3abd33027856e1390ec83517b858d518ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Sun, 28 Feb 2016 01:53:18 +0100 Subject: [PATCH 34/34] increase timing for repeatedly failing travis test --- tests/test_jobqueue.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index a3ea4edea..c3562f621 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -104,8 +104,8 @@ class JobQueueTest(BaseTest, unittest.TestCase): def test_inUpdater(self): u = Updater(bot="MockBot", job_queue_tick_interval=0.005) - u.job_queue.put(self.job1, 0.1) - sleep(0.15) + u.job_queue.put(self.job1, 0.11) + sleep(0.2) self.assertEqual(1, self.result) u.stop() sleep(0.4)