From 5d7c6ad541f8baa3c275206482c3d370f32fab07 Mon Sep 17 00:00:00 2001 From: Jacob Bom Date: Fri, 11 Aug 2017 23:58:41 +0200 Subject: [PATCH] Switch to pytest + required fixes to code (#788) Required fixes: - CallbackQuery is now comparable. - Message.effective_attachment, Message.photo, Message.new_chat_members, Message.new_chat_photo & Game.text_entitties semantic fixes - when they are not defined, return an empty list. - Docstring fix to Update class. --- .coveragerc | 8 - .github/CONTRIBUTING.rst | 47 +- .pre-commit-config.yaml | 2 +- .travis.yml | 10 +- Makefile | 8 +- appveyor.yml | 6 +- requirements-dev.txt | 5 +- setup.cfg | 16 + telegram/bot.py | 2 +- telegram/callbackquery.py | 2 +- telegram/ext/dispatcher.py | 6 - telegram/games/game.py | 2 +- telegram/message.py | 8 +- telegram/update.py | 3 +- telegram/utils/request.py | 2 +- tests/README.md | 5 - tests/base.py | 106 -- tests/bots.py | 73 +- tests/conftest.py | 111 ++ tests/data/telegram_sticker.png | Bin 0 -> 42001 bytes tests/data/telegram_test_channel.jpg | Bin 0 -> 19511 bytes tests/test_animation.py | 108 +- tests/test_audio.py | 324 ++--- tests/test_bot.py | 756 ++++++----- tests/test_botan.py | 61 - tests/test_callbackquery.py | 152 +++ tests/test_callbackqueryhandler.py | 169 +++ tests/test_chat.py | 170 +-- tests/test_chatmember.py | 112 +- tests/test_choseninlineresult.py | 137 +- tests/test_choseninlineresulthandler.py | 139 +++ tests/test_commandhandler.py | 220 ++++ tests/test_constants.py | 75 +- tests/test_contact.py | 138 +-- tests/test_conversationhandler.py | 318 ++--- tests/test_dispatcher.py | 227 ++++ tests/test_document.py | 293 ++--- tests/test_file.py | 132 +- tests/test_filters.py | 571 ++++----- tests/test_forcereply.py | 82 +- tests/test_game.py | 134 +- tests/test_gamehighscore.py | 53 + tests/test_helpers.py | 28 +- tests/test_inlinekeyboardbutton.py | 105 +- tests/test_inlinekeyboardmarkup.py | 91 +- tests/test_inlinequery.py | 107 +- tests/test_inlinequeryhandler.py | 173 +++ tests/test_inlinequeryresultarticle.py | 158 ++- tests/test_inlinequeryresultaudio.py | 141 +-- tests/test_inlinequeryresultcachedaudio.py | 124 +- tests/test_inlinequeryresultcacheddocument.py | 141 +-- tests/test_inlinequeryresultcachedgif.py | 128 +- tests/test_inlinequeryresultcachedmpeg4gif.py | 134 +- tests/test_inlinequeryresultcachedphoto.py | 140 +-- tests/test_inlinequeryresultcachedsticker.py | 119 +- tests/test_inlinequeryresultcachedvideo.py | 140 +-- tests/test_inlinequeryresultcachedvoice.py | 132 +- tests/test_inlinequeryresultcontact.py | 152 ++- tests/test_inlinequeryresultdocument.py | 170 +-- tests/test_inlinequeryresultgame.py | 75 ++ tests/test_inlinequeryresultgif.py | 154 ++- tests/test_inlinequeryresultlocation.py | 151 ++- tests/test_inlinequeryresultmpeg4gif.py | 160 ++- tests/test_inlinequeryresultphoto.py | 157 ++- tests/test_inlinequeryresultvenue.py | 169 ++- tests/test_inlinequeryresultvideo.py | 180 ++- tests/test_inlinequeryresultvoice.py | 135 +- tests/test_inputcontactmessagecontent.py | 89 +- tests/test_inputlocationmessagecontent.py | 82 +- tests/test_inputmessagecontent.py | 30 +- tests/test_inputtextmessagecontent.py | 90 +- tests/test_inputvenuemessagecontent.py | 107 +- tests/test_invoice.py | 136 +- tests/test_jobqueue.py | 336 +++-- tests/test_keyboardbutton.py | 88 +- tests/test_labeledprice.py | 60 +- tests/test_location.py | 121 +- tests/test_message.py | 556 ++++++--- tests/test_messageentity.py | 80 +- tests/test_messagehandler.py | 184 +++ tests/test_messagequeue.py | 112 +- tests/test_meta.py | 42 + tests/test_official.py | 95 +- tests/test_orderinfo.py | 77 +- tests/test_parsemode.py | 49 +- tests/test_photo.py | 412 +++--- tests/test_precheckoutquery.py | 126 +- tests/test_precheckoutqueryhandler.py | 138 +++ tests/test_regexhandler.py | 206 +++ tests/test_replykeyboardmarkup.py | 118 +- tests/test_replykeyboardremove.py | 82 +- tests/test_replymarkup.py | 41 - tests/test_shippingaddress.py | 144 ++- tests/test_shippingoption.py | 99 +- tests/test_shippingquery.py | 113 +- tests/test_shippingqueryhandler.py | 139 +++ tests/test_sticker.py | 467 ++++--- tests/test_stringcommandhandler.py | 123 ++ tests/test_stringregexhandler.py | 127 ++ tests/test_successfulpayment.py | 124 +- tests/test_telegramobject.py | 76 ++ tests/test_typehandler.py | 82 ++ tests/test_update.py | 176 +-- tests/test_updater.py | 1103 +++-------------- tests/test_user.py | 171 ++- tests/test_venue.py | 134 +- tests/test_video.py | 321 +++-- tests/test_videonote.py | 261 ++-- tests/test_voice.py | 302 ++--- tests/travis_fold.py | 78 ++ travis.py | 93 -- 111 files changed, 8370 insertions(+), 7377 deletions(-) delete mode 100644 .coveragerc delete mode 100644 tests/README.md delete mode 100644 tests/base.py create mode 100644 tests/conftest.py create mode 100644 tests/data/telegram_sticker.png create mode 100644 tests/data/telegram_test_channel.jpg delete mode 100644 tests/test_botan.py create mode 100644 tests/test_callbackquery.py create mode 100644 tests/test_callbackqueryhandler.py create mode 100644 tests/test_choseninlineresulthandler.py create mode 100644 tests/test_commandhandler.py create mode 100644 tests/test_dispatcher.py create mode 100644 tests/test_gamehighscore.py create mode 100644 tests/test_inlinequeryhandler.py create mode 100644 tests/test_inlinequeryresultgame.py create mode 100644 tests/test_messagehandler.py create mode 100644 tests/test_meta.py create mode 100644 tests/test_precheckoutqueryhandler.py create mode 100644 tests/test_regexhandler.py delete mode 100644 tests/test_replymarkup.py create mode 100644 tests/test_shippingqueryhandler.py create mode 100644 tests/test_stringcommandhandler.py create mode 100644 tests/test_stringregexhandler.py create mode 100644 tests/test_telegramobject.py create mode 100644 tests/test_typehandler.py create mode 100644 tests/travis_fold.py delete mode 100644 travis.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 9c6d39cbb..000000000 --- a/.coveragerc +++ /dev/null @@ -1,8 +0,0 @@ -[run] -source = telegram -omit = telegram/vendor/* - -[report] -omit = - tests/ - telegram/vendor/* diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 1dc096b83..223dbb30f 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -1,10 +1,10 @@ How To Contribute -=================== +================= Every open source project lives from the generous help by contributors that sacrifice their time and ``python-telegram-bot`` is no different. To make participation as pleasant as possible, this project adheres to the `Code of Conduct`_ by the Python Software Foundation. Setting things up -------------------- +----------------- 1. Fork the ``python-telegram-bot`` repository to your GitHub account. @@ -35,7 +35,7 @@ Setting things up $ pre-commit install Finding something to do -################### +####################### If you already know what you'd like to work on, you can skip this section. @@ -44,7 +44,7 @@ If you have an idea for something to do, first check if it's already been filed Another great way to start contributing is by writing tests. Tests are really important because they help prevent developers from accidentally breaking existing code, allowing them to build cool things faster. If you're interested in helping out, let the development team know by posting to the `developers' mailing list`_, and we'll help you get started. Instructions for making a code change -#################### +##################################### The central development branch is ``master``, which should be clean and ready for release at any time. In general, all changes should be done as feature branches based off of ``master``. @@ -89,7 +89,7 @@ Here's how to make a one-off code change. .. code-block:: - $ nosetests -v + $ pytest -v - To actually make the commit (this will trigger tests for yapf, lint and pep8 automatically): @@ -129,19 +129,19 @@ Here's how to make a one-off code change. .. code-block:: bash - $ git checkout your-branch-name - $ git fetch upstream - $ git merge upstream/master - $ ...[fix the conflicts]... - $ ...[make sure the tests pass before committing]... - $ git commit -a - $ git push origin your-branch-name + $ git checkout your-branch-name + $ git fetch upstream + $ git merge upstream/master + $ ...[fix the conflicts]... + $ ...[make sure the tests pass before committing]... + $ git commit -a + $ git push origin your-branch-name - If after merging you see local modified files in ``telegram/vendor/`` directory, that you didn't actually touch, that means you need to update submodules with this command: .. code-block:: bash - $ git submodule update --init --recursive + $ git submodule update --init --recursive - At the end, the reviewer will merge the pull request. @@ -155,20 +155,29 @@ Here's how to make a one-off code change. 7. **Celebrate.** Congratulations, you have contributed to ``python-telegram-bot``! Style commandments ---------------------- +------------------ Specific commandments ##################### - Avoid using "double quotes" where you can reasonably use 'single quotes'. -AssertEqual argument order -###################### +Assert comparison order +####################### -- assertEqual method's arguments should be in ('actual', 'expected') order. +- assert statements should compare in **actual** == **expected** order. +For example (assuming ``test_call`` is the thing being tested): + +.. code-block:: python + + # GOOD + assert test_call() == 5 + + # BAD + assert 5 == test_call() Properly calling callables -####################### +########################## Methods, functions and classes can specify optional parameters (with default values) using Python's keyword arg syntax. When providing a value to such a @@ -186,7 +195,7 @@ This gives us the flexibility to re-order arguments and more importantly to add new required arguments. It's also more explicit and easier to read. Properly defining optional arguments -######################## +#################################### It's always good to not initialize optional arguments at class creation, instead use ``**kwargs`` to get them. It's well known Telegram API can diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1084512c7..edc3ec080 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,4 +17,4 @@ files: ^telegram/.*\.py$ args: - --errors-only - - --disable=no-name-in-module,import-error + - --disable=import-error diff --git a/.travis.yml b/.travis.yml index 803fd9462..25f22983c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,18 +18,20 @@ branches: cache: directories: - $HOME/.cache/pip + - $HOME/.pre-commit before_cache: - rm -f $HOME/.cache/pip/log/debug.log + - rm -f $HOME/.pre-commit/pre-commit.log install: - - pip install coveralls + - pip install coveralls pytest-cov - pip install -U wheel - - pip install -r requirements.txt - - pip install -r requirements-dev.txt + - pip install -U -r requirements.txt + - pip install -U -r requirements-dev.txt - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then pip install ujson; fi script: - - python travis.py + - pytest -v --cov=telegram after_success: coveralls \ No newline at end of file diff --git a/Makefile b/Makefile index 85bc6b813..ac90c183a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ .PHONY: clean pep257 pep8 yapf lint test install PYLINT := pylint -NOSETESTS := nosetests +PYTEST := pytest PEP257 := pep257 PEP8 := flake8 YAPF := yapf @@ -29,7 +29,7 @@ lint: $(PYLINT) -E telegram --disable=no-name-in-module,import-error test: - $(NOSETESTS) -v + $(PYTEST) -v install: $(PIP) install -r requirements.txt -r requirements-dev.txt @@ -41,11 +41,11 @@ help: @echo "- pep8 Check style with flake8" @echo "- lint Check style with pylint" @echo "- yapf Check style with yapf" - @echo "- test Run tests" + @echo "- test Run tests using pytest" @echo @echo "Available variables:" @echo "- PYLINT default: $(PYLINT)" - @echo "- NOSETESTS default: $(NOSETESTS)" + @echo "- PYTEST default: $(PYTEST)" @echo "- PEP257 default: $(PEP257)" @echo "- PEP8 default: $(PEP8)" @echo "- YAPF default: $(YAPF)" diff --git a/appveyor.yml b/appveyor.yml index ed07e60d7..c9182034b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,8 +24,4 @@ build: off cache: C:\Users\appveyor\pip\wheels test_script: - - "%python%\\Scripts\\nosetests -v --with-flaky --no-flaky-report tests" - -after_test: - # This step builds your wheels. - - "%PYTHON%\\python.exe setup.py bdist_wheel" + - "%python%\\Scripts\\pytest -v --cov=telegram" diff --git a/requirements-dev.txt b/requirements-dev.txt index 1ec26c73f..d729abf8a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,10 +1,9 @@ flake8 -nose pep257 pylint flaky yapf pre-commit -pre-commit-hooks beautifulsoup4 -rednose +pytest +pytest-timeout diff --git a/setup.cfg b/setup.cfg index 806137cc0..e9ce50bd4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,3 +17,19 @@ ignore = W503 based_on_style = google split_before_logical_operator = True column_limit = 99 + +[tool:pytest] +testpaths = tests +addopts = --no-success-flaky-report -rsxX +filterwarnings = + error + ignore::DeprecationWarning + +[coverage:run] +branch = False +source = telegram +omit = + tests/ + telegram/__main__.py + telegram/vendor/* + diff --git a/telegram/bot.py b/telegram/bot.py index dfda20026..5570382c6 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -1651,7 +1651,7 @@ class Bot(TelegramObject): url_ = '{0}/setWebhook'.format(self.base_url) # Backwards-compatibility: 'url' used to be named 'webhook_url' - if 'webhook_url' in kwargs: + if 'webhook_url' in kwargs: # pragma: no cover warnings.warn("The 'webhook_url' parameter has been renamed to 'url' in accordance " "with the API") diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py index 8c28a52a2..4d9e7dd41 100644 --- a/telegram/callbackquery.py +++ b/telegram/callbackquery.py @@ -90,7 +90,7 @@ class CallbackQuery(TelegramObject): self.bot = bot - self._id_attrs = ('id',) + self._id_attrs = (self.id,) @classmethod def de_json(cls, data, bot): diff --git a/telegram/ext/dispatcher.py b/telegram/ext/dispatcher.py index 8d79dd27b..81c52af0f 100644 --- a/telegram/ext/dispatcher.py +++ b/telegram/ext/dispatcher.py @@ -135,12 +135,6 @@ class Dispatcher(object): else: self._set_singleton(None) - @classmethod - def _reset_singleton(cls): - # NOTE: This method was added mainly for test_updater benefit and specifically pypy. Never - # call it in production code. - cls.__singleton_semaphore.release() - def _init_async_threads(self, base_name, workers): base_name = '{}_'.format(base_name) if base_name else '' diff --git a/telegram/games/game.py b/telegram/games/game.py index fe5f3154b..c12c2ebbf 100644 --- a/telegram/games/game.py +++ b/telegram/games/game.py @@ -68,7 +68,7 @@ class Game(TelegramObject): self.description = description self.photo = photo self.text = text - self.text_entities = text_entities + self.text_entities = text_entities or list() self.animation = animation @classmethod diff --git a/telegram/message.py b/telegram/message.py index 766ae2143..bf8477078 100644 --- a/telegram/message.py +++ b/telegram/message.py @@ -232,7 +232,7 @@ class Message(TelegramObject): self.audio = audio self.game = game self.document = document - self.photo = photo + self.photo = photo or list() self.sticker = sticker self.video = video self.voice = voice @@ -242,10 +242,10 @@ class Message(TelegramObject): self.location = location self.venue = venue self._new_chat_member = new_chat_member - self.new_chat_members = new_chat_members + self.new_chat_members = new_chat_members or list() self.left_chat_member = left_chat_member self.new_chat_title = new_chat_title - self.new_chat_photo = new_chat_photo + self.new_chat_photo = new_chat_photo or list() self.delete_chat_photo = bool(delete_chat_photo) self.group_chat_created = bool(group_chat_created) self.supergroup_chat_created = bool(supergroup_chat_created) @@ -330,7 +330,7 @@ class Message(TelegramObject): for i in (self.audio, self.game, self.document, self.photo, self.sticker, self.video, self.voice, self.video_note, self.contact, self.location, self.venue, self.invoice, self.successful_payment): - if i is not None: + if i: self._effective_attachment = i break else: diff --git a/telegram/update.py b/telegram/update.py index 18fa0380b..781e2f174 100644 --- a/telegram/update.py +++ b/telegram/update.py @@ -139,7 +139,8 @@ class Update(TelegramObject): """ :class:`telegram.Chat`: The chat that this update was sent in, no matter what kind of update this is. Will be ``None`` for :attr:`inline_query`, - :attr:`chosen_inline_result`, :attr:`shipping_query` and :attr:`pre_checkout_query`. + :attr:`chosen_inline_result`, :attr:`callback_query` from inline messages, + :attr:`shipping_query` and :attr:`pre_checkout_query`. """ if self._effective_chat: diff --git a/telegram/utils/request.py b/telegram/utils/request.py index f4654eb55..574dd2c2f 100644 --- a/telegram/utils/request.py +++ b/telegram/utils/request.py @@ -34,7 +34,7 @@ try: import telegram.vendor.ptb_urllib3.urllib3.contrib.appengine as appengine from telegram.vendor.ptb_urllib3.urllib3.connection import HTTPConnection from telegram.vendor.ptb_urllib3.urllib3.util.timeout import Timeout -except ImportError: +except ImportError: # pragma: no cover warnings.warn("python-telegram-bot wasn't properly installed. Please refer to README.rst on " "how to properly install.") raise diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index dcd87b733..000000000 --- a/tests/README.md +++ /dev/null @@ -1,5 +0,0 @@ -tests -===== - -Some tests fail because of weird behaviour of the Telegram API. We comment these -out and mark them with a `TODO` comment. diff --git a/tests/base.py b/tests/base.py deleted file mode 100644 index 22209d719..000000000 --- a/tests/base.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2017 -# 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 an object that represents a Base class for tests""" - -import os -import signal -import sys - -from nose.tools import make_decorator - -from tests.bots import get_bot - -sys.path.append('.') - -import json -import telegram - - -class BaseTest(object): - """This object represents a Base test and its sets of functions.""" - - _group_id = None - _channel_id = None - _bot = None - _chat_id = None - _payment_provider_token = None - - @classmethod - def setUpClass(cls): - bot_info = get_bot() - cls._chat_id = bot_info['chat_id'] - cls._bot = telegram.Bot(bot_info['token']) - cls._group_id = bot_info['group_id'] - cls._channel_id = bot_info['channel_id'] - cls._payment_provider_token = bot_info['payment_provider_token'] - - @staticmethod - def is_json(string): - try: - json.loads(string) - except ValueError: - return False - - return True - - @staticmethod - def is_dict(dictionary): - if isinstance(dictionary, dict): - return True - - return False - - -class TestTimedOut(AssertionError): - - def __init__(self, time_limit, frame): - super(TestTimedOut, self).__init__('time_limit={0}'.format(time_limit)) - 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): - try: - # Will only work on unix systems - orig_handler = signal.signal(signal.SIGALRM, timed_out) - signal.alarm(time_limit) - except AttributeError: - pass - try: - rc = func(*args, **kwargs) - finally: - try: - # Will only work on unix systems - signal.alarm(0) - signal.signal(signal.SIGALRM, orig_handler) - except AttributeError: - pass - return rc - - newfunc = make_decorator(func)(newfunc) - return newfunc - - return decorator diff --git a/tests/bots.py b/tests/bots.py index ed31e3b5f..73fa3b397 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -5,62 +5,51 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. """Provide a bot to tests""" import os - import sys +from platform import python_implementation -bot_settings = { - 'APPVEYOR': - { - 'token': '133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0', - 'payment_provider_token': '284685063:TEST:ZGJlMmQxZDI3ZTc3' - }, - 'TRAVIS': - { - 'token': '133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0', - 'payment_provider_token': '284685063:TEST:ZGJlMmQxZDI3ZTc3' - }, - 'FALLBACK': - { - 'token': '133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0', - 'payment_provider_token': '284685063:TEST:ZGJlMmQxZDI3ZTc3' - } +# Provide some public fallbacks so it's easy for contributors to run tests on their local machine +FALLBACKS = { + 'token': '133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0', + 'payment_provider_token': '284685063:TEST:ZGJlMmQxZDI3ZTc3', + 'chat_id': '12173560', + 'group_id': '-49740850', + 'channel_id': '@pythontelegrambottests' } -def get_bot(): - # TODO: Add version info with different bots - # ver = sys.version_info - # pyver = "{}{}".format(ver[0], ver[1]) - # - bot = None - if os.environ.get('TRAVIS', False): - bot = bot_settings.get('TRAVIS', None) - # TODO: - # bot = bot_setting.get('TRAVIS'+pyver, None) - elif os.environ.get('APPVEYOR', False): - bot = bot_settings.get('APPVEYOR', None) - # TODO: - # bot = bot_setting.get('TRAVIS'+pyver, None) - if not bot: - bot = bot_settings['FALLBACK'] +def get(name, fallback): + full_name = '{0}-{1}-{2[0]}{2[1]}'.format(name, python_implementation(), + sys.version_info).upper() + # First try fullnames such as + # TOKEN-CPYTHON-33 + # CHAT_ID-PYPY-27 + val = os.getenv(full_name) + if val: + return val + # Then try short names + # TOKEN + # CHAT_ID + val = os.getenv(name.upper()) + if val: + return val + # Otherwise go with the fallback + return fallback - bot.update({ - 'chat_id': '12173560', - 'group_id': '-49740850', - 'channel_id': '@pythontelegrambottests' - }) - return bot + +def get_bot(): + return {k: get(k, v) for k, v in FALLBACKS.items()} diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 000000000..c18008a82 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import os +import sys +from collections import defaultdict +from queue import Queue +from threading import Thread, Event +from time import sleep + +import pytest + +from telegram import Bot +from telegram.ext import Dispatcher, JobQueue +from tests.bots import get_bot + +TRAVIS = os.getenv('TRAVIS', False) + +if TRAVIS: + pytest_plugins = ['tests.travis_fold'] + + +@pytest.fixture(scope='session') +def bot_info(): + return get_bot() + + +@pytest.fixture(scope='session') +def bot(bot_info): + return Bot(bot_info['token']) + + +@pytest.fixture(scope='session') +def chat_id(bot_info): + return bot_info['chat_id'] + + +@pytest.fixture(scope='session') +def group_id(bot_info): + return bot_info['group_id'] + + +@pytest.fixture(scope='session') +def channel_id(bot_info): + return bot_info['channel_id'] + + +@pytest.fixture(scope='session') +def provider_token(bot_info): + return bot_info['payment_provider_token'] + + +def create_dp(bot): + # Dispatcher is heavy to init (due to many threads and such) so we have a single session + # scoped one here, but before each test, reset it (dp fixture below) + dispatcher = Dispatcher(bot, Queue(), job_queue=JobQueue(bot), workers=2) + thr = Thread(target=dispatcher.start) + thr.start() + sleep(2) + yield dispatcher + sleep(1) + if dispatcher.running: + dispatcher.stop() + thr.join() + + +@pytest.fixture(scope='session') +def _dp(bot): + for dp in create_dp(bot): + yield dp + + +@pytest.fixture(scope='function') +def dp(_dp): + # Reset the dispatcher first + while not _dp.update_queue.empty(): + _dp.update_queue.get(False) + _dp.chat_data = defaultdict(dict) + _dp.user_data = defaultdict(dict) + _dp.handlers = {} + _dp.groups = [] + _dp.error_handlers = [] + _dp.__stop_event = Event() + _dp.__exception_event = Event() + _dp.__async_queue = Queue() + _dp.__async_threads = set() + if _dp._Dispatcher__singleton_semaphore.acquire(blocking=0): + Dispatcher._set_singleton(_dp) + yield _dp + Dispatcher._Dispatcher__singleton_semaphore.release() + + +def pytest_configure(config): + if sys.version_info >= (3,): + config.addinivalue_line('filterwarnings', 'ignore::ResourceWarning') + # TODO: Write so good code that we don't need to ignore ResourceWarnings anymore diff --git a/tests/data/telegram_sticker.png b/tests/data/telegram_sticker.png new file mode 100644 index 0000000000000000000000000000000000000000..ef425db55093d0d4da5c0865562578d1c5111837 GIT binary patch literal 42001 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

GuC=Ve)|zBZ3drNt4Y9G_?Ha7vZv)nwPPt8W@k3 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 literal 0 HcmV?d00001 diff --git a/tests/data/telegram_test_channel.jpg b/tests/data/telegram_test_channel.jpg new file mode 100644 index 0000000000000000000000000000000000000000..561f1b378b416c5b0d87181e4de5f8faa008e8be GIT binary patch literal 19511 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 # # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Animation""" -import unittest -import sys +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import PhotoSize, Animation, Voice -class AnimationTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Animation.""" +@pytest.fixture(scope='class') +def thumb(): + return PhotoSize(height=50, file_size=1613, file_id='AAQEABPQUWQZAAT7gZuQAAH0bd93VwACAg', + width=90) - def setUp(self): - self.animation_file_id = 'CgADBAADFQEAAny4rAUgukhiTv2TWwI' - self.thumb = telegram.PhotoSize.de_json({ - 'height': 50, - 'file_size': 1613, - 'file_id': 'AAQEABPQUWQZAAT7gZuQAAH0bd93VwACAg', - 'width': 90 - }, self._bot) - self.file_name = "game.gif.mp4" - self.mime_type = "video/mp4" - self.file_size = 4008 - self.json_dict = { +@pytest.fixture(scope='class') +def animation(thumb, bot): + return Animation(TestAnimation.animation_file_id, thumb=thumb.to_dict(), + file_name=TestAnimation.file_name, mime_type=TestAnimation.mime_type, + file_size=TestAnimation.file_size, bot=bot) + + +class TestAnimation(object): + animation_file_id = 'CgADBAADFQEAAny4rAUgukhiTv2TWwI' + file_name = 'game.gif.mp4' + mime_type = 'video/mp4' + file_size = 4008 + + def test_de_json(self, bot, thumb): + json_dict = { 'file_id': self.animation_file_id, - 'thumb': self.thumb.to_dict(), + 'thumb': thumb.to_dict(), 'file_name': self.file_name, 'mime_type': self.mime_type, 'file_size': self.file_size } + animation = Animation.de_json(json_dict, bot) + assert animation.file_id == self.animation_file_id + assert animation.thumb == thumb + assert animation.file_name == self.file_name + assert animation.mime_type == self.mime_type + assert animation.file_size == self.file_size - def test_animation_de_json(self): - animation = telegram.Animation.de_json(self.json_dict, self._bot) + def test_to_dict(self, animation, thumb): + animation_dict = animation.to_dict() - self.assertEqual(animation.file_id, self.animation_file_id) - self.assertEqual(animation.thumb, self.thumb) - self.assertEqual(animation.file_name, self.file_name) - self.assertEqual(animation.mime_type, self.mime_type) - self.assertEqual(animation.file_size, self.file_size) - - def test_animation_to_json(self): - animation = telegram.Animation.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(animation.to_json())) - - def test_animation_to_dict(self): - animation = telegram.Animation.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_dict(animation.to_dict())) - self.assertEqual(animation.file_id, self.animation_file_id) - self.assertEqual(animation.thumb, self.thumb) - self.assertEqual(animation.file_name, self.file_name) - self.assertEqual(animation.mime_type, self.mime_type) - self.assertEqual(animation.file_size, self.file_size) + assert isinstance(animation_dict, dict) + assert animation_dict['file_id'] == animation.file_id + assert animation_dict['thumb'] == thumb.to_dict() + assert animation_dict['file_name'] == animation.file_name + assert animation_dict['mime_type'] == animation.mime_type + assert animation_dict['file_size'] == animation.file_size def test_equality(self): - a = telegram.Animation(self.animation_file_id) - b = telegram.Animation(self.animation_file_id) - d = telegram.Animation("") - e = telegram.Voice(self.animation_file_id, 0) + a = Animation(self.animation_file_id) + b = Animation(self.animation_file_id) + d = Animation('') + e = Voice(self.animation_file_id, 0) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_audio.py b/tests/test_audio.py index b6db1b1ee..efad15925 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -5,248 +5,182 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Audio""" - import os -import unittest +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import Audio, TelegramError, Voice -class AudioTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Audio.""" +@pytest.fixture(scope='function') +def audio_file(): + f = open('tests/data/telegram.mp3', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(AudioTest, cls).setUpClass() - cls.caption = "Test audio" - cls.performer = 'Leandro Toledo' - cls.title = 'Teste' - # cls.audio_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.mp3' - # Shortened link, the above one is cached with the wrong duration. - cls.audio_file_url = "https://goo.gl/3En24v" +@pytest.fixture(scope='class') +def audio(bot, chat_id): + with open('tests/data/telegram.mp3', 'rb') as f: + return bot.send_audio(chat_id, audio=f, timeout=10).audio - audio_file = open('tests/data/telegram.mp3', 'rb') - audio = cls._bot.send_audio(cls._chat_id, audio=audio_file, timeout=10).audio - cls.audio = audio +class TestAudio(object): + caption = 'Test audio' + performer = 'Leandro Toledo' + title = 'Teste' + duration = 3 + # audio_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.mp3' + # Shortened link, the above one is cached with the wrong duration. + audio_file_url = 'https://goo.gl/3En24v' + mime_type = 'audio/mpeg' + file_size = 122920 + + def test_creation(self, audio): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.audio, telegram.Audio) - assert isinstance(cls.audio.file_id, str) - assert cls.audio.file_id is not '' + assert isinstance(audio, Audio) + assert isinstance(audio.file_id, str) + assert audio.file_id is not '' - def setUp(self): - self.audio_file = open('tests/data/telegram.mp3', 'rb') - self.json_dict = { - 'file_id': self.audio.file_id, - 'duration': self.audio.duration, - 'performer': self.performer, - 'title': self.title, - 'caption': self.caption, - 'mime_type': self.audio.mime_type, - 'file_size': self.audio.file_size - } - - def test_expected_values(self): - self.assertEqual(self.audio.duration, 3) - self.assertEqual(self.audio.performer, None) - self.assertEqual(self.audio.title, None) - self.assertEqual(self.audio.mime_type, 'audio/mpeg') - self.assertEqual(self.audio.file_size, 122920) + def test_expected_values(self, audio): + assert audio.duration == self.duration + assert audio.performer is None + assert audio.title is None + assert audio.mime_type == self.mime_type + assert audio.file_size == self.file_size @flaky(3, 1) - @timeout(10) - def test_send_audio_all_args(self): - message = self._bot.sendAudio( - self._chat_id, - self.audio_file, - caption=self.caption, - duration=self.audio.duration, - performer=self.performer, - title=self.title, - disable_notification=False) + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, audio_file): + message = bot.send_audio(chat_id, audio=audio_file, caption=self.caption, + duration=self.duration, performer=self.performer, + title=self.title, disable_notification=False) - self.assertEqual(message.caption, self.caption) + assert message.caption == self.caption - audio = message.audio - - self.assertIsInstance(audio, telegram.Audio) - self.assertIsInstance(audio.file_id, str) - self.assertNotEqual(audio.file_id, None) - self.assertEqual(audio.duration, self.audio.duration) - self.assertEqual(audio.performer, self.performer) - self.assertEqual(audio.title, self.title) - self.assertEqual(audio.mime_type, self.audio.mime_type) - self.assertEqual(audio.file_size, self.audio.file_size) + assert isinstance(message.audio, Audio) + assert isinstance(message.audio.file_id, str) + assert message.audio.file_id is not None + assert message.audio.duration == self.duration + assert message.audio.performer == self.performer + assert message.audio.title == self.title + assert message.audio.mime_type == self.mime_type + assert message.audio.file_size == self.file_size @flaky(3, 1) - @timeout(10) - def test_get_and_download_audio(self): - new_file = self._bot.getFile(self.audio.file_id) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, audio): + new_file = bot.get_file(audio.file_id) - self.assertEqual(new_file.file_size, self.audio.file_size) - self.assertEqual(new_file.file_id, self.audio.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == self.file_size + assert new_file.file_id == audio.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram.mp3') - self.assertTrue(os.path.isfile('telegram.mp3')) + assert os.path.isfile('telegram.mp3') @flaky(3, 1) - @timeout(10) - def test_send_audio_mp3_url_file(self): - message = self._bot.sendAudio(chat_id=self._chat_id, audio=self.audio_file_url) + @pytest.mark.timeout(10) + def test_send_mp3_url_file(self, bot, chat_id, audio): + message = bot.send_audio(chat_id=chat_id, audio=self.audio_file_url, caption=self.caption) - audio = message.audio + assert message.caption == self.caption - self.assertIsInstance(audio, telegram.Audio) - self.assertIsInstance(audio.file_id, str) - self.assertNotEqual(audio.file_id, None) - self.assertEqual(audio.duration, self.audio.duration) - self.assertEqual(audio.mime_type, self.audio.mime_type) - self.assertEqual(audio.file_size, self.audio.file_size) + assert isinstance(message.audio, Audio) + assert isinstance(message.audio.file_id, str) + assert message.audio.file_id is not None + assert message.audio.duration == audio.duration + assert message.audio.mime_type == audio.mime_type + assert message.audio.file_size == audio.file_size @flaky(3, 1) - @timeout(10) - def test_send_audio_mp3_url_file_with_caption(self): - message = self._bot.sendAudio( - chat_id=self._chat_id, - audio=self.audio_file_url, - caption=self.caption) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, audio): + message = bot.send_audio(chat_id=chat_id, audio=audio.file_id) - self.assertEqual(message.caption, self.caption) + assert message.audio == audio - audio = message.audio + def test_send_with_audio(self, monkeypatch, bot, chat_id, audio): + def test(_, url, data, **kwargs): + return data['audio'] == audio.file_id - self.assertIsInstance(audio, telegram.Audio) - self.assertIsInstance(audio.file_id, str) - self.assertNotEqual(audio.file_id, None) - self.assertEqual(audio.duration, self.audio.duration) - self.assertEqual(audio.mime_type, self.audio.mime_type) - self.assertEqual(audio.file_size, self.audio.file_size) + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_audio(audio=audio, chat_id=chat_id) + assert message + + def test_de_json(self, bot): + json_dict = {'file_id': 'not a file id', + 'duration': self.duration, + 'performer': self.performer, + 'title': self.title, + 'caption': self.caption, + 'mime_type': self.mime_type, + 'file_size': self.file_size} + json_audio = Audio.de_json(json_dict, bot) + + assert json_audio.file_id == 'not a file id' + assert json_audio.duration == self.duration + assert json_audio.performer == self.performer + assert json_audio.title == self.title + assert json_audio.mime_type == self.mime_type + assert json_audio.file_size == self.file_size + + def test_to_dict(self, audio): + audio_dict = audio.to_dict() + + assert isinstance(audio_dict, dict) + assert audio_dict['file_id'] == audio.file_id + assert audio_dict['duration'] == audio.duration + assert audio_dict['mime_type'] == audio.mime_type + assert audio_dict['file_size'] == audio.file_size @flaky(3, 1) - @timeout(10) - def test_send_audio_resend(self): - message = self._bot.sendAudio( - chat_id=self._chat_id, - audio=self.audio.file_id) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + audio_file = open(os.devnull, 'rb') - audio = message.audio - - self.assertEqual(audio, self.audio) + with pytest.raises(TelegramError): + bot.send_audio(chat_id=chat_id, audio=audio_file) @flaky(3, 1) - @timeout(10) - def test_send_audio_with_audio(self): - message = self._bot.send_audio(audio=self.audio, chat_id=self._chat_id) - audio = message.audio + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_audio(chat_id=chat_id, audio='') - self.assertEqual(audio, self.audio) + def test_error_send_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_audio(chat_id=chat_id) - def test_audio_de_json(self): - audio = telegram.Audio.de_json(self.json_dict, self._bot) + def test_equality(self, audio): + a = Audio(audio.file_id, audio.duration) + b = Audio(audio.file_id, audio.duration) + c = Audio(audio.file_id, 0) + d = Audio('', audio.duration) + e = Voice(audio.file_id, audio.duration) - self.assertIsInstance(audio, telegram.Audio) - self.assertEqual(audio.file_id, self.audio.file_id) - self.assertEqual(audio.duration, self.audio.duration) - self.assertEqual(audio.performer, self.performer) - self.assertEqual(audio.title, self.title) - self.assertEqual(audio.mime_type, self.audio.mime_type) - self.assertEqual(audio.file_size, self.audio.file_size) + assert a == b + assert hash(a) == hash(b) + assert a is not b - def test_audio_to_json(self): - self.assertTrue(self.is_json(self.audio.to_json())) + assert a == c + assert hash(a) == hash(c) - def test_audio_to_dict(self): - audio = self.audio.to_dict() + assert a != d + assert hash(a) != hash(d) - self.assertTrue(self.is_dict(audio)) - self.assertEqual(audio['file_id'], self.audio.file_id) - self.assertEqual(audio['duration'], self.audio.duration) - self.assertEqual(audio['mime_type'], self.audio.mime_type) - self.assertEqual(audio['file_size'], self.audio.file_size) - - @flaky(3, 1) - @timeout(10) - def test_error_send_audio_empty_file(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['audio'] = open(os.devnull, 'rb') - - with self.assertRaises(telegram.TelegramError): - self._bot.sendAudio(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_send_audio_empty_file_id(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['audio'] = '' - - with self.assertRaises(telegram.TelegramError): - self._bot.sendAudio(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_audio_without_required_args(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - del (json_dict['duration']) - - with self.assertRaises(TypeError): - self._bot.sendAudio(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_reply_audio(self): - """Test for Message.reply_audio""" - message = self._bot.sendMessage(self._chat_id, '.') - audio = message.reply_audio(self.audio_file).audio - - self.assertIsInstance(audio, telegram.Audio) - self.assertIsInstance(audio.file_id, str) - self.assertNotEqual(audio.file_id, None) - - def test_equality(self): - a = telegram.Audio(self.audio.file_id, self.audio.duration) - b = telegram.Audio(self.audio.file_id, self.audio.duration) - c = telegram.Audio(self.audio.file_id, 0) - d = telegram.Audio("", self.audio.duration) - e = telegram.Voice(self.audio.file_id, self.audio.duration) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_bot.py b/tests/test_bot.py index 722bb971a..f05e423ba 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1,424 +1,618 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Bot""" - -import io -import re -from datetime import datetime import time -import sys -import unittest +from datetime import datetime, timedelta +from platform import python_implementation +import pytest from flaky import flaky +from future.utils import string_types -sys.path.append('.') - -import telegram -from telegram.utils.request import Request -from telegram.error import BadRequest -from tests.base import BaseTest, timeout +from telegram import (Bot, Update, ChatAction, TelegramError, User, InlineKeyboardMarkup, + InlineKeyboardButton, InlineQueryResultArticle, InputTextMessageContent, + ShippingOption, LabeledPrice) +from telegram.error import BadRequest, InvalidToken, NetworkError, RetryAfter, TimedOut +from telegram.utils.helpers import from_timestamp BASE_TIME = time.time() HIGHSCORE_DELTA = 1450000000 -def _stall_retry(*_args, **_kwargs): - time.sleep(3) - return True +@pytest.fixture(scope='class') +def message(bot, chat_id): + return bot.send_message(chat_id, 'Text', reply_to_message_id=1, + disable_web_page_preview=True, disable_notification=True) -class BotTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Bot.""" +@pytest.fixture(scope='class') +def media_message(bot, chat_id): + with open('tests/data/telegram.ogg', 'rb') as f: + return bot.send_voice(chat_id, voice=f, caption='my caption', timeout=10) + + +class TestBot(object): + @pytest.mark.parametrize('token', argvalues=[ + '123', + '12a:abcd1234', + '12:abcd1234', + '1234:abcd1234\n', + ' 1234:abcd1234', + ' 1234:abcd1234\r', + '1234:abcd 1234' + ]) + def test_invalid_token(self, token): + with pytest.raises(InvalidToken, match='Invalid token'): + Bot(token) @flaky(3, 1) - @timeout(10) - def testGetMe(self): - bot = self._bot.getMe() - - self.assertTrue(self.is_json(bot.to_json())) - self._testUserEqualsBot(bot) + @pytest.mark.timeout(10) + def test_invalid_token_server_response(self, monkeypatch): + monkeypatch.setattr('telegram.Bot._validate_token', lambda x, y: True) + bot = Bot('12') + with pytest.raises(InvalidToken): + bot.get_me() @flaky(3, 1) - @timeout(10) - def testSendMessage(self): - message = self._bot.sendMessage( - chat_id=self._chat_id, text='Моё судно на воздушной подушке полно угрей') + @pytest.mark.timeout(10) + def test_get_me_and_properties(self, bot): + get_me_bot = bot.get_me() - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') - self.assertTrue(isinstance(message.date, datetime)) + assert isinstance(get_me_bot, User) + assert get_me_bot.id == bot.id + assert get_me_bot.username == bot.username + assert get_me_bot.first_name == bot.first_name + assert get_me_bot.last_name == bot.last_name + assert get_me_bot.name == bot.name @flaky(3, 1) - @timeout(10) - def testSilentSendMessage(self): - message = self._bot.sendMessage( - chat_id=self._chat_id, - text='Моё судно на воздушной подушке полно угрей', - disable_notification=True) + @pytest.mark.timeout(10) + def test_forward_message(self, bot, chat_id, message): + message = bot.forward_message(chat_id, from_chat_id=chat_id, message_id=message.message_id) - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') - self.assertTrue(isinstance(message.date, datetime)) + assert message.text == message.text + assert message.forward_from.username == message.from_user.username + assert isinstance(message.forward_date, datetime) @flaky(3, 1) - @timeout(10) - def test_sendMessage_no_web_page_preview(self): - message = self._bot.sendMessage( - chat_id=self._chat_id, - text='Моё судно на воздушной подушке полно угрей', - disable_web_page_preview=True) + @pytest.mark.timeout(10) + def test_delete_message(self, bot, chat_id): + message = bot.send_message(chat_id, text='will be deleted') - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') + assert bot.delete_message(chat_id=chat_id, message_id=message.message_id) is True @flaky(3, 1) - @timeout(10) - def test_deleteMessage(self): - message = self._bot.send_message( - chat_id=self._chat_id, text='This message will be deleted') - - self.assertTrue( - self._bot.delete_message( - chat_id=self._chat_id, message_id=message.message_id)) - - @flaky(3, 1) - @timeout(10) - def test_deleteMessage_old_message(self): - with self.assertRaisesRegexp(telegram.TelegramError, "can't be deleted"): + @pytest.mark.timeout(10) + def test_delete_message_old_message(self, bot, chat_id): + with pytest.raises(TelegramError, match='can\'t be deleted'): # Considering that the first message is old enough - self._bot.delete_message(chat_id=self._chat_id, message_id=1) + bot.delete_message(chat_id=chat_id, message_id=1) + + # send_photo, send_audio, send_document, send_sticker, send_video, send_voice + # and send_video_note are tested in their respective test modules. No need to duplicate here. @flaky(3, 1) - @timeout(10) - def testGetUpdates(self): - self._bot.delete_webhook() # make sure there is no webhook set if webhook tests failed - updates = self._bot.getUpdates(timeout=1) + @pytest.mark.timeout(10) + def test_send_location(self, bot, chat_id): + message = bot.send_location(chat_id=chat_id, latitude=-23.691288, longitude=-46.788279) - if updates: - self.assertTrue(self.is_json(updates[0].to_json())) - self.assertTrue(isinstance(updates[0], telegram.Update)) + assert message.location + assert message.location.longitude == -46.788279 + assert message.location.latitude == -23.691288 @flaky(3, 1) - @timeout(10) - def testForwardMessage(self): - message = self._bot.forwardMessage( - chat_id=self._chat_id, from_chat_id=self._chat_id, message_id=2398) + @pytest.mark.timeout(10) + def test_send_venue(self, bot, chat_id): + longitude = -46.788279 + latitude = -23.691288 + title = 'title' + address = 'address' + message = bot.send_venue(chat_id=chat_id, title=title, address=address, latitude=latitude, + longitude=longitude) - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, 'teste') - self.assertEqual(message.forward_from.username, 'leandrotoledo') - self.assertTrue(isinstance(message.forward_date, datetime)) + assert message.venue + assert message.venue.title == title + assert message.venue.address == address + assert message.venue.location.latitude == latitude + assert message.venue.location.longitude == longitude @flaky(3, 1) - @timeout(10) - def testSendGame(self): + @pytest.mark.timeout(10) + @pytest.mark.xfail(raises=RetryAfter) + @pytest.mark.skipif(python_implementation() == 'PyPy', + reason='Unstable on pypy for some reason') + def test_send_contact(self, bot, chat_id): + phone_number = '+11234567890' + first_name = 'Leandro' + last_name = 'Toledo' + message = bot.send_contact(chat_id=chat_id, phone_number=phone_number, + first_name=first_name, last_name=last_name) + + assert message.contact + assert message.contact.phone_number == phone_number + assert message.contact.first_name == first_name + assert message.contact.last_name == last_name + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_game(self, bot, chat_id): game_short_name = 'python_telegram_bot_test_game' - message = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + message = bot.send_game(chat_id, game_short_name) - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.game.description, 'This is a test game for python-telegram-bot.') - self.assertEqual(message.game.animation.file_id, 'CgADAQADKwIAAvjAuQABozciVqhFDO0C') - self.assertEqual(message.game.photo[0].file_size, 851) + assert message.game + assert message.game.description == 'This is a test game for python-telegram-bot.' + assert message.game.animation.file_id == 'CgADAQADKwIAAvjAuQABozciVqhFDO0C' + assert message.game.photo[0].file_size == 851 @flaky(3, 1) - @timeout(10) - def testSendChatAction(self): - self._bot.sendChatAction(action=telegram.ChatAction.TYPING, chat_id=self._chat_id) + @pytest.mark.timeout(10) + def test_send_chat_action(self, bot, chat_id): + assert bot.send_chat_action(chat_id, ChatAction.TYPING) + + # TODO: Needs improvement. We need incoming inline query to test answer. + def test_answer_inline_query(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'cache_time': 300, + 'results': [{'title': 'first', 'id': '11', 'type': 'article', + 'input_message_content': {'message_text': 'first'}}, + {'title': 'second', 'id': '12', 'type': 'article', + 'input_message_content': {'message_text': 'second'}}], + 'next_offset': '42', 'switch_pm_parameter': 'start_pm', + 'inline_query_id': 1234, 'is_personal': True, + 'switch_pm_text': 'switch pm'} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + results = [InlineQueryResultArticle('11', 'first', InputTextMessageContent('first')), + InlineQueryResultArticle('12', 'second', InputTextMessageContent('second'))] + + assert bot.answer_inline_query(1234, + results=results, + cache_time=300, + is_personal=True, + next_offset='42', + switch_pm_text='switch pm', + switch_pm_parameter='start_pm') @flaky(3, 1) - @timeout(10) - def testGetUserProfilePhotos(self): - upf = self._bot.getUserProfilePhotos(user_id=self._chat_id) + @pytest.mark.timeout(10) + def test_get_user_profile_photos(self, bot, chat_id): + user_profile_photos = bot.get_user_profile_photos(chat_id) - self.assertTrue(self.is_json(upf.to_json())) - self.assertEqual(upf.photos[0][0].file_size, 12421) + assert user_profile_photos.photos[0][0].file_size == 12421 @flaky(3, 1) - @timeout(10) - def test_get_one_user_profile_photo(self): - upf = self._bot.getUserProfilePhotos(user_id=self._chat_id, offset=0) - self.assertTrue(self.is_json(upf.to_json())) - self.assertEqual(upf.photos[0][0].file_size, 12421) + @pytest.mark.timeout(10) + def test_get_one_user_profile_photo(self, bot, chat_id): + user_profile_photos = bot.get_user_profile_photos(chat_id, offset=0, limit=1) + assert user_profile_photos.photos[0][0].file_size == 12421 - def _test_invalid_token(self, token): - self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token', telegram.Bot, token) + # get_file is tested multiple times in the test_*media* modules. - def testInvalidToken1(self): - self._test_invalid_token('123') + # TODO: Needs improvement. No feasable way to test until bots can add members. + def test_kick_chat_member(self, monkeypatch, bot): + def test(_, url, data, *args, **kwargs): + chat_id = data['chat_id'] == 2 + user_id = data['user_id'] == 32 + until_date = data.get('until_date', 1577887200) == 1577887200 + return chat_id and user_id and until_date - def testInvalidToken2(self): - self._test_invalid_token('12a:') + monkeypatch.setattr('telegram.utils.request.Request.post', test) + until = from_timestamp(1577887200) - def testInvalidToken3(self): - self._test_invalid_token('12:') + assert bot.kick_chat_member(2, 32) + assert bot.kick_chat_member(2, 32, until_date=until) + assert bot.kick_chat_member(2, 32, until_date=1577887200) - def testInvalidToken4(self): - # white spaces are invalid - self._test_invalid_token('1234:abcd1234\n') - self._test_invalid_token(' 1234:abcd1234') - self._test_invalid_token(' 1234:abcd1234\r') - self._test_invalid_token('1234:abcd 1234') + # TODO: Needs improvement. + def test_unban_chat_member(self, monkeypatch, bot): + def test(_, url, data, *args, **kwargs): + chat_id = data['chat_id'] == 2 + user_id = data['user_id'] == 32 + return chat_id and user_id - def testUnauthToken(self): - with self.assertRaisesRegexp(telegram.error.Unauthorized, 'Unauthorized'): - bot = telegram.Bot('1234:abcd1234') - bot.getMe() + monkeypatch.setattr('telegram.utils.request.Request.post', test) - def testInvalidSrvResp(self): - with self.assertRaisesRegexp(telegram.error.InvalidToken, 'Invalid token'): - # bypass the valid token check - newbot_cls = type( - 'NoTokenValidateBot', (telegram.Bot,), dict(_validate_token=lambda x, y: None)) - bot = newbot_cls('0xdeadbeef') - bot.base_url = 'https://api.telegram.org/bot{0}'.format('12') + assert bot.unban_chat_member(2, 32) - bot.getMe() + # TODO: Needs improvement. Need an incoming callbackquery to test + def test_answer_callback_query(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'callback_query_id': 23, 'show_alert': True, 'url': 'no_url', + 'cache_time': 1, 'text': 'answer'} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + + assert bot.answer_callback_query(23, text='answer', show_alert=True, url='no_url', + cache_time=1) @flaky(3, 1) - @timeout(10) - def testLeaveChat(self): - regex = re.compile('chat not found', re.IGNORECASE) - with self.assertRaisesRegexp(telegram.error.BadRequest, regex): - chat = self._bot.leaveChat(-123456) + @pytest.mark.timeout(10) + def test_edit_message_text(self, bot, message): + message = bot.edit_message_text(text='new_text', chat_id=message.chat_id, + message_id=message.message_id, parse_mode='HTML', + disable_web_page_preview=True) - with self.assertRaisesRegexp(telegram.error.NetworkError, regex): - chat = self._bot.leaveChat(-123456) + assert message.text == 'new_text' + + @pytest.mark.skip(reason='need reference to an inline message') + def test_edit_message_text_inline(self): + pass @flaky(3, 1) - @timeout(10) - def testGetChat(self): - chat = self._bot.getChat(self._group_id) + @pytest.mark.timeout(10) + def test_edit_message_caption(self, bot, media_message): + message = bot.edit_message_caption(caption='new_caption', chat_id=media_message.chat_id, + message_id=media_message.message_id) - self.assertTrue(self.is_json(chat.to_json())) - self.assertEqual(chat.type, "group") - self.assertEqual(chat.title, ">>> telegram.Bot() - Developers") - self.assertEqual(chat.id, int(self._group_id)) + assert message.caption == 'new_caption' + + @pytest.mark.xfail(raises=TelegramError) # TODO: remove when #744 is merged + def test_edit_message_caption_without_required(self, bot): + with pytest.raises(ValueError, match='Both chat_id and message_id are required when'): + bot.edit_message_caption(caption='new_caption') + + @pytest.mark.skip(reason='need reference to an inline message') + def test_edit_message_caption_inline(self): + pass @flaky(3, 1) - @timeout(10) - def testGetChatAdministrators(self): - admins = self._bot.getChatAdministrators(self._channel_id) - self.assertTrue(isinstance(admins, list)) - self.assertTrue(self.is_json(admins[0].to_json())) + @pytest.mark.timeout(10) + def test_edit_reply_markup(self, bot, message): + new_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text='test', callback_data='1')]]) + message = bot.edit_message_reply_markup(chat_id=message.chat_id, + message_id=message.message_id, + reply_markup=new_markup) + + assert message is not True + + @pytest.mark.xfail(raises=TelegramError) # TODO: remove when #744 is merged + def test_edit_message_reply_markup_without_required(self, bot): + new_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text='test', callback_data='1')]]) + with pytest.raises(ValueError, match='Both chat_id and message_id are required when'): + bot.edit_message_reply_markup(reply_markup=new_markup) + + @pytest.mark.skip(reason='need reference to an inline message') + def test_edit_reply_markup_inline(self): + pass + + # TODO: Actually send updates to the test bot so this can be tested properly + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_get_updates(self, bot): + bot.delete_webhook() # make sure there is no webhook set if webhook tests failed + updates = bot.get_updates(timeout=1) + + assert isinstance(updates, list) + if updates: + assert isinstance(updates[0], Update) + + @flaky(3, 1) + @pytest.mark.timeout(15) + @pytest.mark.xfail + def test_set_webhook_get_webhook_info_and_delete_webhook(self, bot): + url = 'https://python-telegram-bot.org/test/webhook' + max_connections = 7 + allowed_updates = ['message'] + bot.set_webhook(url, max_connections=max_connections, allowed_updates=allowed_updates) + time.sleep(2) + live_info = bot.get_webhook_info() + time.sleep(6) + bot.delete_webhook() + time.sleep(2) + info = bot.get_webhook_info() + assert info.url == '' + assert live_info.url == url + assert live_info.max_connections == max_connections + assert live_info.allowed_updates == allowed_updates + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_leave_chat(self, bot): + with pytest.raises(BadRequest, match='Chat not found'): + bot.leave_chat(-123456) + + with pytest.raises(NetworkError, match='Chat not found'): + bot.leave_chat(-123456) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_get_chat(self, bot, group_id): + chat = bot.get_chat(group_id) + + assert chat.type == 'group' + assert chat.title == '>>> telegram.Bot() - Developers' + assert chat.id == int(group_id) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_get_chat_administrators(self, bot, channel_id): + admins = bot.get_chat_administrators(channel_id) + assert isinstance(admins, list) for a in admins: - self.assertTrue(a.status in ("administrator", "creator")) - - bot = [a.user for a in admins if a.user.id == 133505823][0] - self._testUserEqualsBot(bot) + assert a.status in ('administrator', 'creator') @flaky(3, 1) - @timeout(10) - def testGetChatMembersCount(self): - count = self._bot.getChatMembersCount(self._channel_id) - self.assertTrue(isinstance(count, int)) - self.assertTrue(count > 3) + @pytest.mark.timeout(10) + def test_get_chat_members_count(self, bot, channel_id): + count = bot.get_chat_members_count(channel_id) + assert isinstance(count, int) + assert count > 3 @flaky(3, 1) - @timeout(10) - def testGetChatMember(self): - chat_member = self._bot.getChatMember(self._channel_id, 133505823) - bot = chat_member.user + @pytest.mark.timeout(10) + def test_get_chat_member(self, bot, channel_id): + chat_member = bot.get_chat_member(channel_id, 103246792) # Eldin - self.assertTrue(self.is_json(chat_member.to_json())) - self.assertEqual(chat_member.status, "administrator") - self._testUserEqualsBot(bot) + assert chat_member.status == 'administrator' + assert chat_member.user.username == 'EchteEldin' @flaky(3, 1) - @timeout(10) - def test_forward_channel_message(self): - text = 'test forward message' - msg = self._bot.sendMessage(self._channel_id, text) - self.assertEqual(text, msg.text) - fwdmsg = msg.forward(self._chat_id) - self.assertEqual(text, fwdmsg.text) - self.assertEqual(fwdmsg.forward_from_message_id, msg.message_id) - - # @flaky(20, 1, _stall_retry) - # @timeout(10) - # def test_set_webhook_get_webhook_info(self): - # url = 'https://python-telegram-bot.org/test/webhook' - # max_connections = 7 - # allowed_updates = ['message'] - # self._bot.set_webhook(url, max_connections=7, allowed_updates=['message']) - # info = self._bot.getWebhookInfo() - # self._bot.delete_webhook() - # self.assertEqual(url, info.url) - # self.assertEqual(max_connections, info.max_connections) - # self.assertListEqual(allowed_updates, info.allowed_updates) - # - # @flaky(20, 1, _stall_retry) - # @timeout(10) - # def test_delete_webhook(self): - # url = 'https://python-telegram-bot.org/test/webhook' - # self._bot.set_webhook(url) - # self._bot.delete_webhook() - # info = self._bot.getWebhookInfo() - # self.assertEqual(info.url, '') - - @flaky(3, 1) - @timeout(10) - def test_set_game_score1(self): + @pytest.mark.timeout(10) + def test_set_game_score_1(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods game_short_name = 'python_telegram_bot_test_game' - game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + game = bot.send_game(chat_id, game_short_name) - message = self._bot.set_game_score( - user_id=self._chat_id, + message = bot.set_game_score( + user_id=chat_id, score=int(BASE_TIME) - HIGHSCORE_DELTA, chat_id=game.chat_id, message_id=game.message_id) - self.assertTrue(self.is_json(game.to_json())) - self.assertEqual(message.game.description, game.game.description) - self.assertEqual(message.game.animation.file_id, game.game.animation.file_id) - self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size) - self.assertNotEqual(message.game.text, game.game.text) + assert message.game.description == game.game.description + assert message.game.animation.file_id == game.game.animation.file_id + assert message.game.photo[0].file_size == game.game.photo[0].file_size + assert message.game.text != game.game.text @flaky(3, 1) - @timeout(10) - def test_set_game_score2(self): + @pytest.mark.timeout(10) + def test_set_game_score_2(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods game_short_name = 'python_telegram_bot_test_game' - game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + game = bot.send_game(chat_id, game_short_name) score = int(BASE_TIME) - HIGHSCORE_DELTA + 1 - message = self._bot.set_game_score( - user_id=self._chat_id, + message = bot.set_game_score( + user_id=chat_id, score=score, chat_id=game.chat_id, message_id=game.message_id, disable_edit_message=True) - self.assertTrue(self.is_json(game.to_json())) - self.assertEqual(message.game.description, game.game.description) - self.assertEqual(message.game.animation.file_id, game.game.animation.file_id) - self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size) - self.assertEqual(message.game.text, game.game.text) + assert message.game.description == game.game.description + assert message.game.animation.file_id == game.game.animation.file_id + assert message.game.photo[0].file_size == game.game.photo[0].file_size + assert message.game.text == game.game.text @flaky(3, 1) - @timeout(10) - def test_set_game_score3(self): + @pytest.mark.timeout(10) + def test_set_game_score_3(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods game_short_name = 'python_telegram_bot_test_game' - game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + game = bot.send_game(chat_id, game_short_name) score = int(BASE_TIME) - HIGHSCORE_DELTA - 1 - with self.assertRaises(BadRequest) as cm: - self._bot.set_game_score( - user_id=self._chat_id, + with pytest.raises(BadRequest, match='Bot_score_not_modified'): + bot.set_game_score( + user_id=chat_id, score=score, chat_id=game.chat_id, message_id=game.message_id) - self.assertTrue('BOT_SCORE_NOT_MODIFIED' in str(cm.exception.message).upper()) - @flaky(3, 1) - @timeout(10) - def test_set_game_score4(self): + @pytest.mark.timeout(10) + def test_set_game_score_4(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods game_short_name = 'python_telegram_bot_test_game' - game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + game = bot.send_game(chat_id, game_short_name) score = int(BASE_TIME) - HIGHSCORE_DELTA - 2 - message = self._bot.set_game_score( - user_id=self._chat_id, + message = bot.set_game_score( + user_id=chat_id, score=score, chat_id=game.chat_id, message_id=game.message_id, force=True) - self.assertTrue(self.is_json(game.to_json())) - self.assertEqual(message.game.description, game.game.description) - self.assertEqual(message.game.animation.file_id, game.game.animation.file_id) - self.assertEqual(message.game.photo[0].file_size, game.game.photo[0].file_size) + assert message.game.description == game.game.description + assert message.game.animation.file_id == game.game.animation.file_id + assert message.game.photo[0].file_size == game.game.photo[0].file_size # For some reason the returned message does not contain the updated score. need to fetch # the game again... - game2 = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) - self.assertIn(str(score), game2.game.text) + game2 = bot.send_game(chat_id, game_short_name) + assert str(score) in game2.game.text @flaky(3, 1) - @timeout(10) - def test_set_game_score_too_low_score(self): + @pytest.mark.timeout(10) + def test_set_game_score_too_low_score(self, bot, chat_id): # We need a game to set the score for game_short_name = 'python_telegram_bot_test_game' - game = self._bot.sendGame(game_short_name=game_short_name, chat_id=self._chat_id) + game = bot.send_game(chat_id, game_short_name) - with self.assertRaises(BadRequest): - self._bot.set_game_score( - user_id=self._chat_id, score=100, chat_id=game.chat_id, message_id=game.message_id) - - def _testUserEqualsBot(self, user): - """Tests if user is our trusty @PythonTelegramBot.""" - self.assertEqual(user.id, 133505823) - self.assertEqual(user.first_name, 'PythonTelegramBot') - self.assertEqual(user.last_name, None) - self.assertEqual(user.username, 'PythonTelegramBot') - self.assertEqual(user.name, '@PythonTelegramBot') + with pytest.raises(BadRequest): + bot.set_game_score(user_id=chat_id, score=100, + chat_id=game.chat_id, message_id=game.message_id) @flaky(3, 1) - @timeout(10) - def test_info(self): - # tests the Bot.info decorator and associated funcs - self.assertEqual(self._bot.id, 133505823) - self.assertEqual(self._bot.first_name, 'PythonTelegramBot') - self.assertEqual(self._bot.last_name, None) - self.assertEqual(self._bot.username, 'PythonTelegramBot') - self.assertEqual(self._bot.name, '@PythonTelegramBot') + @pytest.mark.timeout(10) + def test_get_game_high_scores(self, bot, chat_id): + # We need a game to get the scores for + game_short_name = 'python_telegram_bot_test_game' + game = bot.send_game(chat_id, game_short_name) + high_scores = bot.get_game_high_scores(chat_id, game.chat_id, game.message_id) + # We assume that the other game score tests ran within 20 sec + assert pytest.approx(high_scores[0].score, abs=20) == int(BASE_TIME) - HIGHSCORE_DELTA + + # send_invoice is tested in test_invoice + + # TODO: Needs improvement. Need incoming shippping queries to test + def test_answer_shipping_query_ok(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'shipping_query_id': 1, 'ok': True, + 'shipping_options': [{'title': 'option1', + 'prices': [{'label': 'price', 'amount': 100}], + 'id': 1}]} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + shipping_options = ShippingOption(1, 'option1', [LabeledPrice('price', 100)]) + assert bot.answer_shipping_query(1, True, shipping_options=[shipping_options]) + + def test_answer_shipping_query_error_message(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'shipping_query_id': 1, 'error_message': 'Not enough fish', + 'ok': False} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + assert bot.answer_shipping_query(1, False, error_message='Not enough fish') + + def test_answer_shipping_query_errors(self, monkeypatch, bot): + shipping_options = ShippingOption(1, 'option1', [LabeledPrice('price', 100)]) + + with pytest.raises(TelegramError, match='should not be empty and there should not be'): + bot.answer_shipping_query(1, True, error_message='Not enough fish') + + with pytest.raises(TelegramError, match='should not be empty and there should not be'): + bot.answer_shipping_query(1, False) + + with pytest.raises(TelegramError, match='should not be empty and there should not be'): + bot.answer_shipping_query(1, False, shipping_options=shipping_options) + + with pytest.raises(TelegramError, match='should not be empty and there should not be'): + bot.answer_shipping_query(1, True) + + # TODO: Needs improvement. Need incoming pre checkout queries to test + def test_answer_pre_checkout_query_ok(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'pre_checkout_query_id': 1, 'ok': True} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + assert bot.answer_pre_checkout_query(1, True) + + def test_answer_pre_checkout_query_error_message(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + def test(_, url, data, *args, **kwargs): + return data == {'pre_checkout_query_id': 1, 'error_message': 'Not enough fish', + 'ok': False} + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + assert bot.answer_pre_checkout_query(1, False, error_message='Not enough fish') + + def test_answer_pre_checkout_query_errors(self, monkeypatch, bot): + with pytest.raises(TelegramError, match='should not be'): + bot.answer_pre_checkout_query(1, True, error_message='Not enough fish') + + with pytest.raises(TelegramError, match='should not be empty'): + bot.answer_pre_checkout_query(1, False) @flaky(3, 1) - @timeout(10) - def test_send_contact(self): - # test disabled due to telegram servers annoyances repeatedly returning: - # "Flood control exceeded. Retry in 2036 seconds" - return - phone = '+3-54-5445445' - name = 'name' - last = 'last' - message = self._bot.send_contact(self._chat_id, phone, name, last) - self.assertEqual(phone.replace('-', ''), message.contact.phone_number) - self.assertEqual(name, message.contact.first_name) - self.assertEqual(last, message.contact.last_name) + @pytest.mark.timeout(10) + def test_restrict_chat_member(self, bot, channel_id): + # TODO: Add bot to supergroup so this can be tested properly + with pytest.raises(BadRequest, match='Method is available only for supergroups'): + until = datetime.now() + timedelta(seconds=30) + assert bot.restrict_chat_member(channel_id, + 95205500, + until_date=datetime.now(), + can_send_messages=False, + can_send_media_messages=False, + can_send_other_messages=False, + can_add_web_page_previews=False) - def test_timeout_propagation(self): + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_promote_chat_member(self, bot, channel_id): + # TODO: Add bot to supergroup so this can be tested properly / give bot perms + with pytest.raises(BadRequest, match='Chat_admin_required'): + assert bot.promote_chat_member(channel_id, + 95205500, + can_change_info=True, + can_post_messages=True, + can_edit_messages=True, + can_delete_messages=True, + can_invite_users=True, + can_restrict_members=True, + can_pin_messages=True, + can_promote_members=True) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_export_chat_invite_link(self, bot, channel_id): + # Each link is unique apparently + invite_link = bot.export_chat_invite_link(channel_id) + assert isinstance(invite_link, string_types) + assert invite_link != '' + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_delete_chat_photo(self, bot, channel_id): + assert bot.delete_chat_photo(channel_id) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_set_chat_photo(self, bot, channel_id): + with open('tests/data/telegram_test_channel.jpg', 'rb') as f: + assert bot.set_chat_photo(channel_id, f) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_set_chat_title(self, bot, channel_id): + assert bot.set_chat_title(channel_id, '>>> telegram.Bot() - Tests') + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_set_chat_description(self, bot, channel_id): + assert bot.set_chat_description(channel_id, 'Time: ' + str(time.time())) + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_error_pin_unpin_message(self, bot, message): + # TODO: Add bot to supergroup so this can be tested properly + with pytest.raises(BadRequest, match='Method is available only for supergroups'): + bot.pin_chat_message(message.chat_id, message.message_id, disable_notification=True) + + with pytest.raises(BadRequest, match='Method is available only for supergroups'): + bot.unpin_chat_message(message.chat_id) + + # get_sticker_set, upload_sticker_file, create_new_sticker_set, add_sticker_to_set, + # set_sticker_position_in_set and delete_sticker_from_set are tested in the + # test_sticker module. + + def test_timeout_propagation(self, monkeypatch, bot, chat_id): class OkException(Exception): pass - class MockRequest(Request): - def post(self, url, data, timeout=None): - raise OkException(timeout) - - _request = self._bot._request - self._bot._request = MockRequest() - timeout = 500 - with self.assertRaises(OkException) as ok: - self._bot.send_photo(self._chat_id, open('tests/data/telegram.jpg'), timeout=timeout) - self.assertEqual(ok.exception.args[0], timeout) + def post(*args, **kwargs): + if kwargs.get('timeout') == 500: + raise OkException - self._bot._request = _request + monkeypatch.setattr('telegram.utils.request.Request.post', post) -if __name__ == '__main__': - unittest.main() + with pytest.raises(OkException): + bot.send_photo(chat_id, open('tests/data/telegram.jpg', 'rb'), timeout=timeout) diff --git a/tests/test_botan.py b/tests/test_botan.py deleted file mode 100644 index a45c28fd0..000000000 --- a/tests/test_botan.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -"""This module contains an object that represents Tests for Botan analytics integration""" - -import sys -import unittest -import os - -from flaky import flaky - -sys.path.append('.') - -from telegram.contrib.botan import Botan -from tests.base import BaseTest - - -class MessageMock(object): - chat_id = None - - def __init__(self, chat_id): - self.chat_id = chat_id - - def to_json(self): - return "{}" - - -@flaky(3, 1) -class BotanTest(BaseTest, unittest.TestCase): - """This object represents Tests for Botan analytics integration.""" - - token = os.environ.get('BOTAN_TOKEN') - - def test_track(self): - botan = Botan(self.token) - message = MessageMock(self._chat_id) - result = botan.track(message, 'named event') - self.assertTrue(result) - - def test_track_fail(self): - botan = Botan(self.token) - botan.url_template = 'https://api.botan.io/traccc?token={token}&uid={uid}&name={name}' - message = MessageMock(self._chat_id) - result = botan.track(message, 'named event') - self.assertFalse(result) - - def test_wrong_message(self): - botan = Botan(self.token) - message = MessageMock(self._chat_id) - message = delattr(message, 'chat_id') - result = botan.track(message, 'named event') - self.assertFalse(result) - - def test_wrong_endpoint(self): - botan = Botan(self.token) - botan.url_template = 'https://api.botaaaaan.io/traccc?token={token}&uid={uid}&name={name}' - message = MessageMock(self._chat_id) - result = botan.track(message, 'named event') - self.assertFalse(result) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py new file mode 100644 index 000000000..a8293a856 --- /dev/null +++ b/tests/test_callbackquery.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import CallbackQuery, User, Message, Chat, Audio + + +@pytest.fixture(scope='class', params=['message', 'inline']) +def callback_query(bot, request): + cbq = CallbackQuery(TestCallbackQuery.id, + TestCallbackQuery.from_user, + TestCallbackQuery.chat_instance, + data=TestCallbackQuery.data, + game_short_name=TestCallbackQuery.game_short_name, + bot=bot) + if request.param == 'message': + cbq.message = TestCallbackQuery.message + else: + cbq.inline_message_id = TestCallbackQuery.inline_message_id + return cbq + + +class TestCallbackQuery(object): + id = 'id' + from_user = User(1, 'test_user') + chat_instance = 'chat_instance' + message = Message(3, User(5, 'bot'), None, Chat(4, 'private')) + data = 'data' + inline_message_id = 'inline_message_id' + game_short_name = 'the_game' + + def test_de_json(self, bot): + json_dict = {'id': self.id, + 'from': self.from_user.to_dict(), + 'chat_instance': self.chat_instance, + 'message': self.message.to_dict(), + 'data': self.data, + 'inline_message_id': self.inline_message_id, + 'game_short_name': self.game_short_name} + callback_query = CallbackQuery.de_json(json_dict, bot) + + assert callback_query.id == self.id + assert callback_query.from_user == self.from_user + assert callback_query.chat_instance == self.chat_instance + assert callback_query.message == self.message + assert callback_query.data == self.data + assert callback_query.inline_message_id == self.inline_message_id + assert callback_query.game_short_name == self.game_short_name + + def test_to_dict(self, callback_query): + callback_query_dict = callback_query.to_dict() + + assert isinstance(callback_query_dict, dict) + assert callback_query_dict['id'] == callback_query.id + assert callback_query_dict['from'] == callback_query.from_user.to_dict() + assert callback_query_dict['chat_instance'] == callback_query.chat_instance + if callback_query.message: + assert callback_query_dict['message'] == callback_query.message.to_dict() + else: + assert callback_query_dict['inline_message_id'] == callback_query.inline_message_id + assert callback_query_dict['data'] == callback_query.data + assert callback_query_dict['game_short_name'] == callback_query.game_short_name + + def test_answer(self, monkeypatch, callback_query): + def test(*args, **kwargs): + return args[1] == callback_query.id + + monkeypatch.setattr('telegram.Bot.answerCallbackQuery', test) + # TODO: PEP8 + assert callback_query.answer() + + def test_edit_message_text(self, monkeypatch, callback_query): + def test(*args, **kwargs): + try: + id = kwargs['inline_message_id'] == callback_query.inline_message_id + text = kwargs['text'] == 'test' + return id and text + except KeyError: + chat_id = kwargs['chat_id'] == callback_query.message.chat_id + message_id = kwargs['message_id'] == callback_query.message.message_id + text = kwargs['text'] == 'test' + return chat_id and message_id and text + + monkeypatch.setattr('telegram.Bot.edit_message_text', test) + assert callback_query.edit_message_text(text='test') + + def test_edit_message_caption(self, monkeypatch, callback_query): + def test(*args, **kwargs): + try: + id = kwargs['inline_message_id'] == callback_query.inline_message_id + caption = kwargs['caption'] == 'new caption' + return id and caption + except KeyError: + id = kwargs['chat_id'] == callback_query.message.chat_id + message = kwargs['message_id'] == callback_query.message.message_id + caption = kwargs['caption'] == 'new caption' + return id and message and caption + + monkeypatch.setattr('telegram.Bot.edit_message_caption', test) + assert callback_query.edit_message_caption(caption='new caption') + + def test_edit_message_reply_markup(self, monkeypatch, callback_query): + def test(*args, **kwargs): + try: + id = kwargs['inline_message_id'] == callback_query.inline_message_id + reply_markup = kwargs['reply_markup'] == [['1', '2']] + return id and reply_markup + except KeyError: + id = kwargs['chat_id'] == callback_query.message.chat_id + message = kwargs['message_id'] == callback_query.message.message_id + reply_markup = kwargs['reply_markup'] == [['1', '2']] + return id and message and reply_markup + + monkeypatch.setattr('telegram.Bot.edit_message_reply_markup', test) + assert callback_query.edit_message_reply_markup(reply_markup=[['1', '2']]) + + def test_equality(self): + a = CallbackQuery(self.id, self.from_user, 'chat') + b = CallbackQuery(self.id, self.from_user, 'chat') + c = CallbackQuery(self.id, None, '') + d = CallbackQuery('', None, 'chat') + e = Audio(self.id, 1) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_callbackqueryhandler.py b/tests/test_callbackqueryhandler.py new file mode 100644 index 000000000..83e56b47f --- /dev/null +++ b/tests/test_callbackqueryhandler.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import pytest + +from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import CallbackQueryHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')} +] + +ids = ('message', 'edited_message', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=2, **request.param) + + +@pytest.fixture(scope='function') +def callback_query(bot): + return Update(0, callback_query=CallbackQuery(2, None, None, data='test data')) + + +class TestCallbackQueryHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def callback_group(self, bot, update, groups=None, groupdict=None): + if groups is not None: + self.test_flag = groups == ('t', ' data') + if groupdict is not None: + self.test_flag = groupdict == {'begin': 't', 'end': ' data'} + + def test_basic(self, dp, callback_query): + handler = CallbackQueryHandler(self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(callback_query) + + dp.process_update(callback_query) + assert self.test_flag + + def test_with_pattern(self, callback_query): + handler = CallbackQueryHandler(self.callback_basic, pattern='.*est.*') + + assert handler.check_update(callback_query) + + callback_query.callback_query.data = 'nothing here' + assert not handler.check_update(callback_query) + + def test_with_passing_group_dict(self, dp, callback_query): + handler = CallbackQueryHandler(self.callback_group, + pattern='(?P.*)est(?P.*)', + pass_groups=True) + dp.add_handler(handler) + + dp.process_update(callback_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = CallbackQueryHandler(self.callback_group, + pattern='(?P.*)est(?P.*)', + pass_groupdict=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(callback_query) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, callback_query): + handler = CallbackQueryHandler(self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(callback_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = CallbackQueryHandler(self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(callback_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = CallbackQueryHandler(self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(callback_query) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, callback_query): + handler = CallbackQueryHandler(self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(callback_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = CallbackQueryHandler(self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(callback_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = CallbackQueryHandler(self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(callback_query) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = CallbackQueryHandler(self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_chat.py b/tests/test_chat.py index 54e77ff75..510d56ddf 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -5,106 +5,134 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Chat""" -import unittest -import sys +import pytest -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Chat, ChatAction +from telegram import User -class ChatTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Chat.""" +@pytest.fixture(scope='class') +def chat(bot): + return Chat(TestChat.id, TestChat.title, TestChat.type, + all_members_are_administrators=TestChat.all_members_are_administrators, + bot=bot) - def setUp(self): - self._id = -28767330 - self.title = 'ToledosPalaceBot - Group' - self.type = 'group' - self.all_members_are_administrators = False - self.json_dict = { - 'id': self._id, - 'title': self.title, - 'type': self.type, - 'all_members_are_administrators': self.all_members_are_administrators +class TestChat(object): + id = -28767330 + title = 'ToledosPalaceBot - Group' + type = 'group' + all_members_are_administrators = False + + def test_de_json(self, bot): + json_dict = { + 'id': TestChat.id, + 'title': TestChat.title, + 'type': TestChat.type, + 'all_members_are_administrators': TestChat.all_members_are_administrators } + chat = Chat.de_json(json_dict, bot) - def test_group_chat_de_json_empty_json(self): - group_chat = telegram.Chat.de_json({}, self._bot) + assert chat.id == self.id + assert chat.title == self.title + assert chat.type == self.type + assert chat.all_members_are_administrators == self.all_members_are_administrators - self.assertEqual(group_chat, None) + def test_to_dict(self, chat): + chat_dict = chat.to_dict() - def test_group_chat_de_json(self): - group_chat = telegram.Chat.de_json(self.json_dict, self._bot) + assert isinstance(chat_dict, dict) + assert chat_dict['id'] == chat.id + assert chat_dict['title'] == chat.title + assert chat_dict['type'] == chat.type + assert chat_dict['all_members_are_administrators'] == chat.all_members_are_administrators - self.assertEqual(group_chat.id, self._id) - self.assertEqual(group_chat.title, self.title) - self.assertEqual(group_chat.type, self.type) - self.assertEqual(group_chat.all_members_are_administrators, - self.all_members_are_administrators) + def test_send_action(self, monkeypatch, chat): + def test(*args, **kwargs): + id = args[1] == chat.id + action = kwargs['action'] == ChatAction.TYPING + return id and action - def test_group_chat_to_json(self): - group_chat = telegram.Chat.de_json(self.json_dict, self._bot) + monkeypatch.setattr('telegram.Bot.send_chat_action', test) + assert chat.send_action(action=ChatAction.TYPING) - self.assertTrue(self.is_json(group_chat.to_json())) + def test_leave(self, monkeypatch, chat): + def test(*args, **kwargs): + return args[1] == chat.id - def test_group_chat_to_dict(self): - group_chat = telegram.Chat.de_json(self.json_dict, self._bot) + monkeypatch.setattr('telegram.Bot.leave_chat', test) + assert chat.leave() - self.assertTrue(self.is_dict(group_chat.to_dict())) - self.assertEqual(group_chat['id'], self._id) - self.assertEqual(group_chat['title'], self.title) - self.assertEqual(group_chat['type'], self.type) - self.assertEqual(group_chat['all_members_are_administrators'], - self.all_members_are_administrators) + def test_get_administrators(self, monkeypatch, chat): + def test(*args, **kwargs): + return args[1] == chat.id - @flaky(3, 1) - def test_send_action(self): - """Test for Chat.send_action""" - self.json_dict['id'] = self._chat_id - group_chat = telegram.Chat.de_json(self.json_dict, self._bot) - group_chat.bot = self._bot + monkeypatch.setattr('telegram.Bot.get_chat_administrators', test) + assert chat.get_administrators() - result = group_chat.send_action(telegram.ChatAction.TYPING) + def test_get_members_count(self, monkeypatch, chat): + def test(*args, **kwargs): + return args[1] == chat.id - self.assertTrue(result) + monkeypatch.setattr('telegram.Bot.get_chat_members_count', test) + assert chat.get_members_count() + + def test_get_member(self, monkeypatch, chat): + def test(*args, **kwargs): + chat_id = args[1] == chat.id + user_id = args[2] == 42 + return chat_id and user_id + + monkeypatch.setattr('telegram.Bot.get_chat_member', test) + assert chat.get_member(42) + + def test_kick_member(self, monkeypatch, chat): + def test(*args, **kwargs): + chat_id = args[1] == chat.id + user_id = args[2] == 42 + until = kwargs['until_date'] == 43 + return chat_id and user_id and until + + monkeypatch.setattr('telegram.Bot.kick_chat_member', test) + assert chat.kick_member(42, until_date=43) + + def test_unban_member(self, monkeypatch, chat): + def test(*args, **kwargs): + chat_id = args[1] == chat.id + user_id = args[2] == 42 + return chat_id and user_id + + monkeypatch.setattr('telegram.Bot.unban_chat_member', test) + assert chat.unban_member(42) def test_equality(self): - a = telegram.Chat(self._id, self.title, self.type) - b = telegram.Chat(self._id, self.title, self.type) - c = telegram.Chat(self._id, "", "") - d = telegram.Chat(0, self.title, self.type) - e = telegram.User(self._id, "") + a = Chat(self.id, self.title, self.type) + b = Chat(self.id, self.title, self.type) + c = Chat(self.id, '', '') + d = Chat(0, self.title, self.type) + e = User(self.id, '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index e28226195..f6a3a1a45 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -5,67 +5,101 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram ChatMember""" +import datetime -import unittest -import sys +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import User, ChatMember +from telegram.utils.helpers import to_timestamp -class ChatMemberTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ChatMember.""" +@pytest.fixture(scope='class') +def user(): + return User(1, 'First name') - def setUp(self): - self.user = {'id': 1, 'first_name': 'User'} - self.status = telegram.ChatMember.CREATOR - self.json_dict = {'user': self.user, 'status': self.status} +@pytest.fixture(scope='class') +def chat_member(user): + return ChatMember(user, TestChatMember.status) - def test_chatmember_de_json(self): - chatmember = telegram.ChatMember.de_json(self.json_dict, self._bot) - self.assertEqual(chatmember.user.to_dict(), self.user) - self.assertEqual(chatmember.status, self.status) +class TestChatMember(object): + status = ChatMember.CREATOR - def test_chatmember_to_json(self): - chatmember = telegram.ChatMember.de_json(self.json_dict, self._bot) + def test_de_json_required_args(self, bot, user): + json_dict = {'user': user.to_dict(), 'status': self.status} - self.assertTrue(self.is_json(chatmember.to_json())) + chat_member = ChatMember.de_json(json_dict, bot) - def test_chatmember_to_dict(self): - chatmember = telegram.ChatMember.de_json(self.json_dict, self._bot) + assert chat_member.user == user + assert chat_member.status == self.status - self.assertTrue(self.is_dict(chatmember.to_dict())) - self.assertEqual(chatmember['user'].to_dict(), self.user) - self.assertEqual(chatmember['status'], self.status) + def test_de_json_all_args(self, bot, user): + time = datetime.datetime.now() + json_dict = {'user': user.to_dict(), + 'status': self.status, + 'until_date': to_timestamp(time), + 'can_be_edited': False, + 'can_change_info': True, + 'can_post_messages': False, + 'can_edit_messages': True, + 'can_delete_messages': True, + 'can_invite_users': False, + 'can_restrict_members': True, + 'can_pin_messages': False, + 'can_promote_members': True, + 'can_send_messages': False, + 'can_send_media_messages': True, + 'can_send_other_messages': False, + 'can_add_web_page_previews': True} + + chat_member = ChatMember.de_json(json_dict, bot) + + assert chat_member.user == user + assert chat_member.status == self.status + assert chat_member.can_be_edited is False + assert chat_member.can_change_info is True + assert chat_member.can_post_messages is False + assert chat_member.can_edit_messages is True + assert chat_member.can_delete_messages is True + assert chat_member.can_invite_users is False + assert chat_member.can_restrict_members is True + assert chat_member.can_pin_messages is False + assert chat_member.can_promote_members is True + assert chat_member.can_send_messages is False + assert chat_member.can_send_media_messages is True + assert chat_member.can_send_other_messages is False + assert chat_member.can_add_web_page_previews is True + + def test_to_dict(self, chat_member): + chat_member_dict = chat_member.to_dict() + assert isinstance(chat_member_dict, dict) + assert chat_member_dict['user'] == chat_member.user.to_dict() + assert chat_member['status'] == chat_member.status def test_equality(self): - a = telegram.ChatMember(telegram.User(1, ""), telegram.ChatMember.ADMINISTRATOR) - b = telegram.ChatMember(telegram.User(1, ""), telegram.ChatMember.ADMINISTRATOR) - d = telegram.ChatMember(telegram.User(2, ""), telegram.ChatMember.ADMINISTRATOR) - d2 = telegram.ChatMember(telegram.User(1, ""), telegram.ChatMember.CREATOR) + a = ChatMember(User(1, ''), ChatMember.ADMINISTRATOR) + b = ChatMember(User(1, ''), ChatMember.ADMINISTRATOR) + d = ChatMember(User(2, ''), ChatMember.ADMINISTRATOR) + d2 = ChatMember(User(1, ''), ChatMember.CREATOR) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, d2) - self.assertNotEqual(hash(a), hash(d2)) + assert a != d2 + assert hash(a) != hash(d2) diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index a0396018c..56c1c9379 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -5,85 +5,86 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -ChosenInlineResult""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import User, ChosenInlineResult, Location, Voice -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): - result = telegram.ChosenInlineResult.de_json(self.json_dict, self._bot) - - self.assertEqual(result.result_id, self.result_id) - self.assertDictEqual(result.from_user.to_dict(), self.from_user.to_dict()) - self.assertEqual(result.query, self.query) - - def test_choseninlineresult_to_json(self): - result = telegram.ChosenInlineResult.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(result.to_json())) - - def test_choseninlineresult_to_dict(self): - result = telegram.ChosenInlineResult.de_json(self.json_dict, self._bot).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) - - def test_equality(self): - a = telegram.ChosenInlineResult(self.result_id, None, "Query", "") - b = telegram.ChosenInlineResult(self.result_id, None, "Query", "") - c = telegram.ChosenInlineResult(self.result_id, None, "", "") - d = telegram.ChosenInlineResult("", None, "Query", "") - e = telegram.Voice(self.result_id, 0) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) +@pytest.fixture(scope='class') +def user(): + return User(1, 'First name') -if __name__ == '__main__': - unittest.main() +@pytest.fixture(scope='class') +def chosen_inline_result(user): + return ChosenInlineResult(TestChosenInlineResult.result_id, user, TestChosenInlineResult.query) + + +class TestChosenInlineResult(object): + result_id = 'result id' + query = 'query text' + + def test_de_json_required(self, bot, user): + json_dict = {'result_id': self.result_id, + 'from': user.to_dict(), + 'query': self.query} + result = ChosenInlineResult.de_json(json_dict, bot) + + assert result.result_id == self.result_id + assert result.from_user == user + assert result.query == self.query + + def test_de_json_all(self, bot, user): + loc = Location(-42.003, 34.004) + json_dict = {'result_id': self.result_id, + 'from': user.to_dict(), + 'query': self.query, + 'location': loc.to_dict(), + 'inline_message_id': 'a random id'} + result = ChosenInlineResult.de_json(json_dict, bot) + + assert result.result_id == self.result_id + assert result.from_user == user + assert result.query == self.query + assert result.location == loc + assert result.inline_message_id == 'a random id' + + def test_to_dict(self, chosen_inline_result): + chosen_inline_result_dict = chosen_inline_result.to_dict() + + assert isinstance(chosen_inline_result_dict, dict) + assert chosen_inline_result_dict['result_id'] == chosen_inline_result.result_id + assert chosen_inline_result_dict['from'] == chosen_inline_result.from_user.to_dict() + assert chosen_inline_result_dict['query'] == chosen_inline_result.query + + def test_equality(self, user): + a = ChosenInlineResult(self.result_id, user, 'Query', '') + b = ChosenInlineResult(self.result_id, user, 'Query', '') + c = ChosenInlineResult(self.result_id, user, '', '') + d = ChosenInlineResult('', user, 'Query', '') + e = Voice(self.result_id, 0) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_choseninlineresulthandler.py b/tests/test_choseninlineresulthandler.py new file mode 100644 index 000000000..95e6b16df --- /dev/null +++ b/tests/test_choseninlineresulthandler.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, + InlineQuery, ShippingQuery, PreCheckoutQuery) +from telegram.ext import ChosenInlineResultHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='class') +def chosen_inline_result(): + return Update(1, chosen_inline_result=ChosenInlineResult('result_id', + User(1, 'test_user'), + 'query')) + + +class TestChosenInlineResultHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def test_basic(self, dp, chosen_inline_result): + handler = ChosenInlineResultHandler(self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(chosen_inline_result) + dp.process_update(chosen_inline_result) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, chosen_inline_result): + handler = ChosenInlineResultHandler(self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(chosen_inline_result) + assert self.test_flag + + dp.remove_handler(handler) + handler = ChosenInlineResultHandler(self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(chosen_inline_result) + assert self.test_flag + + dp.remove_handler(handler) + handler = ChosenInlineResultHandler(self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(chosen_inline_result) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, chosen_inline_result): + handler = ChosenInlineResultHandler(self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(chosen_inline_result) + assert self.test_flag + + dp.remove_handler(handler) + handler = ChosenInlineResultHandler(self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(chosen_inline_result) + assert self.test_flag + + dp.remove_handler(handler) + handler = ChosenInlineResultHandler(self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(chosen_inline_result) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = ChosenInlineResultHandler(self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_commandhandler.py b/tests/test_commandhandler.py new file mode 100644 index 000000000..afc92ae97 --- /dev/null +++ b/tests/test_commandhandler.py @@ -0,0 +1,220 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import CommandHandler, Filters + +message = Message(1, User(1, ''), None, Chat(1, ''), text='test') + +params = [ + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('callback_query', 'channel_post', 'edited_channel_post', 'inline_query', + 'chosen_inline_result', 'shipping_query', 'pre_checkout_query', + 'callback_query_without_message',) + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='function') +def message(bot): + return Message(1, None, None, None, bot=bot) + + +class TestCommandHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def ch_callback_args(self, bot, update, args): + if update.message.text == '/test': + self.test_flag = len(args) == 0 + elif update.message.text == '/test@{}'.format(bot.username): + self.test_flag = len(args) == 0 + else: + self.test_flag = args == ['one', 'two'] + + def test_basic(self, dp, message): + handler = CommandHandler('test', self.callback_basic) + dp.add_handler(handler) + + message.text = '/test' + assert handler.check_update(Update(0, message)) + dp.process_update(Update(0, message)) + assert self.test_flag + + message.text = '/nottest' + assert not handler.check_update(Update(0, message)) + + message.text = 'test' + assert not handler.check_update(Update(0, message)) + + message.text = 'not /test at start' + assert not handler.check_update(Update(0, message)) + + def test_command_list(self, message): + handler = CommandHandler(['test', 'start'], self.callback_basic) + + message.text = '/test' + assert handler.check_update(Update(0, message)) + + message.text = '/start' + assert handler.check_update(Update(0, message)) + + message.text = '/stop' + assert not handler.check_update(Update(0, message)) + + def test_edited(self, message): + handler = CommandHandler('test', self.callback_basic, allow_edited=False) + + message.text = '/test' + assert handler.check_update(Update(0, message)) + assert not handler.check_update(Update(0, edited_message=message)) + handler.allow_edited = True + assert handler.check_update(Update(0, message)) + assert handler.check_update(Update(0, edited_message=message)) + + def test_directed_commands(self, message): + handler = CommandHandler('test', self.callback_basic) + + message.text = '/test@{}'.format(message.bot.username) + assert handler.check_update(Update(0, message)) + + message.text = '/test@otherbot' + assert not handler.check_update(Update(0, message)) + + def test_with_filter(self, message): + handler = CommandHandler('test', self.callback_basic, Filters.group) + + message.chat = Chat(-23, 'group') + message.text = '/test' + assert handler.check_update(Update(0, message)) + + message.chat = Chat(23, 'private') + assert not handler.check_update(Update(0, message)) + + def test_pass_args(self, dp, message): + handler = CommandHandler('test', self.ch_callback_args, pass_args=True) + dp.add_handler(handler) + + message.text = '/test' + dp.process_update(Update(0, message=message)) + assert self.test_flag + + self.test_flag = False + message.text = '/test@{}'.format(message.bot.username) + dp.process_update(Update(0, message=message)) + assert self.test_flag + + self.test_flag = False + message.text = '/test one two' + dp.process_update(Update(0, message=message)) + assert self.test_flag + + self.test_flag = False + message.text = '/test@{} one two'.format(message.bot.username) + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, message): + handler = CommandHandler('test', self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + message.text = '/test' + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = CommandHandler('test', self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = CommandHandler('test', self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, message): + handler = CommandHandler('test', self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + message.text = '/test' + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = CommandHandler('test', self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = CommandHandler('test', self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = CommandHandler('test', self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_constants.py b/tests/test_constants.py index 1ed8f58f9..c4f873b8b 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -1,6 +1,8 @@ -# python-telegram-bot - a Python interface to the Telegram Bot API +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 -# by the python-telegram-bot contributors +# 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 @@ -14,60 +16,33 @@ # # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -"""Test the Telegram constants.""" - -import sys -import unittest - +import pytest from flaky import flaky -sys.path.append('.') - -import telegram +from telegram import constants from telegram.error import BadRequest -from tests.base import BaseTest, timeout -class ConstantsTest(BaseTest, unittest.TestCase): +class TestConstants(object): + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_max_message_length(self, bot, chat_id): + bot.send_message(chat_id=chat_id, text='a' * constants.MAX_MESSAGE_LENGTH) + + with pytest.raises(BadRequest, message='MAX_MESSAGE_LENGTH is no longer valid', + match='too long'): + bot.send_message(chat_id=chat_id, text='a' * (constants.MAX_MESSAGE_LENGTH + 1)) @flaky(3, 1) - @timeout(10) - def testMaxMessageLength(self): - self._bot.sendMessage( - chat_id=self._chat_id, text='a' * telegram.constants.MAX_MESSAGE_LENGTH) - - try: - self._bot.sendMessage( - chat_id=self._chat_id, text='a' * (telegram.constants.MAX_MESSAGE_LENGTH + 1)) - except BadRequest as e: - err = str(e) - - self.assertTrue("too long" in err) # BadRequest: 'Message is too long' - - @flaky(3, 1) - @timeout(10) - def testMaxCaptionLength(self): - good_caption = 'a' * telegram.constants.MAX_CAPTION_LENGTH - good_msg = self._bot.sendPhoto( - photo=open('tests/data/telegram.png', 'rb'), - caption=good_caption, - chat_id=self._chat_id) - self.assertEqual(good_msg.caption, good_caption) + @pytest.mark.timeout(10) + def test_max_caption_length(self, bot, chat_id): + good_caption = 'a' * constants.MAX_CAPTION_LENGTH + with open('tests/data/telegram.png', 'rb') as f: + good_msg = bot.send_photo(photo=f, caption=good_caption, chat_id=chat_id) + assert good_msg.caption == good_caption bad_caption = good_caption + 'Z' - try: - bad_msg = self._bot.sendPhoto( - photo=open('tests/data/telegram.png', 'rb'), - caption='a' * (telegram.constants.MAX_CAPTION_LENGTH + 1), - chat_id=self._chat_id) - except BadRequest as e: - # This used to be the way long caption was handled before Oct? Nov? 2016 - err = str(e) - self.assertTrue("TOO_LONG" in err) # BadRequest: 'MEDIA_CAPTION_TOO_LONG' - else: - self.assertNotEqual(bad_msg.caption, bad_caption) - self.assertEqual(len(bad_msg.caption), telegram.constants.MAX_CAPTION_LENGTH) - - -if __name__ == '__main__': - unittest.main() + with open('tests/data/telegram.png', 'rb') as f: + bad_message = bot.send_photo(photo=f, caption=bad_caption, chat_id=chat_id) + assert bad_message.caption != bad_caption + assert len(bad_message.caption) == constants.MAX_CAPTION_LENGTH diff --git a/tests/test_contact.py b/tests/test_contact.py index 3245a4bc0..4da25c181 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -5,108 +5,92 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Contact""" -import unittest -import sys +import pytest -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Contact, Voice -class ContactTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Contact.""" +@pytest.fixture(scope='class') +def contact(): + return Contact(TestContact.phone_number, TestContact.first_name, TestContact.last_name, + TestContact.user_id) - def setUp(self): - self.phone_number = '+11234567890' - self.first_name = 'Leandro Toledo' - self.last_name = '' - self.user_id = 0 - self.json_dict = { - 'phone_number': self.phone_number, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'user_id': self.user_id - } +class TestContact(object): + phone_number = '+11234567890' + first_name = 'Leandro' + last_name = 'Toledo' + user_id = 23 - def test_contact_de_json(self): - contact = telegram.Contact.de_json(self.json_dict, self._bot) + def test_de_json_required(self, bot): + json_dict = {'phone_number': self.phone_number, 'first_name': self.first_name} + contact = Contact.de_json(json_dict, bot) - self.assertEqual(contact.phone_number, self.phone_number) - self.assertEqual(contact.first_name, self.first_name) - self.assertEqual(contact.last_name, self.last_name) - self.assertEqual(contact.user_id, self.user_id) + assert contact.phone_number == self.phone_number + assert contact.first_name == self.first_name - '''Commented out because it caused too many "RetryAfter: Flood control exceeded" errors. - def test_send_contact_with_contact(self): - con = telegram.Contact.de_json(self.json_dict, self._bot) - message = self._bot.send_contact(contact=con, chat_id=self._chat_id) - contact = message.contact + def test_de_json_all(self, bot): + json_dict = {'phone_number': self.phone_number, 'first_name': self.first_name, + 'last_name': self.last_name, 'user_id': self.user_id} + contact = Contact.de_json(json_dict, bot) - self.assertEqual(contact, con) - ''' + assert contact.phone_number == self.phone_number + assert contact.first_name == self.first_name + assert contact.last_name == self.last_name + assert contact.user_id == self.user_id - def test_contact_to_json(self): - contact = telegram.Contact.de_json(self.json_dict, self._bot) + def test_send_with_contact(self, monkeypatch, bot, chat_id, contact): + def test(_, url, data, **kwargs): + phone = data['phone_number'] == contact.phone_number + first = data['first_name'] == contact.first_name + last = data['last_name'] == contact.last_name + return phone and first and last - self.assertTrue(self.is_json(contact.to_json())) + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_contact(contact=contact, chat_id=chat_id) + assert message - def test_contact_to_dict(self): - contact = telegram.Contact.de_json(self.json_dict, self._bot) + def test_send_contact_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match='Either contact or phone_number and first_name'): + bot.send_contact(chat_id=chat_id) - self.assertTrue(self.is_dict(contact.to_dict())) - self.assertEqual(contact['phone_number'], self.phone_number) - self.assertEqual(contact['first_name'], self.first_name) - self.assertEqual(contact['last_name'], self.last_name) - self.assertEqual(contact['user_id'], self.user_id) + def test_to_dict(self, contact): + contact_dict = contact.to_dict() + + assert isinstance(contact_dict, dict) + assert contact_dict['phone_number'] == contact.phone_number + assert contact_dict['first_name'] == contact.first_name + assert contact_dict['last_name'] == contact.last_name + assert contact_dict['user_id'] == contact.user_id def test_equality(self): - a = telegram.Contact(self.phone_number, self.first_name) - b = telegram.Contact(self.phone_number, self.first_name) - c = telegram.Contact(self.phone_number, "") - d = telegram.Contact("", self.first_name) - e = telegram.Voice("", 0) + a = Contact(self.phone_number, self.first_name) + b = Contact(self.phone_number, self.first_name) + c = Contact(self.phone_number, '') + d = Contact('', self.first_name) + e = Voice('', 0) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -''' Commented out, because it would cause "Too Many Requests (429)" errors. - @flaky(3, 1) - def test_reply_contact(self): - """Test for Message.reply_contact""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_contact(self.phone_number, self.first_name) - - self.assertEqual(message.contact.phone_number, self.phone_number) - self.assertEqual(message.contact.first_name, self.first_name) -''' - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index 231306da7..1f1327e65 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -1,77 +1,60 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for ConversationHandler -""" -import logging -import sys -import unittest from time import sleep -try: - # python2 - from urllib2 import urlopen, Request, HTTPError -except ImportError: - # python3 - from urllib.request import Request, urlopen - from urllib.error import HTTPError +import pytest -sys.path.append('.') - -from telegram import Update, Message, TelegramError, User, Chat, Bot, CallbackQuery -from telegram.ext import (Updater, ConversationHandler, CommandHandler, CallbackQueryHandler, - InlineQueryHandler) -from tests.base import BaseTest -from tests.test_updater import MockBot - -# Enable logging -root = logging.getLogger() -root.setLevel(logging.DEBUG) - -ch = logging.StreamHandler(sys.stdout) -ch.setLevel(logging.WARN) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s ' '- %(message)s') -ch.setFormatter(formatter) -root.addHandler(ch) +from telegram import Update, Message, User, Chat, CallbackQuery +from telegram.ext import (ConversationHandler, CommandHandler, CallbackQueryHandler) -class ConversationHandlerTest(BaseTest, unittest.TestCase): - """ - This object represents the tests for the conversation handler. - """ +@pytest.fixture(scope='class') +def user1(): + return User(first_name='Misses Test', id=123) + +@pytest.fixture(scope='class') +def user2(): + return User(first_name='Mister Test', id=124) + + +class TestConversationHandler(object): # State definitions # At first we're thirsty. Then we brew coffee, we drink it # and then we can start coding! END, THIRSTY, BREWING, DRINKING, CODING = range(-1, 4) - _updater = None + + current_state, entry_points, states, fallbacks = None, None, None, None + group = Chat(0, Chat.GROUP) + second_group = Chat(1, Chat.GROUP) # Test related - def setUp(self): + @pytest.fixture(autouse=True) + def reset(self): self.current_state = dict() self.entry_points = [CommandHandler('start', self.start)] self.states = { self.THIRSTY: [CommandHandler('brew', self.brew), CommandHandler('wait', self.start)], self.BREWING: [CommandHandler('pourCoffee', self.drink)], self.DRINKING: - [CommandHandler('startCoding', self.code), CommandHandler('drinkMore', self.drink)], + [CommandHandler('startCoding', self.code), + CommandHandler('drinkMore', self.drink)], self.CODING: [ CommandHandler('keepCoding', self.code), CommandHandler('gettingThirsty', self.start), @@ -80,41 +63,11 @@ class ConversationHandlerTest(BaseTest, unittest.TestCase): } self.fallbacks = [CommandHandler('eat', self.start)] - self.group = Chat(0, Chat.GROUP) - self.second_group = Chat(1, Chat.GROUP) - - def _chat(self, user): - return Chat(user.id, Chat.GROUP) - - def _setup_updater(self, *args, **kwargs): - self.bot = MockBot(*args, **kwargs) - self.updater = Updater(workers=2, bot=self.bot) - - def tearDown(self): - if self.updater is not None: - self.updater.stop() - - @property - def updater(self): - return self._updater - - @updater.setter - def updater(self, val): - if self._updater: - self._updater.stop() - self._updater = val - - def reset(self): - self.current_state = dict() - # State handlers def _set_state(self, update, state): self.current_state[update.message.from_user.id] = state return state - def _get_state(self, user_id): - return self.current_state[user_id] - # Actions def start(self, bot, update): return self._set_state(update, self.THIRSTY) @@ -132,116 +85,118 @@ class ConversationHandlerTest(BaseTest, unittest.TestCase): return self._set_state(update, self.CODING) # Tests - def test_addConversationHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) - second_user = User(first_name="Mister Test", id=124) + def test_per_all_false(self): + with pytest.raises(ValueError, match="can't all be 'False'"): + handler = ConversationHandler(self.entry_points, self.states, self.fallbacks, + per_chat=False, per_user=False, per_message=False) - handler = ConversationHandler( - entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + def test_conversation_handler(self, dp, bot, user1, user2): + handler = ConversationHandler(entry_points=self.entry_points, states=self.states, + fallbacks=self.fallbacks) + dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, user, None, self.group, text="/start", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.current_state[user.id] == self.THIRSTY) + message = Message(0, user1, None, self.group, text='/start', bot=bot) + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.THIRSTY # The user is thirsty and wants to brew coffee. - message = Message(0, user, None, self.group, text="/brew", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.current_state[user.id] == self.BREWING) + message.text = '/brew' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.BREWING # Lets see if an invalid command makes sure, no state is changed. - message = Message(0, user, None, self.group, text="/nothing", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.current_state[user.id] == self.BREWING) + message.text = '/nothing' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.BREWING # Lets see if the state machine still works by pouring coffee. - message = Message(0, user, None, self.group, text="/pourCoffee", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.current_state[user.id] == self.DRINKING) + message.text = '/pourCoffee' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.DRINKING # Let's now verify that for another user, who did not start yet, # the state has not been changed. - message = Message(0, second_user, None, self.group, text="/brew", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertRaises(KeyError, self._get_state, user_id=second_user.id) + message.from_user = user2 + dp.process_update(Update(update_id=0, message=message)) + with pytest.raises(KeyError): + self.current_state[user2.id] - def test_addConversationHandlerPerChat(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) - second_user = User(first_name="Mister Test", id=124) + def test_conversation_handler_fallback(self, dp, bot, user1, user2): + handler = ConversationHandler(entry_points=self.entry_points, states=self.states, + fallbacks=self.fallbacks) + dp.add_handler(handler) + # first check if fallback will not trigger start when not started + message = Message(0, user1, None, self.group, text='/eat', bot=bot) + dp.process_update(Update(update_id=0, message=message)) + with pytest.raises(KeyError): + self.current_state[user1.id] + + # User starts the state machine. + message.text = '/start' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.THIRSTY + + # The user is thirsty and wants to brew coffee. + message.text = '/brew' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.BREWING + + # Now a fallback command is issued + message.text = '/eat' + dp.process_update(Update(update_id=0, message=message)) + assert self.current_state[user1.id] == self.THIRSTY + + def test_conversation_handler_per_chat(self, dp, bot, user1, user2): handler = ConversationHandler( entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks, per_user=False) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, user, None, self.group, text="/start", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) + message = Message(0, user1, None, self.group, text='/start', bot=bot) + dp.process_update(Update(update_id=0, message=message)) # The user is thirsty and wants to brew coffee. - message = Message(0, user, None, self.group, text="/brew", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) + message.text = '/brew' + dp.process_update(Update(update_id=0, message=message)) # Let's now verify that for another user, who did not start yet, # the state will be changed because they are in the same group. - message = Message(0, second_user, None, self.group, text="/pourCoffee", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEquals(handler.conversations[(self.group.id,)], self.DRINKING) + message.from_user = user2 + message.text = '/pourCoffee' + dp.process_update(Update(update_id=0, message=message)) - def test_addConversationHandlerPerUser(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) + assert handler.conversations[(self.group.id,)] == self.DRINKING + def test_conversation_handler_per_user(self, dp, bot, user1): handler = ConversationHandler( entry_points=self.entry_points, states=self.states, fallbacks=self.fallbacks, per_chat=False) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, user, None, self.group, text="/start", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) + message = Message(0, user1, None, self.group, text='/start', bot=bot) + dp.process_update(Update(update_id=0, message=message)) # The user is thirsty and wants to brew coffee. - message = Message(0, user, None, self.group, text="/brew", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) + message.text = '/brew' + dp.process_update(Update(update_id=0, message=message)) # Let's now verify that for the same user in a different group, the state will still be # updated - message = Message(0, user, None, self.second_group, text="/pourCoffee", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) + message.chat = self.second_group + message.text = '/pourCoffee' + dp.process_update(Update(update_id=0, message=message)) - self.assertEquals(handler.conversations[(user.id,)], self.DRINKING) - - def test_addConversationHandlerPerMessage(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) - second_user = User(first_name="Mister Test", id=124) + assert handler.conversations[(user1.id,)] == self.DRINKING + def test_conversation_handler_per_message(self, dp, bot, user1, user2): def entry(bot, update): return 1 @@ -257,85 +212,68 @@ class ConversationHandlerTest(BaseTest, unittest.TestCase): 2: [CallbackQueryHandler(two)]}, fallbacks=[], per_message=True) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + dp.add_handler(handler) # User one, starts the state machine. - message = Message(0, user, None, self.group, text="msg w/ inlinekeyboard", bot=self.bot) + message = Message(0, user1, None, self.group, text='msg w/ inlinekeyboard', bot=bot) - cbq = CallbackQuery(0, user, None, message=message, data='data', bot=self.bot) - queue.put(Update(update_id=0, callback_query=cbq)) - sleep(.1) - self.assertEquals(handler.conversations[(self.group.id, user.id, message.message_id)], 1) + cbq = CallbackQuery(0, user1, None, message=message, data='data', bot=bot) + dp.process_update(Update(update_id=0, callback_query=cbq)) - cbq = CallbackQuery(0, user, None, message=message, data='data', bot=self.bot) - queue.put(Update(update_id=0, callback_query=cbq)) - sleep(.1) - self.assertEquals(handler.conversations[(self.group.id, user.id, message.message_id)], 2) + assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 1 + + dp.process_update(Update(update_id=0, callback_query=cbq)) + + assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 2 # Let's now verify that for a different user in the same group, the state will not be # updated - cbq = CallbackQuery(0, second_user, None, message=message, data='data', bot=self.bot) - queue.put(Update(update_id=0, callback_query=cbq)) - sleep(.1) - self.assertEquals(handler.conversations[(self.group.id, user.id, message.message_id)], 2) + cbq.from_user = user2 + dp.process_update(Update(update_id=0, callback_query=cbq)) - def test_endOnFirstMessage(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) + assert handler.conversations[(self.group.id, user1.id, message.message_id)] == 2 + def test_end_on_first_message(self, dp, bot, user1): handler = ConversationHandler( entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[]) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + dp.add_handler(handler) # User starts the state machine and immediately ends it. - message = Message(0, user, None, self.group, text="/start", bot=self.bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEquals(len(handler.conversations), 0) + message = Message(0, user1, None, self.group, text='/start', bot=bot) + dp.process_update(Update(update_id=0, message=message)) + assert len(handler.conversations) == 0 - def test_endOnFirstMessageAsync(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - user = User(first_name="Misses Test", id=123) - - start_end_async = (lambda bot, update: d.run_async(self.start_end, bot, update)) + def test_end_on_first_message_async(self, dp, bot, user1): + start_end_async = (lambda bot, update: dp.run_async(self.start_end, bot, update)) handler = ConversationHandler( entry_points=[CommandHandler('start', start_end_async)], states={}, fallbacks=[]) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) + dp.add_handler(handler) # User starts the state machine with an async function that immediately ends the # conversation. Async results are resolved when the users state is queried next time. - message = Message(0, user, None, self.group, text="/start", bot=self.bot) - queue.put(Update(update_id=0, message=message)) + message = Message(0, user1, None, self.group, text='/start', bot=bot) + dp.update_queue.put(Update(update_id=0, message=message)) sleep(.1) # Assert that the Promise has been accepted as the new state - self.assertEquals(len(handler.conversations), 1) + assert len(handler.conversations) == 1 - message = Message(0, user, None, self.group, text="resolve promise pls", bot=self.bot) - queue.put(Update(update_id=0, message=message)) + message.text = 'resolve promise pls' + dp.update_queue.put(Update(update_id=0, message=message)) sleep(.1) # Assert that the Promise has been resolved and the conversation ended. - self.assertEquals(len(handler.conversations), 0) + assert len(handler.conversations) == 0 - def test_perChatMessageWithoutChat(self): + def test_per_chat_message_without_chat(self, bot, user1): handler = ConversationHandler( entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[]) - user = User(first_name="Misses Test", id=123) - cbq = CallbackQuery(0, user, None, None) + cbq = CallbackQuery(0, user1, None, None, bot=bot) update = Update(0, callback_query=cbq) - handler.check_update(update) + assert not handler.check_update(update) - def test_channelMessageWithoutChat(self): - handler = ConversationHandler(entry_points=[CommandHandler('start', self.start_end)], states={}, fallbacks=[]) - message = Message(0, None, None, Chat(0, Chat.CHANNEL, "Misses Test")) + def test_channel_message_without_chat(self, bot): + handler = ConversationHandler(entry_points=[CommandHandler('start', self.start_end)], + states={}, fallbacks=[]) + message = Message(0, None, None, Chat(0, Chat.CHANNEL, 'Misses Test'), bot=bot) update = Update(0, message=message) - handler.check_update(update) - - -if __name__ == '__main__': - unittest.main() + assert not handler.check_update(update) diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py new file mode 100644 index 000000000..175f46731 --- /dev/null +++ b/tests/test_dispatcher.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +from queue import Queue +from threading import current_thread +from time import sleep + +import pytest + +from telegram import TelegramError, Message, User, Chat, Update +from telegram.ext import MessageHandler, Filters, CommandHandler +from telegram.ext.dispatcher import run_async, Dispatcher, DispatcherHandlerContinue, \ + DispatcherHandlerStop +from tests.conftest import create_dp + + +@pytest.fixture(scope='function') +def dp2(bot): + for dp in create_dp(bot): + yield dp + + +class TestDispatcher(object): + message_update = Update(1, message=Message(1, User(1, ''), None, Chat(1, ''), text='Text')) + received = None + count = 0 + + @pytest.fixture(autouse=True) + def reset(self): + self.received = None + self.count = 0 + + def error_handler(self, bot, update, error): + self.received = error.message + + def callback_increase_count(self, bot, update): + self.count += 1 + + def callback_set_count(self, count): + def callback(bot, update): + self.count = count + + return callback + + def callback_raise_error(self, bot, update): + raise TelegramError(update.message.text) + + def callback_if_not_update_queue(self, bot, update, update_queue=None): + if update_queue is not None: + self.received = update.message + + def test_error_handler(self, dp): + dp.add_error_handler(self.error_handler) + error = TelegramError('Unauthorized.') + dp.update_queue.put(error) + sleep(.1) + assert self.received == 'Unauthorized.' + + # Remove handler + dp.remove_error_handler(self.error_handler) + self.reset() + + dp.update_queue.put(error) + sleep(.1) + assert self.received is None + + def test_run_async_multiple(self, bot, dp, dp2): + def get_dispatcher_name(q): + q.put(current_thread().name) + + q1 = Queue() + q2 = Queue() + + dp.run_async(get_dispatcher_name, q1) + dp2.run_async(get_dispatcher_name, q2) + + sleep(.1) + + name1 = q1.get() + name2 = q2.get() + + assert name1 != name2 + + def test_multiple_run_async_decorator(self, dp, dp2): + # Make sure we got two dispatchers and that they are not the same + assert isinstance(dp, Dispatcher) + assert isinstance(dp2, Dispatcher) + assert dp is not dp2 + + @run_async + def must_raise_runtime_error(): + pass + + with pytest.raises(RuntimeError): + must_raise_runtime_error() + + def test_run_async_with_args(self, dp): + dp.add_handler(MessageHandler(Filters.all, + run_async(self.callback_if_not_update_queue), + pass_update_queue=True)) + + dp.update_queue.put(self.message_update) + sleep(.1) + assert self.received == self.message_update.message + + def test_error_in_handler(self, dp): + dp.add_handler(MessageHandler(Filters.all, self.callback_raise_error)) + dp.add_error_handler(self.error_handler) + + dp.update_queue.put(self.message_update) + sleep(.1) + assert self.received == self.message_update.message.text + + def test_add_remove_handler(self, dp): + handler = MessageHandler(Filters.all, self.callback_increase_count) + dp.add_handler(handler) + dp.update_queue.put(self.message_update) + sleep(.1) + assert self.count == 1 + dp.remove_handler(handler) + dp.update_queue.put(self.message_update) + assert self.count == 1 + + def test_add_remove_handler_non_default_group(self, dp): + handler = MessageHandler(Filters.all, self.callback_increase_count) + dp.add_handler(handler, group=2) + with pytest.raises(KeyError): + dp.remove_handler(handler) + dp.remove_handler(handler, group=2) + + def test_error_start_twice(self, dp): + assert dp.running + dp.start() + + def test_handler_order_in_group(self, dp): + dp.add_handler(MessageHandler(Filters.photo, self.callback_set_count(1))) + dp.add_handler(MessageHandler(Filters.all, self.callback_set_count(2))) + dp.add_handler(MessageHandler(Filters.text, self.callback_set_count(3))) + dp.update_queue.put(self.message_update) + sleep(.1) + assert self.count == 2 + + def test_groups(self, dp): + dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count)) + dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=2) + dp.add_handler(MessageHandler(Filters.all, self.callback_increase_count), group=-1) + + dp.update_queue.put(self.message_update) + sleep(.1) + assert self.count == 3 + + def test_add_handler_errors(self, dp): + handler = 'not a handler' + with pytest.raises(TypeError, match='handler is not an instance of'): + dp.add_handler(handler) + + handler = MessageHandler(Filters.photo, self.callback_set_count(1)) + with pytest.raises(TypeError, match='group is not int'): + dp.add_handler(handler, 'one') + + def test_handler_flow_continue(self, bot, dp): + passed = [] + + def start1(b, u): + passed.append('start1') + raise DispatcherHandlerContinue + + def start2(b, u): + passed.append('start2') + + def start3(b, u): + passed.append('start3') + + def error(b, u, e): + passed.append('error') + passed.append(e) + + update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) + + # If Continue raised next handler should be proceed. + passed = [] + dp.add_handler(CommandHandler('start', start1)) + dp.add_handler(CommandHandler('start', start2)) + dp.process_update(update) + assert passed == ['start1', 'start2'] + + def test_dispatcher_handler_flow_stop(self, dp, bot): + passed = [] + + def start1(b, u): + passed.append('start1') + raise DispatcherHandlerStop + + def start2(b, u): + passed.append('start2') + + def start3(b, u): + passed.append('start3') + + def error(b, u, e): + passed.append('error') + passed.append(e) + + update = Update(1, message=Message(1, None, None, None, text='/start', bot=bot)) + + # If Stop raised handlers in other groups should not be called. + passed = [] + dp.add_handler(CommandHandler('start', start1), 1) + dp.add_handler(CommandHandler('start', start3), 1) + dp.add_handler(CommandHandler('start', start2), 2) + dp.process_update(update) + assert passed == ['start1'] diff --git a/tests/test_document.py b/tests/test_document.py index edcbc4401..ef92203a9 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -5,218 +5,175 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Document""" - import os -import unittest +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import Document, PhotoSize, TelegramError, Voice -class DocumentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Document.""" +@pytest.fixture(scope='function') +def document_file(): + f = open('tests/data/telegram.png', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(DocumentTest, cls).setUpClass() - cls.caption = u'DocumentTest - Caption' - cls.document_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.gif' +@pytest.fixture(scope='class') +def document(bot, chat_id): + with open('tests/data/telegram.png', 'rb') as f: + return bot.send_document(chat_id, document=f).document - document_file = open('tests/data/telegram.png', 'rb') - document = cls._bot.send_document(cls._chat_id, document=document_file, timeout=10).document - cls.document = document - # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.document, telegram.Document) - assert isinstance(cls.document.file_id, str) - assert cls.document.file_id is not '' +class TestDocument(object): + caption = 'DocumentTest - Caption' + document_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.gif' + file_size = 12948 + mime_type = 'image/png' + file_name = 'telegram.png' + thumb_file_size = 2364 + thumb_width = 90 + thumb_heigth = 90 - def setUp(self): - self.document_file = open('tests/data/telegram.png', 'rb') - self.json_dict = { - 'file_id': self.document.file_id, - 'thumb': self.document.thumb.to_dict(), - 'file_name': self.document.file_name, - 'mime_type': self.document.mime_type, - 'file_size': self.document.file_size - } + def test_creation(self, document): + assert isinstance(document, Document) + assert isinstance(document.file_id, str) + assert document.file_id is not '' - def test_expected_values(self): - self.assertEqual(self.document.file_size, 12948) - self.assertEqual(self.document.mime_type, 'image/png') - self.assertEqual(self.document.file_name, 'telegram.png') - self.assertEqual(self.document.thumb.file_size, 2364) - self.assertEqual(self.document.thumb.width, 90) - self.assertEqual(self.document.thumb.height, 90) + def test_expected_values(self, document): + assert document.file_size == self.file_size + assert document.mime_type == self.mime_type + assert document.file_name == self.file_name + assert document.thumb.file_size == self.thumb_file_size + assert document.thumb.width == self.thumb_width + assert document.thumb.height == self.thumb_heigth @flaky(3, 1) - @timeout(10) - def test_send_document_all_args(self): - message = self._bot.sendDocument(self._chat_id, document=self.document_file, caption=self.caption, - disable_notification=False) + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, document_file, document): + message = bot.send_document(chat_id, document=document_file, caption=self.caption, + disable_notification=False, filename='telegram_custom.png') - document = message.document - - self.assertIsInstance(document, telegram.Document) - self.assertIsInstance(document.file_id, str) - self.assertNotEqual(document.file_id, '') - self.assertTrue(isinstance(document.thumb, telegram.PhotoSize)) - self.assertEqual(document.file_name, self.document.file_name) - self.assertEqual(document.mime_type, self.document.mime_type) - self.assertEqual(document.file_size, self.document.file_size) - self.assertEqual(document.thumb, self.document.thumb) - self.assertEqual(message.caption, self.caption) + assert isinstance(message.document, Document) + assert isinstance(message.document.file_id, str) + assert message.document.file_id != '' + assert isinstance(message.document.thumb, PhotoSize) + assert message.document.file_name == 'telegram_custom.png' + assert message.document.mime_type == document.mime_type + assert message.document.file_size == document.file_size + assert message.document.thumb == document.thumb + assert message.caption == self.caption @flaky(3, 1) - @timeout(10) - def test_get_and_download_document(self): - new_file = self._bot.getFile(self.document.file_id) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, document): + new_file = bot.get_file(document.file_id) - self.assertEqual(new_file.file_size, self.document.file_size) - self.assertEqual(new_file.file_id, self.document.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == document.file_size + assert new_file.file_id == document.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram.png') - self.assertTrue(os.path.isfile('telegram.png')) + assert os.path.isfile('telegram.png') @flaky(3, 1) - @timeout(10) - def test_send_document_png_file_with_custom_file_name(self): - message = self._bot.sendDocument( - self._chat_id, self.document_file, filename='telegram_custom.png') + @pytest.mark.timeout(10) + def test_send_url_gif_file(self, bot, chat_id): + message = bot.send_document(chat_id, self.document_file_url) document = message.document - self.assertEqual(document.file_name, 'telegram_custom.png') + assert isinstance(document, Document) + assert isinstance(document.file_id, str) + assert document.file_id != '' + assert isinstance(document.thumb, PhotoSize) + assert document.file_name == 'telegram.gif' + assert document.mime_type == 'image/gif' + assert document.file_size == 3878 @flaky(3, 1) - @timeout(10) - def test_send_document_url_gif_file(self): - message = self._bot.sendDocument(self._chat_id, self.document_file_url) + @pytest.mark.timeout(10) + def test_send_resend(self, bot, chat_id, document): + message = bot.send_document(chat_id=chat_id, document=document.file_id) - document = message.document + assert message.document == document - self.assertIsInstance(document, telegram.Document) - self.assertIsInstance(document.file_id, str) - self.assertNotEqual(document.file_id, '') - self.assertTrue(isinstance(document.thumb, telegram.PhotoSize)) - self.assertEqual(document.file_name, 'telegram.gif') - self.assertEqual(document.mime_type, 'image/gif') - self.assertEqual(document.file_size, 3878) + def test_send_with_document(self, monkeypatch, bot, chat_id, document): + def test(_, url, data, **kwargs): + return data['document'] == document.file_id + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + + message = bot.send_document(document=document, chat_id=chat_id) + + assert message + + def test_de_json(self, bot, document): + json_dict = {'file_id': 'not a file id', + 'thumb': document.thumb.to_dict(), + 'file_name': self.file_name, + 'mime_type': self.mime_type, + 'file_size': self.file_size + } + test_document = Document.de_json(json_dict, bot) + + assert test_document.file_id == 'not a file id' + assert test_document.thumb == document.thumb + assert test_document.file_name == self.file_name + assert test_document.mime_type == self.mime_type + assert test_document.file_size == self.file_size + + def test_to_dict(self, document): + document_dict = document.to_dict() + + assert isinstance(document_dict, dict) + assert document_dict['file_id'] == document.file_id + assert document_dict['file_name'] == document.file_name + assert document_dict['mime_type'] == document.mime_type + assert document_dict['file_size'] == document.file_size @flaky(3, 1) - @timeout(10) - def test_send_document_resend(self): - message = self._bot.sendDocument(chat_id=self._chat_id, document=self.document.file_id) - - document = message.document - - self.assertEqual(document, self.document) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with open(os.devnull, 'rb') as f: + with pytest.raises(TelegramError): + bot.send_document(chat_id=chat_id, document=f) @flaky(3, 1) - @timeout(10) - def test_send_document_with_document(self): - message = self._bot.send_document(document=self.document, chat_id=self._chat_id) - document = message.document + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_document(chat_id=chat_id, document='') - self.assertEqual(document, self.document) + def test_error_send_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_document(chat_id=chat_id) + def test_equality(self, document): + a = Document(document.file_id) + b = Document(document.file_id) + d = Document('') + e = Voice(document.file_id, 0) - def test_document_de_json(self): - document = telegram.Document.de_json(self.json_dict, self._bot) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(document, self.document) + assert a != d + assert hash(a) != hash(d) - def test_document_to_json(self): - self.assertTrue(self.is_json(self.document.to_json())) - - def test_document_to_dict(self): - document = self.document.to_dict() - - self.assertTrue(self.is_dict(document)) - self.assertEqual(document['file_id'], self.document.file_id) - self.assertEqual(document['file_name'], self.document.file_name) - self.assertEqual(document['mime_type'], self.document.mime_type) - self.assertEqual(document['file_size'], self.document.file_size) - - @flaky(3, 1) - @timeout(10) - def test_error_send_document_empty_file(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['document'] = open(os.devnull, 'rb') - - with self.assertRaises(telegram.TelegramError): - self._bot.sendDocument(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_send_document_empty_file_id(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['document'] = '' - - with self.assertRaises(telegram.TelegramError): - self._bot.sendDocument(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_document_without_required_args(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - - with self.assertRaises(TypeError): self._bot.sendDocument(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_reply_document(self): - """Test for Message.reply_document""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_document(self.document_file) - - document = message.document - - self.assertIsInstance(document, telegram.Document) - self.assertIsInstance(document.file_id, str) - self.assertNotEqual(document.file_id, '') - self.assertTrue(isinstance(document.thumb, telegram.PhotoSize)) - - def test_equality(self): - a = telegram.Document(self.document.file_id) - b = telegram.Document(self.document.file_id) - d = telegram.Document("") - e = telegram.Voice(self.document.file_id, 0) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_file.py b/tests/test_file.py index 405070857..01d108a21 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -5,100 +5,88 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram File""" -import sys -import unittest -import os +import pytest +from flaky import flaky -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import File, TelegramError, Voice -class FileTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram File.""" +@pytest.fixture(scope='class') +def file(bot): + return File(TestFile.file_id, + file_path=TestFile.file_path, + file_size=TestFile.file_size, + bot=bot) - def setUp(self): - self.json_dict = { - 'file_id': "NOTVALIDDONTMATTER", - 'file_path': - 'https://api.telegram.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3', - 'file_size': 28232 + +class TestFile(object): + file_id = 'NOTVALIDDOESNOTMATTER' + file_path = ( + u'https://api.org/file/bot133505823:AAHZFMHno3mzVLErU5b5jJvaeG--qUyLyG0/document/file_3') + file_size = 28232 + + def test_de_json(self, bot): + json_dict = { + 'file_id': self.file_id, + 'file_path': self.file_path, + 'file_size': self.file_size } + new_file = File.de_json(json_dict, bot) - def test_file_de_json(self): - new_file = telegram.File.de_json(self.json_dict, self._bot) + assert new_file.file_id == self.file_id + assert new_file.file_path == self.file_path + assert new_file.file_size == self.file_size - self.assertEqual(new_file.file_id, self.json_dict['file_id']) - self.assertEqual(new_file.file_path, self.json_dict['file_path']) - self.assertEqual(new_file.file_size, self.json_dict['file_size']) + def test_to_dict(self, file): + file_dict = file.to_dict() - def test_file_to_json(self): - new_file = telegram.File.de_json(self.json_dict, self._bot) + assert isinstance(file_dict, dict) + assert file_dict['file_id'] == file.file_id + assert file_dict['file_path'] == file.file_path + assert file_dict['file_size'] == file.file_size - self.assertTrue(self.is_json(new_file.to_json())) + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_error_get_empty_file_id(self, bot): + with pytest.raises(TelegramError): + bot.get_file(file_id='') - def test_file_to_dict(self): - new_file = telegram.File.de_json(self.json_dict, self._bot).to_dict() + def test_download(self, monkeypatch, file): + def test(*args, **kwargs): + raise TelegramError('test worked') - self.assertTrue(self.is_dict(new_file)) - self.assertEqual(new_file['file_id'], self.json_dict['file_id']) - self.assertEqual(new_file['file_path'], self.json_dict['file_path']) - self.assertEqual(new_file['file_size'], self.json_dict['file_size']) + monkeypatch.setattr('telegram.utils.request.Request.download', test) + with pytest.raises(TelegramError, match='test worked'): + file.download() - def test_error_get_empty_file_id(self): - json_dict = self.json_dict - json_dict['file_id'] = '' - del (json_dict['file_path']) - del (json_dict['file_size']) + def test_equality(self, bot): + a = File(self.file_id, bot) + b = File(self.file_id, bot) + c = File(self.file_id, None) + d = File('', bot) + e = Voice(self.file_id, 0) - with self.assertRaises(telegram.TelegramError): - self._bot.getFile(**json_dict) + assert a == b + assert hash(a) == hash(b) + assert a is not b - def test_error_file_without_required_args(self): - json_dict = self.json_dict + assert a == c + assert hash(a) == hash(c) - del (json_dict['file_id']) - del (json_dict['file_path']) - del (json_dict['file_size']) + assert a != d + assert hash(a) != hash(d) - with self.assertRaises(TypeError): - self._bot.getFile(**json_dict) - - - def test_equality(self): - a = telegram.File("DOESNTMATTER", self._bot) - b = telegram.File("DOESNTMATTER", self._bot) - c = telegram.File("DOESNTMATTER", None) - d = telegram.File("DOESNTMATTER2", self._bot) - e = telegram.Voice("DOESNTMATTER", 0) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_filters.py b/tests/test_filters.py index 913d1c5a8..d2b521eea 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -5,375 +5,350 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Filters for use with MessageHandler. -""" +import datetime -import sys -import unittest -from datetime import datetime -import functools - -sys.path.append('.') +import pytest from telegram import Message, User, Chat, MessageEntity from telegram.ext import Filters, BaseFilter -from tests.base import BaseTest -class FiltersTest(BaseTest, unittest.TestCase): - """This object represents Tests for MessageHandler.Filters""" +@pytest.fixture(scope='function') +def message(): + return Message(0, User(0, 'Testuser'), datetime.datetime.now(), Chat(0, 'private')) - def setUp(self): - self.message = Message(0, User(0, "Testuser"), datetime.now(), Chat(0, 'private')) - self.e = functools.partial(MessageEntity, offset=0, length=0) - def test_filters_text(self): - self.message.text = 'test' - self.assertTrue(Filters.text(self.message)) - self.message.text = '/test' - self.assertFalse(Filters.text(self.message)) +@pytest.fixture(scope='function', + params=MessageEntity.ALL_TYPES) +def message_entity(request): + return MessageEntity(request.param, 0, 0, url='', user='') - def test_filters_command(self): - self.message.text = 'test' - self.assertFalse(Filters.command(self.message)) - self.message.text = '/test' - self.assertTrue(Filters.command(self.message)) - def test_filters_reply(self): - another_message = Message(1, User(1, "TestOther"), datetime.now(), Chat(0, 'private')) - self.message.text = 'test' - self.assertFalse(Filters.reply(self.message)) - self.message.reply_to_message = another_message - self.assertTrue(Filters.reply(self.message)) +class TestFilters(object): + def test_filters_all(self, message): + assert Filters.all(message) - def test_filters_audio(self): - self.message.audio = 'test' - self.assertTrue(Filters.audio(self.message)) - self.message.audio = None - self.assertFalse(Filters.audio(self.message)) + def test_filters_text(self, message): + message.text = 'test' + assert Filters.text(message) + message.text = '/test' + assert not Filters.text(message) - def test_filters_document(self): - self.message.document = 'test' - self.assertTrue(Filters.document(self.message)) - self.message.document = None - self.assertFalse(Filters.document(self.message)) + def test_filters_command(self, message): + message.text = 'test' + assert not Filters.command(message) + message.text = '/test' + assert Filters.command(message) - def test_filters_photo(self): - self.message.photo = 'test' - self.assertTrue(Filters.photo(self.message)) - self.message.photo = None - self.assertFalse(Filters.photo(self.message)) + def test_filters_reply(self, message): + another_message = Message(1, User(1, 'TestOther'), datetime.datetime.now(), + Chat(0, 'private')) + message.text = 'test' + assert not Filters.reply(message) + message.reply_to_message = another_message + assert Filters.reply(message) - def test_filters_sticker(self): - self.message.sticker = 'test' - self.assertTrue(Filters.sticker(self.message)) - self.message.sticker = None - self.assertFalse(Filters.sticker(self.message)) + def test_filters_audio(self, message): + assert not Filters.audio(message) + message.audio = 'test' + assert Filters.audio(message) - def test_filters_video(self): - self.message.video = 'test' - self.assertTrue(Filters.video(self.message)) - self.message.video = None - self.assertFalse(Filters.video(self.message)) + def test_filters_document(self, message): + assert not Filters.document(message) + message.document = 'test' + assert Filters.document(message) - def test_filters_voice(self): - self.message.voice = 'test' - self.assertTrue(Filters.voice(self.message)) - self.message.voice = None - self.assertFalse(Filters.voice(self.message)) + def test_filters_photo(self, message): + assert not Filters.photo(message) + message.photo = 'test' + assert Filters.photo(message) - def test_filters_contact(self): - self.message.contact = 'test' - self.assertTrue(Filters.contact(self.message)) - self.message.contact = None - self.assertFalse(Filters.contact(self.message)) + def test_filters_sticker(self, message): + assert not Filters.sticker(message) + message.sticker = 'test' + assert Filters.sticker(message) - def test_filters_location(self): - self.message.location = 'test' - self.assertTrue(Filters.location(self.message)) - self.message.location = None - self.assertFalse(Filters.location(self.message)) + def test_filters_video(self, message): + assert not Filters.video(message) + message.video = 'test' + assert Filters.video(message) - def test_filters_venue(self): - self.message.venue = 'test' - self.assertTrue(Filters.venue(self.message)) - self.message.venue = None - self.assertFalse(Filters.venue(self.message)) + def test_filters_voice(self, message): + assert not Filters.voice(message) + message.voice = 'test' + assert Filters.voice(message) - def test_filters_game(self): - self.message.game = 'test' - self.assertTrue(Filters.game(self.message)) - self.message.game = None - self.assertFalse(Filters.game(self.message)) + def test_filters_contact(self, message): + assert not Filters.contact(message) + message.contact = 'test' + assert Filters.contact(message) - def test_filters_successful_payment(self): - self.message.successful_payment = 'test' - self.assertTrue(Filters.successful_payment(self.message)) - self.message.successful_payment = None - self.assertFalse(Filters.successful_payment(self.message)) + def test_filters_location(self, message): + assert not Filters.location(message) + message.location = 'test' + assert Filters.location(message) - def test_filters_invoice(self): - self.message.invoice = 'test' - self.assertTrue(Filters.invoice(self.message)) - self.message.invoice = None - self.assertFalse(Filters.invoice(self.message)) + def test_filters_venue(self, message): + assert not Filters.venue(message) + message.venue = 'test' + assert Filters.venue(message) - def test_filters_status_update(self): - self.assertFalse(Filters.status_update(self.message)) + def test_filters_status_update(self, message): + assert not Filters.status_update(message) - self.message.new_chat_members = ['test'] - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.new_chat_members(self.message)) - self.message.new_chat_members = None + message.new_chat_members = ['test'] + assert Filters.status_update(message) + assert Filters.status_update.new_chat_members(message) + message.new_chat_members = None - self.message.left_chat_member = 'test' - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.left_chat_member(self.message)) - self.message.left_chat_member = None + message.left_chat_member = 'test' + assert Filters.status_update(message) + assert Filters.status_update.left_chat_member(message) + message.left_chat_member = None - self.message.new_chat_title = 'test' - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.new_chat_title(self.message)) - self.message.new_chat_title = '' + message.new_chat_title = 'test' + assert Filters.status_update(message) + assert Filters.status_update.new_chat_title(message) + message.new_chat_title = '' - self.message.new_chat_photo = 'test' - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.new_chat_photo(self.message)) - self.message.new_chat_photo = None + message.new_chat_photo = 'test' + assert Filters.status_update(message) + assert Filters.status_update.new_chat_photo(message) + message.new_chat_photo = None - self.message.delete_chat_photo = True - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.delete_chat_photo(self.message)) - self.message.delete_chat_photo = False + message.delete_chat_photo = True + assert Filters.status_update(message) + assert Filters.status_update.delete_chat_photo(message) + message.delete_chat_photo = False - self.message.group_chat_created = True - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.chat_created(self.message)) - self.message.group_chat_created = False + message.group_chat_created = True + assert Filters.status_update(message) + assert Filters.status_update.chat_created(message) + message.group_chat_created = False - self.message.supergroup_chat_created = True - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.chat_created(self.message)) - self.message.supergroup_chat_created = False + message.supergroup_chat_created = True + assert Filters.status_update(message) + assert Filters.status_update.chat_created(message) + message.supergroup_chat_created = False - self.message.migrate_to_chat_id = 100 - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.migrate(self.message)) - self.message.migrate_to_chat_id = 0 + message.channel_chat_created = True + assert Filters.status_update(message) + assert Filters.status_update.chat_created(message) + message.channel_chat_created = False - self.message.migrate_from_chat_id = 100 - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.migrate(self.message)) - self.message.migrate_from_chat_id = 0 + message.migrate_to_chat_id = 100 + assert Filters.status_update(message) + assert Filters.status_update.migrate(message) + message.migrate_to_chat_id = 0 - self.message.channel_chat_created = True - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.chat_created(self.message)) - self.message.channel_chat_created = False + message.migrate_from_chat_id = 100 + assert Filters.status_update(message) + assert Filters.status_update.migrate(message) + message.migrate_from_chat_id = 0 - self.message.pinned_message = 'test' - self.assertTrue(Filters.status_update(self.message)) - self.assertTrue(Filters.status_update.pinned_message(self.message)) - self.message.pinned_message = None + message.pinned_message = 'test' + assert Filters.status_update(message) + assert Filters.status_update.pinned_message(message) + message.pinned_message = None - def test_entities_filter(self): - self.message.entities = [self.e(MessageEntity.MENTION)] - self.assertTrue(Filters.entity(MessageEntity.MENTION)(self.message)) + def test_filters_forwarded(self, message): + assert not Filters.forwarded(message) + message.forward_date = 'test' + assert Filters.forwarded(message) - self.message.entities = [] - self.assertFalse(Filters.entity(MessageEntity.MENTION)(self.message)) + def test_filters_game(self, message): + assert not Filters.game(message) + message.game = 'test' + assert Filters.game(message) - self.message.entities = [self.e(MessageEntity.BOLD)] - self.assertFalse(Filters.entity(MessageEntity.MENTION)(self.message)) + def test_entities_filter(self, message, message_entity): + message.entities = [message_entity] + assert Filters.entity(message_entity.type)(message) - self.message.entities = [self.e(MessageEntity.BOLD), self.e(MessageEntity.MENTION)] - self.assertTrue(Filters.entity(MessageEntity.MENTION)(self.message)) + message.entities = [] + assert not Filters.entity(MessageEntity.MENTION)(message) - def test_private_filter(self): - self.assertTrue(Filters.private(self.message)) - self.message.chat.type = "group" - self.assertFalse(Filters.private(self.message)) + second = message_entity.to_dict() + second['type'] = 'bold' + second = MessageEntity.de_json(second, None) + message.entities = [message_entity, second] + assert Filters.entity(message_entity.type)(message) - def test_group_fileter(self): - self.assertFalse(Filters.group(self.message)) - self.message.chat.type = "group" - self.assertTrue(Filters.group(self.message)) - self.message.chat.type = "supergroup" - self.assertTrue(Filters.group(self.message)) + def test_private_filter(self, message): + assert Filters.private(message) + message.chat.type = 'group' + assert not Filters.private(message) - def test_filters_chat(self): - with self.assertRaisesRegexp(ValueError, 'chat_id or username'): - Filters.chat(chat_id=-1, username='chat') - with self.assertRaisesRegexp(ValueError, 'chat_id or username'): - Filters.chat() - - def test_filters_chat_id(self): - self.assertFalse(Filters.chat(chat_id=-1)(self.message)) - self.message.chat.id = -1 - self.assertTrue(Filters.chat(chat_id=-1)(self.message)) - self.message.chat.id = -2 - self.assertTrue(Filters.chat(chat_id=[-1, -2])(self.message)) - self.assertFalse(Filters.chat(chat_id=-1)(self.message)) - - def test_filters_chat_username(self): - self.assertFalse(Filters.chat(username='chat')(self.message)) - self.message.chat.username = 'chat' - self.assertTrue(Filters.chat(username='@chat')(self.message)) - self.assertTrue(Filters.chat(username='chat')(self.message)) - self.assertTrue(Filters.chat(username=['chat1', 'chat', 'chat2'])(self.message)) - self.assertFalse(Filters.chat(username=['@chat1', 'chat_2'])(self.message)) + def test_group_filter(self, message): + assert not Filters.group(message) + message.chat.type = 'group' + assert Filters.group(message) + message.chat.type = 'supergroup' + assert Filters.group(message) def test_filters_user(self): - with self.assertRaisesRegexp(ValueError, 'user_id or username'): + with pytest.raises(ValueError, match='user_id or username'): Filters.user(user_id=1, username='user') - with self.assertRaisesRegexp(ValueError, 'user_id or username'): + with pytest.raises(ValueError, match='user_id or username'): Filters.user() - def test_filters_user_id(self): - self.assertFalse(Filters.user(user_id=1)(self.message)) - self.message.from_user.id = 1 - self.assertTrue(Filters.user(user_id=1)(self.message)) - self.message.from_user.id = 2 - self.assertTrue(Filters.user(user_id=[1, 2])(self.message)) - self.assertFalse(Filters.user(user_id=1)(self.message)) + def test_filters_user_id(self, message): + assert not Filters.user(user_id=1)(message) + message.from_user.id = 1 + assert Filters.user(user_id=1)(message) + message.from_user.id = 2 + assert Filters.user(user_id=[1, 2])(message) + assert not Filters.user(user_id=[3, 4])(message) - def test_filters_username(self): - self.assertFalse(Filters.user(username='user')(self.message)) - self.assertFalse(Filters.user(username='Testuser')(self.message)) - self.message.from_user.username = 'user' - self.assertTrue(Filters.user(username='@user')(self.message)) - self.assertTrue(Filters.user(username='user')(self.message)) - self.assertTrue(Filters.user(username=['user1', 'user', 'user2'])(self.message)) - self.assertFalse(Filters.user(username=['@username', '@user_2'])(self.message)) + def test_filters_username(self, message): + assert not Filters.user(username='user')(message) + assert not Filters.user(username='Testuser')(message) + message.from_user.username = 'user' + assert Filters.user(username='@user')(message) + assert Filters.user(username='user')(message) + assert Filters.user(username=['user1', 'user', 'user2'])(message) + assert not Filters.user(username=['@username', '@user_2'])(message) - def test_and_filters(self): - self.message.text = 'test' - self.message.forward_date = True - self.assertTrue((Filters.text & Filters.forwarded)(self.message)) - self.message.text = '/test' - self.assertFalse((Filters.text & Filters.forwarded)(self.message)) - self.message.text = 'test' - self.message.forward_date = None - self.assertFalse((Filters.text & Filters.forwarded)(self.message)) + def test_filters_chat(self): + with pytest.raises(ValueError, match='chat_id or username'): + Filters.chat(chat_id=-1, username='chat') + with pytest.raises(ValueError, match='chat_id or username'): + Filters.chat() - self.message.text = 'test' - self.message.forward_date = True - self.message.entities = [self.e(MessageEntity.MENTION)] - self.assertTrue((Filters.text & Filters.forwarded & Filters.entity(MessageEntity.MENTION))( - self.message)) - self.message.entities = [self.e(MessageEntity.BOLD)] - self.assertFalse((Filters.text & Filters.forwarded & Filters.entity(MessageEntity.MENTION) - )(self.message)) + def test_filters_chat_id(self, message): + assert not Filters.chat(chat_id=-1)(message) + message.chat.id = -1 + assert Filters.chat(chat_id=-1)(message) + message.chat.id = -2 + assert Filters.chat(chat_id=[-1, -2])(message) + assert not Filters.chat(chat_id=[-3, -4])(message) - def test_or_filters(self): - self.message.text = 'test' - self.assertTrue((Filters.text | Filters.status_update)(self.message)) - self.message.group_chat_created = True - self.assertTrue((Filters.text | Filters.status_update)(self.message)) - self.message.text = None - self.assertTrue((Filters.text | Filters.status_update)(self.message)) - self.message.group_chat_created = False - self.assertFalse((Filters.text | Filters.status_update)(self.message)) + def test_filters_chat_username(self, message): + assert not Filters.chat(username='chat')(message) + message.chat.username = 'chat' + assert Filters.chat(username='@chat')(message) + assert Filters.chat(username='chat')(message) + assert Filters.chat(username=['chat1', 'chat', 'chat2'])(message) + assert not Filters.chat(username=['@chat1', 'chat_2'])(message) - def test_and_or_filters(self): - self.message.text = 'test' - self.message.forward_date = True - self.assertTrue((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION)) - )(self.message)) - self.message.forward_date = False - self.assertFalse((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION) - ))(self.message)) - self.message.entities = [self.e(MessageEntity.MENTION)] - self.assertTrue((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION)) - )(self.message)) + def test_filters_invoice(self, message): + assert not Filters.invoice(message) + message.invoice = 'test' + assert Filters.invoice(message) - self.assertEqual( - str((Filters.text & (Filters.forwarded | Filters.entity(MessageEntity.MENTION)))), - '>' - ) + def test_filters_successful_payment(self, message): + assert not Filters.successful_payment(message) + message.successful_payment = 'test' + assert Filters.successful_payment(message) - def test_inverted_filters(self): - self.message.text = '/test' - self.assertTrue((Filters.command)(self.message)) - self.assertFalse((~Filters.command)(self.message)) - self.message.text = 'test' - self.assertFalse((Filters.command)(self.message)) - self.assertTrue((~Filters.command)(self.message)) + def test_language_filter_single(self, message): + message.from_user.language_code = 'en_US' + assert (Filters.language('en_US'))(message) + assert (Filters.language('en'))(message) + assert not (Filters.language('en_GB'))(message) + assert not (Filters.language('da'))(message) + message.from_user.language_code = 'da' + assert not (Filters.language('en_US'))(message) + assert not (Filters.language('en'))(message) + assert not (Filters.language('en_GB'))(message) + assert (Filters.language('da'))(message) - def test_inverted_and_filters(self): - self.message.text = '/test' - self.message.forward_date = 1 - self.assertTrue((Filters.forwarded & Filters.command)(self.message)) - self.assertFalse((~Filters.forwarded & Filters.command)(self.message)) - self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) - self.assertFalse((~(Filters.forwarded & Filters.command))(self.message)) - self.message.forward_date = None - self.assertFalse((Filters.forwarded & Filters.command)(self.message)) - self.assertTrue((~Filters.forwarded & Filters.command)(self.message)) - self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) - self.assertTrue((~(Filters.forwarded & Filters.command))(self.message)) - self.message.text = 'test' - self.assertFalse((Filters.forwarded & Filters.command)(self.message)) - self.assertFalse((~Filters.forwarded & Filters.command)(self.message)) - self.assertFalse((Filters.forwarded & ~Filters.command)(self.message)) - self.assertTrue((~(Filters.forwarded & Filters.command))(self.message)) + def test_language_filter_multiple(self, message): + f = Filters.language(['en_US', 'da']) + message.from_user.language_code = 'en_US' + assert f(message) + message.from_user.language_code = 'en_GB' + assert not f(message) + message.from_user.language_code = 'da' + assert f(message) - def test_faulty_custom_filter(self): + def test_and_filters(self, message): + message.text = 'test' + message.forward_date = True + assert (Filters.text & Filters.forwarded)(message) + message.text = '/test' + assert not (Filters.text & Filters.forwarded)(message) + message.text = 'test' + message.forward_date = None + assert not (Filters.text & Filters.forwarded)(message) + message.text = 'test' + message.forward_date = True + assert (Filters.text & Filters.forwarded & Filters.private)(message) + + def test_or_filters(self, message): + message.text = 'test' + assert (Filters.text | Filters.status_update)(message) + message.group_chat_created = True + assert (Filters.text | Filters.status_update)(message) + message.text = None + assert (Filters.text | Filters.status_update)(message) + message.group_chat_created = False + assert not (Filters.text | Filters.status_update)(message) + + def test_and_or_filters(self, message): + message.text = 'test' + message.forward_date = True + assert (Filters.text & (Filters.forwarded | Filters.status_update))(message) + message.forward_date = False + assert not (Filters.text & (Filters.forwarded | Filters.status_update))(message) + message.pinned_message = True + assert (Filters.text & (Filters.forwarded | Filters.status_update)(message)) + + assert str((Filters.text & (Filters.forwarded | Filters.entity( + MessageEntity.MENTION)))) == '>' + + def test_inverted_filters(self, message): + message.text = '/test' + assert Filters.command(message) + assert not (~Filters.command)(message) + message.text = 'test' + assert not Filters.command(message) + assert (~Filters.command)(message) + + def test_inverted_and_filters(self, message): + message.text = '/test' + message.forward_date = 1 + assert (Filters.forwarded & Filters.command)(message) + assert not (~Filters.forwarded & Filters.command)(message) + assert not (Filters.forwarded & ~Filters.command)(message) + assert not (~(Filters.forwarded & Filters.command))(message) + message.forward_date = None + assert not (Filters.forwarded & Filters.command)(message) + assert (~Filters.forwarded & Filters.command)(message) + assert not (Filters.forwarded & ~Filters.command)(message) + assert (~(Filters.forwarded & Filters.command))(message) + message.text = 'test' + assert not (Filters.forwarded & Filters.command)(message) + assert not (~Filters.forwarded & Filters.command)(message) + assert not (Filters.forwarded & ~Filters.command)(message) + assert (~(Filters.forwarded & Filters.command))(message) + + def test_faulty_custom_filter(self, message): class _CustomFilter(BaseFilter): pass custom = _CustomFilter() - with self.assertRaises(NotImplementedError): - (custom & Filters.text)(self.message) + with pytest.raises(NotImplementedError): + (custom & Filters.text)(message) - def test_language_filter_single(self): - self.message.from_user.language_code = 'en_US' - self.assertTrue((Filters.language('en_US'))(self.message)) - self.assertTrue((Filters.language('en'))(self.message)) - self.assertFalse((Filters.language('en_GB'))(self.message)) - self.assertFalse((Filters.language('da'))(self.message)) - self.message.from_user.language_code = 'en_GB' - self.assertFalse((Filters.language('en_US'))(self.message)) - self.assertTrue((Filters.language('en'))(self.message)) - self.assertTrue((Filters.language('en_GB'))(self.message)) - self.assertFalse((Filters.language('da'))(self.message)) - self.message.from_user.language_code = 'da' - self.assertFalse((Filters.language('en_US'))(self.message)) - self.assertFalse((Filters.language('en'))(self.message)) - self.assertFalse((Filters.language('en_GB'))(self.message)) - self.assertTrue((Filters.language('da'))(self.message)) - - def test_language_filter_multiple(self): - f = Filters.language(['en_US', 'da']) - self.message.from_user.language_code = 'en_US' - self.assertTrue(f(self.message)) - self.message.from_user.language_code = 'en_GB' - self.assertFalse(f(self.message)) - self.message.from_user.language_code = 'da' - self.assertTrue(f(self.message)) - - def test_custom_unnamed_filter(self): + def test_custom_unnamed_filter(self, message): class Unnamed(BaseFilter): - def filter(self, message): + def filter(self, mes): return True unnamed = Unnamed() - self.assertEqual(str(unnamed), Unnamed.__name__) - - -if __name__ == '__main__': - unittest.main() + assert str(unnamed) == Unnamed.__name__ diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index e4898ab51..427057506 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -1,76 +1,48 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram ForceReply""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ForceReply -class ForceReplyTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ForceReply.""" - - def setUp(self): - self.force_reply = True - self.selective = True - - self.json_dict = { - 'force_reply': self.force_reply, - 'selective': self.selective, - } - - def test_send_message_with_force_reply(self): - message = self._bot.sendMessage( - self._chat_id, - 'Моё судно на воздушной подушке полно угрей', - reply_markup=telegram.ForceReply.de_json(self.json_dict, self._bot)) - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') - - def test_force_reply_de_json(self): - force_reply = telegram.ForceReply.de_json(self.json_dict, self._bot) - - self.assertEqual(force_reply.force_reply, self.force_reply) - self.assertEqual(force_reply.selective, self.selective) - - def test_force_reply_de_json_empty(self): - force_reply = telegram.ForceReply.de_json(None, self._bot) - - self.assertFalse(force_reply) - - def test_force_reply_to_json(self): - force_reply = telegram.ForceReply.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(force_reply.to_json())) - - def test_force_reply_to_dict(self): - force_reply = telegram.ForceReply.de_json(self.json_dict, self._bot) - - self.assertEqual(force_reply['force_reply'], self.force_reply) - self.assertEqual(force_reply['selective'], self.selective) +@pytest.fixture(scope='class') +def force_reply(): + return ForceReply(TestForceReply.force_reply, TestForceReply.selective) -if __name__ == '__main__': - unittest.main() +class TestForceReply(object): + force_reply = True + selective = True + + def test_send_message_with_force_reply(self, bot, chat_id, force_reply): + message = bot.send_message(chat_id, 'text', reply_markup=force_reply) + + assert message.text == 'text' + + def test_expected(self, force_reply): + assert force_reply.force_reply == self.force_reply + assert force_reply.selective == self.selective + + def test_to_dict(self, force_reply): + force_reply_dict = force_reply.to_dict() + + assert isinstance(force_reply_dict, dict) + assert force_reply_dict['force_reply'] == force_reply.force_reply + assert force_reply_dict['selective'] == force_reply.selective diff --git a/tests/test_game.py b/tests/test_game.py index 494e0cde0..3692f14bf 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -1,101 +1,97 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Games""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import MessageEntity, Game, PhotoSize, Animation -class GameTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Game.""" +@pytest.fixture(scope='function') +def game(): + return Game(TestGame.title, + TestGame.description, + TestGame.photo, + text=TestGame.text, + text_entities=TestGame.text_entities, + animation=TestGame.animation) - def setUp(self): - self.title = 'Python-telegram-bot Test Game' - self.description = 'description' - self.photo = [{'width': 640, 'height': 360, 'file_id': 'Blah', 'file_size': 0}] - self.text = 'Other description' - self.text_entities = [{'offset': 13, 'length': 17, 'type': telegram.MessageEntity.URL}] - self.animation = {'file_id': 'Blah'} - self.json_dict = { +class TestGame(object): + title = 'Python-telegram-bot Test Game' + description = 'description' + photo = [PhotoSize('Blah', 640, 360, file_size=0)] + text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' + b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape') + text_entities = [MessageEntity(13, 17, MessageEntity.URL)] + animation = Animation('blah') + + def test_de_json_required(self, bot): + json_dict = { 'title': self.title, 'description': self.description, - 'photo': self.photo, - 'text': self.text, - 'text_entities': self.text_entities, - 'animation': self.animation + 'photo': [self.photo[0].to_dict()], } + game = Game.de_json(json_dict, bot) - def test_game_de_json(self): - game = telegram.Game.de_json(self.json_dict, self._bot) + assert game.title == self.title + assert game.description == self.description + assert game.photo == self.photo - self.assertEqual(game.title, self.title) - self.assertEqual(game.description, self.description) - self.assertTrue(isinstance(game.photo[0], telegram.PhotoSize)) - self.assertEqual(game.text, self.text) - self.assertTrue(isinstance(game.text_entities[0], telegram.MessageEntity)) - self.assertTrue(isinstance(game.animation, telegram.Animation)) + def test_de_json_all(self, bot): + json_dict = { + 'title': self.title, + 'description': self.description, + 'photo': [self.photo[0].to_dict()], + 'text': self.text, + 'text_entities': [self.text_entities[0].to_dict()], + 'animation': self.animation.to_dict() + } + game = Game.de_json(json_dict, bot) - def test_game_to_json(self): - game = telegram.Game.de_json(self.json_dict, self._bot) + assert game.title == self.title + assert game.description == self.description + assert game.photo == self.photo + assert game.text == self.text + assert game.text_entities == self.text_entities + assert game.animation == self.animation - self.assertTrue(self.is_json(game.to_json())) + def test_to_dict(self, game): + game_dict = game.to_dict() - def test_game_all_args(self): - game = telegram.Game( - title=self.title, - description=self.description, - photo=self.photo, - text=self.text, - text_entities=self.text_entities, - animation=self.animation) + assert isinstance(game_dict, dict) + assert game_dict['title'] == game.title + assert game_dict['description'] == game.description + assert game_dict['photo'] == [game.photo[0].to_dict()] + assert game_dict['text'] == game.text + assert game_dict['text_entities'] == [game.text_entities[0].to_dict()] + assert game_dict['animation'] == game.animation.to_dict() - self.assertEqual(game.title, self.title) - self.assertEqual(game.description, self.description) - self.assertEqual(game.photo, self.photo) - self.assertEqual(game.text, self.text) - self.assertEqual(game.text_entities, self.text_entities) - self.assertEqual(game.animation, self.animation) + def test_parse_entity(self, game): + entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) + game.text_entities = [entity] - def test_parse_entity(self): - text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' - b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape') - entity = telegram.MessageEntity(type=telegram.MessageEntity.URL, offset=13, length=17) - game = telegram.Game( - self.title, self.description, self.photo, text=text, text_entities=[entity]) - self.assertEqual(game.parse_text_entity(entity), 'http://google.com') + assert game.parse_text_entity(entity) == 'http://google.com' - def test_parse_entities(self): - text = (b'\\U0001f469\\u200d\\U0001f469\\u200d\\U0001f467' - b'\\u200d\\U0001f467\\U0001f431http://google.com').decode('unicode-escape') - entity = telegram.MessageEntity(type=telegram.MessageEntity.URL, offset=13, length=17) - entity_2 = telegram.MessageEntity(type=telegram.MessageEntity.BOLD, offset=13, length=1) - game = telegram.Game( - self.title, self.description, self.photo, text=text, text_entities=[entity_2, entity]) - self.assertDictEqual( - game.parse_text_entities(telegram.MessageEntity.URL), {entity: 'http://google.com'}) - self.assertDictEqual(game.parse_text_entities(), - {entity: 'http://google.com', - entity_2: 'h'}) + def test_parse_entities(self, game): + entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) + entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1) + game.text_entities = [entity_2, entity] + + assert game.parse_text_entities(MessageEntity.URL) == {entity: 'http://google.com'} + assert game.parse_text_entities() == {entity: 'http://google.com', entity_2: 'h'} diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py new file mode 100644 index 000000000..fd132727b --- /dev/null +++ b/tests/test_gamehighscore.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import GameHighScore, User + + +@pytest.fixture(scope='class') +def game_highscore(): + return GameHighScore(TestGameHighScore.position, + TestGameHighScore.user, + TestGameHighScore.score) + + +class TestGameHighScore(object): + position = 12 + user = User(2, 'test user') + score = 42 + + def test_de_json(self, bot): + json_dict = {'position': self.position, + 'user': self.user.to_dict(), + 'score': self.score} + highscore = GameHighScore.de_json(json_dict, bot) + + assert highscore.position == self.position + assert highscore.user == self.user + assert highscore.score == self.score + + def test_to_dict(self, game_highscore): + game_highscore_dict = game_highscore.to_dict() + + assert isinstance(game_highscore_dict, dict) + assert game_highscore_dict['position'] == game_highscore.position + assert game_highscore_dict['user'] == game_highscore.user.to_dict() + assert game_highscore_dict['score'] == game_highscore.score diff --git a/tests/test_helpers.py b/tests/test_helpers.py index b96ce4372..49cd7751d 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -5,38 +5,24 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -MessageEntity""" - -import sys -import unittest from telegram.utils import helpers -sys.path.append('.') - -from tests.base import BaseTest - - -class HelpersTest(BaseTest, unittest.TestCase): - """This object represents Tests for the Helpers Module""" +class TestHelpers(object): def test_escape_markdown(self): - test_str = "*bold*, _italic_, `code`, [text_link](http://github.com/)" - expected_str = "\*bold\*, \_italic\_, \`code\`, \[text\_link](http://github.com/)" - self.assertEquals(expected_str, helpers.escape_markdown(test_str)) + test_str = '*bold*, _italic_, `code`, [text_link](http://github.com/)' + expected_str = '\*bold\*, \_italic\_, \`code\`, \[text\_link](http://github.com/)' - -if __name__ == '__main__': - unittest.main() + assert expected_str == helpers.escape_markdown(test_str) diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index c6ce97a7a..b187d7084 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -1,79 +1,86 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram InlineKeyboardButton""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InlineKeyboardButton -class InlineKeyboardButtonTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram KeyboardButton.""" +@pytest.fixture(scope='class') +def inline_keyboard_button(): + return InlineKeyboardButton(TestInlineKeyboardButton.text, + url=TestInlineKeyboardButton.url, + callback_data=TestInlineKeyboardButton.callback_data, + switch_inline_query=TestInlineKeyboardButton.switch_inline_query, + switch_inline_query_current_chat=TestInlineKeyboardButton + .switch_inline_query_current_chat, + callback_game=TestInlineKeyboardButton.callback_game, + pay=TestInlineKeyboardButton.pay) - def setUp(self): - self.text = 'text' - self.url = 'url' - self.callback_data = 'callback data' - self.switch_inline_query = '' - self.json_dict = { +class TestInlineKeyboardButton(object): + text = 'text' + url = 'url' + callback_data = 'callback data' + switch_inline_query = 'switch_inline_query' + switch_inline_query_current_chat = 'switch_inline_query_current_chat' + callback_game = 'callback_game' + pay = 'pay' + + def test_de_json(self, bot): + json_dict = { 'text': self.text, 'url': self.url, 'callback_data': self.callback_data, - 'switch_inline_query': self.switch_inline_query + 'switch_inline_query': self.switch_inline_query, + 'switch_inline_query_current_chat': + self.switch_inline_query_current_chat, + 'callback_game': self.callback_game, + 'pay': self.pay } + inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, bot) - def test_inline_keyboard_button_de_json(self): - inline_keyboard_button = telegram.InlineKeyboardButton.de_json(self.json_dict, self._bot) + assert inline_keyboard_button.text == self.text + assert inline_keyboard_button.url == self.url + assert inline_keyboard_button.callback_data == self.callback_data + assert inline_keyboard_button.switch_inline_query == self.switch_inline_query + assert inline_keyboard_button.switch_inline_query_current_chat == \ + self.switch_inline_query_current_chat + assert inline_keyboard_button.callback_game == self.callback_game + assert inline_keyboard_button.pay == self.pay - self.assertEqual(inline_keyboard_button.text, self.text) - self.assertEqual(inline_keyboard_button.url, self.url) - self.assertEqual(inline_keyboard_button.callback_data, self.callback_data) - self.assertEqual(inline_keyboard_button.switch_inline_query, self.switch_inline_query) + def test_de_list(self, bot, inline_keyboard_button): + keyboard_json = [inline_keyboard_button.to_dict(), inline_keyboard_button.to_dict()] + inline_keyboard_buttons = InlineKeyboardButton.de_list(keyboard_json, bot) - def test_inline_keyboard_button_de_json_empty(self): - inline_keyboard_button = telegram.InlineKeyboardButton.de_json(None, self._bot) + assert inline_keyboard_buttons == [inline_keyboard_button, inline_keyboard_button] - self.assertFalse(inline_keyboard_button) + def test_to_dict(self, inline_keyboard_button): + inline_keyboard_button_dict = inline_keyboard_button.to_dict() - def test_inline_keyboard_button_de_list_empty(self): - inline_keyboard_button = telegram.InlineKeyboardButton.de_list(None, self._bot) - - self.assertFalse(inline_keyboard_button) - - def test_inline_keyboard_button_to_json(self): - inline_keyboard_button = telegram.InlineKeyboardButton.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(inline_keyboard_button.to_json())) - - def test_inline_keyboard_button_to_dict(self): - inline_keyboard_button = telegram.InlineKeyboardButton.de_json(self.json_dict, - self._bot).to_dict() - - self.assertTrue(self.is_dict(inline_keyboard_button)) - self.assertDictEqual(self.json_dict, inline_keyboard_button) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(inline_keyboard_button_dict, dict) + assert inline_keyboard_button_dict['text'] == inline_keyboard_button.text + assert inline_keyboard_button_dict['url'] == inline_keyboard_button.url + assert inline_keyboard_button_dict['callback_data'] == inline_keyboard_button.callback_data + assert inline_keyboard_button_dict['switch_inline_query'] == \ + inline_keyboard_button.switch_inline_query + assert inline_keyboard_button_dict['switch_inline_query_current_chat'] == \ + inline_keyboard_button.switch_inline_query_current_chat + assert inline_keyboard_button_dict['callback_game'] == inline_keyboard_button.callback_game + assert inline_keyboard_button_dict['pay'] == inline_keyboard_button.pay diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 58b1b0d5b..acc72bca3 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -1,83 +1,64 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram InlineKeyboardMarkup""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InlineKeyboardButton, InlineKeyboardMarkup -class InlineKeyboardMarkupTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram KeyboardButton.""" +@pytest.fixture(scope='class') +def inline_keyboard_markup(): + return InlineKeyboardMarkup(TestInlineKeyboardMarkup.inline_keyboard) - def setUp(self): - self.inline_keyboard = [[ - telegram.InlineKeyboardButton( - text='button1', callback_data='data1'), telegram.InlineKeyboardButton( - text='button2', callback_data='data2') - ]] - self.json_dict = { - 'inline_keyboard': - [[self.inline_keyboard[0][0].to_dict(), self.inline_keyboard[0][1].to_dict()]], - } +class TestInlineKeyboardMarkup(object): + inline_keyboard = [[ + InlineKeyboardButton(text='button1', callback_data='data1'), + InlineKeyboardButton(text='button2', callback_data='data2') + ]] - def test_send_message_with_inline_keyboard_markup(self): - message = self._bot.sendMessage( - self._chat_id, + def test_send_message_with_inline_keyboard_markup(self, bot, chat_id, inline_keyboard_markup): + message = bot.send_message( + chat_id, 'Testing InlineKeyboardMarkup', - reply_markup=telegram.InlineKeyboardMarkup(self.inline_keyboard)) + reply_markup=inline_keyboard_markup) - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, 'Testing InlineKeyboardMarkup') + assert message.text == 'Testing InlineKeyboardMarkup' - def test_inline_keyboard_markup_de_json_empty(self): - inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(None, self._bot) + def test_de_json(self, bot, inline_keyboard_markup): + json_dict = { + 'inline_keyboard': [[ + self.inline_keyboard[0][0].to_dict(), + self.inline_keyboard[0][1].to_dict() + ]], + } + inline_keyboard_markup_json = InlineKeyboardMarkup.de_json(json_dict, bot) - self.assertFalse(inline_keyboard_markup) + assert inline_keyboard_markup_json.to_dict() == inline_keyboard_markup.to_dict() - def test_inline_keyboard_markup_de_json(self): - inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_keyboard_markup): + inline_keyboard_markup_dict = inline_keyboard_markup.to_dict() - self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard, list)) - self.assertTrue( - isinstance(inline_keyboard_markup.inline_keyboard[0][0], - telegram.InlineKeyboardButton)) - - def test_inline_keyboard_markup_to_json(self): - inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(inline_keyboard_markup.to_json())) - - def test_inline_keyboard_markup_to_dict(self): - inline_keyboard_markup = telegram.InlineKeyboardMarkup.de_json(self.json_dict, self._bot) - - self.assertTrue(isinstance(inline_keyboard_markup.inline_keyboard, list)) - self.assertTrue( - isinstance(inline_keyboard_markup.inline_keyboard[0][0], - telegram.InlineKeyboardButton)) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(inline_keyboard_markup_dict, dict) + assert inline_keyboard_markup_dict['inline_keyboard'] == [ + [ + self.inline_keyboard[0][0].to_dict(), + self.inline_keyboard[0][1].to_dict() + ] + ] diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index b9de97384..f7082f0f8 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -5,90 +5,85 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQuery""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import User, Location, InlineQuery, Update -class InlineQueryTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQuery.""" +@pytest.fixture(scope='class') +def inline_query(bot): + return InlineQuery(TestInlineQuery.id, TestInlineQuery.from_user, TestInlineQuery.query, + TestInlineQuery.offset, location=TestInlineQuery.location, bot=bot) - def setUp(self): - user = telegram.User(1, 'First name') - location = telegram.Location(8.8, 53.1) - self._id = 1234 - self.from_user = user - self.query = 'query text' - self.offset = 'offset' - self.location = location +class TestInlineQuery(object): + id = 1234 + from_user = User(1, 'First name') + query = 'query text' + offset = 'offset' + location = Location(8.8, 53.1) - self.json_dict = { - 'id': self._id, + def test_de_json(self, bot): + json_dict = { + 'id': self.id, 'from': self.from_user.to_dict(), 'query': self.query, 'offset': self.offset, 'location': self.location.to_dict() } + inline_query_json = InlineQuery.de_json(json_dict, bot) - def test_inlinequery_de_json(self): - inlinequery = telegram.InlineQuery.de_json(self.json_dict, self._bot) + assert inline_query_json.id == self.id + assert inline_query_json.from_user == self.from_user + assert inline_query_json.location == self.location + assert inline_query_json.query == self.query + assert inline_query_json.offset == self.offset - self.assertEqual(inlinequery.id, self._id) - self.assertDictEqual(inlinequery.from_user.to_dict(), self.from_user.to_dict()) - self.assertDictEqual(inlinequery.location.to_dict(), self.location.to_dict()) - self.assertEqual(inlinequery.query, self.query) - self.assertEqual(inlinequery.offset, self.offset) + def test_to_dict(self, inline_query): + inline_query_dict = inline_query.to_dict() - def test_inlinequery_to_json(self): - inlinequery = telegram.InlineQuery.de_json(self.json_dict, self._bot) + assert isinstance(inline_query_dict, dict) + assert inline_query_dict['id'] == inline_query.id + assert inline_query_dict['from'] == inline_query.from_user.to_dict() + assert inline_query_dict['location'] == inline_query.location.to_dict() + assert inline_query_dict['query'] == inline_query.query + assert inline_query_dict['offset'] == inline_query.offset - self.assertTrue(self.is_json(inlinequery.to_json())) + def test_answer(self, monkeypatch, inline_query): + def test(*args, **kwargs): + return args[1] == inline_query.id - def test_inlinequery_to_dict(self): - inlinequery = telegram.InlineQuery.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(inlinequery)) - self.assertDictEqual(inlinequery, self.json_dict) + monkeypatch.setattr('telegram.Bot.answer_inline_query', test) + assert inline_query.answer() def test_equality(self): - a = telegram.InlineQuery(self._id, telegram.User(1, ""), "", "") - b = telegram.InlineQuery(self._id, telegram.User(1, ""), "", "") - c = telegram.InlineQuery(self._id, telegram.User(0, ""), "", "") - d = telegram.InlineQuery(0, telegram.User(1, ""), "", "") - e = telegram.Update(self._id) + a = InlineQuery(self.id, User(1, ''), '', '') + b = InlineQuery(self.id, User(1, ''), '', '') + c = InlineQuery(self.id, User(0, ''), '', '') + d = InlineQuery(0, User(1, ''), '', '') + e = Update(self.id) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryhandler.py b/tests/test_inlinequeryhandler.py new file mode 100644 index 000000000..f7e38d3fc --- /dev/null +++ b/tests/test_inlinequeryhandler.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import pytest + +from telegram import (Update, CallbackQuery, Bot, Message, User, Chat, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery, Location) +from telegram.ext import InlineQueryHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=2, **request.param) + + +@pytest.fixture(scope='function') +def inline_query(bot): + return Update(0, inline_query=InlineQuery('id', User(2, 'test user'), + 'test query', offset='22', + location=Location(latitude=-23.691288, + longitude=-46.788279))) + + +class TestCallbackQueryHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def callback_group(self, bot, update, groups=None, groupdict=None): + if groups is not None: + self.test_flag = groups == ('t', ' query') + if groupdict is not None: + self.test_flag = groupdict == {'begin': 't', 'end': ' query'} + + def test_basic(self, dp, inline_query): + handler = InlineQueryHandler(self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(inline_query) + + dp.process_update(inline_query) + assert self.test_flag + + def test_with_pattern(self, inline_query): + handler = InlineQueryHandler(self.callback_basic, pattern='(?P.*)est(?P.*)') + + assert handler.check_update(inline_query) + + inline_query.inline_query.query = 'nothing here' + assert not handler.check_update(inline_query) + + def test_with_passing_group_dict(self, dp, inline_query): + handler = InlineQueryHandler(self.callback_group, + pattern='(?P.*)est(?P.*)', + pass_groups=True) + dp.add_handler(handler) + + dp.process_update(inline_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = InlineQueryHandler(self.callback_group, + pattern='(?P.*)est(?P.*)', + pass_groupdict=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(inline_query) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, inline_query): + handler = InlineQueryHandler(self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(inline_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = InlineQueryHandler(self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(inline_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = InlineQueryHandler(self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(inline_query) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, inline_query): + handler = InlineQueryHandler(self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(inline_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = InlineQueryHandler(self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(inline_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = InlineQueryHandler(self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(inline_query) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = InlineQueryHandler(self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index 813ee1e30..3b10a1bd0 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -5,107 +5,103 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultArticle""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardMarkup, InlineQueryResultAudio, InlineQueryResultArticle, + InlineKeyboardButton, InputTextMessageContent) -class InlineQueryResultArticleTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultArticle.""" +@pytest.fixture(scope='class') +def inline_query_result_article(): + return InlineQueryResultArticle(TestInlineQueryResultArticle.id, + TestInlineQueryResultArticle.title, + input_message_content=TestInlineQueryResultArticle.input_message_content, + reply_markup=TestInlineQueryResultArticle.reply_markup, + url=TestInlineQueryResultArticle.url, + hide_url=TestInlineQueryResultArticle.hide_url, + description=TestInlineQueryResultArticle.description, + thumb_url=TestInlineQueryResultArticle.thumb_url, + thumb_height=TestInlineQueryResultArticle.thumb_height, + thumb_width=TestInlineQueryResultArticle.thumb_width) - def setUp(self): - self._id = 'id' - self.type = 'article' - self.title = 'title' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - 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': self.type, - 'id': self._id, - 'title': self.title, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - '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 - } +class TestInlineQueryResultArticle(object): + id = 'id' + type = 'article' + title = 'title' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) + url = 'url' + hide_url = True + description = 'description' + thumb_url = 'thumb url' + thumb_height = 10 + thumb_width = 15 - def test_article_de_json(self): - article = telegram.InlineQueryResultArticle.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_article): + assert inline_query_result_article.type == self.type + assert inline_query_result_article.id == self.id + assert inline_query_result_article.title == self.title + assert inline_query_result_article.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_article.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_article.url == self.url + assert inline_query_result_article.hide_url == self.hide_url + assert inline_query_result_article.description == self.description + assert inline_query_result_article.thumb_url == self.thumb_url + assert inline_query_result_article.thumb_height == self.thumb_height + assert inline_query_result_article.thumb_width == self.thumb_width - self.assertEqual(article.type, self.type) - self.assertEqual(article.id, self._id) - self.assertEqual(article.title, self.title) - self.assertDictEqual(article.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(article.reply_markup.to_dict(), self.reply_markup.to_dict()) - 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_to_dict(self, inline_query_result_article): + inline_query_result_article_dict = inline_query_result_article.to_dict() - def test_article_to_json(self): - article = telegram.InlineQueryResultArticle.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(article.to_json())) - - def test_article_to_dict(self): - article = telegram.InlineQueryResultArticle.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(article)) - self.assertDictEqual(self.json_dict, article) + assert isinstance(inline_query_result_article_dict, dict) + assert inline_query_result_article_dict['type'] == inline_query_result_article.type + assert inline_query_result_article_dict['id'] == inline_query_result_article.id + assert inline_query_result_article_dict['title'] == inline_query_result_article.title + assert inline_query_result_article_dict['input_message_content'] == \ + inline_query_result_article.input_message_content.to_dict() + assert inline_query_result_article_dict['reply_markup'] == \ + inline_query_result_article.reply_markup.to_dict() + assert inline_query_result_article_dict['url'] == inline_query_result_article.url + assert inline_query_result_article_dict['hide_url'] == inline_query_result_article.hide_url + assert inline_query_result_article_dict['description'] == \ + inline_query_result_article.description + assert inline_query_result_article_dict['thumb_url'] == \ + inline_query_result_article.thumb_url + assert inline_query_result_article_dict['thumb_height'] == \ + inline_query_result_article.thumb_height + assert inline_query_result_article_dict['thumb_width'] == \ + inline_query_result_article.thumb_width def test_equality(self): - a = telegram.InlineQueryResultArticle(self._id, self.title, self.input_message_content) - b = telegram.InlineQueryResultArticle(self._id, self.title, self.input_message_content) - c = telegram.InlineQueryResultArticle(self._id, "", self.input_message_content) - d = telegram.InlineQueryResultArticle("", self.title, self.input_message_content) - e = telegram.InlineQueryResultAudio(self._id, "", "") + a = InlineQueryResultArticle(self.id, self.title, self.input_message_content) + b = InlineQueryResultArticle(self.id, self.title, self.input_message_content) + c = InlineQueryResultArticle(self.id, '', self.input_message_content) + d = InlineQueryResultArticle('', self.title, self.input_message_content) + e = InlineQueryResultAudio(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index f2efa417a..39f7c2ed9 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -5,101 +5,92 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultAudio""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardMarkup, InlineKeyboardButton, InlineQueryResultAudio, + InputTextMessageContent, InlineQueryResultVoice) -class InlineQueryResultAudioTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultAudio.""" +@pytest.fixture(scope='class') +def inline_query_result_audio(): + return InlineQueryResultAudio(TestInlineQueryResultAudio.id, + TestInlineQueryResultAudio.audio_url, + TestInlineQueryResultAudio.title, + performer=TestInlineQueryResultAudio.performer, + audio_duration=TestInlineQueryResultAudio.audio_duration, + caption=TestInlineQueryResultAudio.caption, + input_message_content=TestInlineQueryResultAudio.input_message_content, + reply_markup=TestInlineQueryResultAudio.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'audio' - self.audio_url = 'audio url' - self.title = 'title' - self.performer = 'performer' - self.audio_duration = 'audio_duration' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'audio_url': self.audio_url, - 'title': self.title, - 'performer': self.performer, - 'audio_duration': self.audio_duration, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultAudio(object): + id = 'id' + type = 'audio' + audio_url = 'audio url' + title = 'title' + performer = 'performer' + audio_duration = 'audio_duration' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_audio_de_json(self): - audio = telegram.InlineQueryResultAudio.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_audio): + assert inline_query_result_audio.type == self.type + assert inline_query_result_audio.id == self.id + assert inline_query_result_audio.audio_url == self.audio_url + assert inline_query_result_audio.title == self.title + assert inline_query_result_audio.performer == self.performer + assert inline_query_result_audio.audio_duration == self.audio_duration + assert inline_query_result_audio.caption == self.caption + assert inline_query_result_audio.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_audio.reply_markup.to_dict() == self.reply_markup.to_dict() - self.assertEqual(audio.type, self.type) - self.assertEqual(audio.id, self._id) - self.assertEqual(audio.audio_url, self.audio_url) - self.assertEqual(audio.title, self.title) - self.assertEqual(audio.performer, self.performer) - self.assertEqual(audio.audio_duration, self.audio_duration) - self.assertEqual(audio.caption, self.caption) - self.assertDictEqual(audio.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(audio.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_audio): + inline_query_result_audio_dict = inline_query_result_audio.to_dict() - def test_audio_to_json(self): - audio = telegram.InlineQueryResultAudio.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(audio.to_json())) - - def test_audio_to_dict(self): - audio = telegram.InlineQueryResultAudio.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(audio)) - self.assertDictEqual(self.json_dict, audio) + assert isinstance(inline_query_result_audio_dict, dict) + assert inline_query_result_audio_dict['type'] == inline_query_result_audio.type + assert inline_query_result_audio_dict['id'] == inline_query_result_audio.id + assert inline_query_result_audio_dict['audio_url'] == inline_query_result_audio.audio_url + assert inline_query_result_audio_dict['title'] == inline_query_result_audio.title + assert inline_query_result_audio_dict['performer'] == inline_query_result_audio.performer + assert inline_query_result_audio_dict['audio_duration'] == \ + inline_query_result_audio.audio_duration + assert inline_query_result_audio_dict['caption'] == inline_query_result_audio.caption + assert inline_query_result_audio_dict['input_message_content'] == \ + inline_query_result_audio.input_message_content.to_dict() + assert inline_query_result_audio_dict['reply_markup'] == \ + inline_query_result_audio.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultAudio(self._id, self.audio_url, self.title) - b = telegram.InlineQueryResultAudio(self._id, self.title, self.title) - c = telegram.InlineQueryResultAudio(self._id, "", self.title) - d = telegram.InlineQueryResultAudio("", self.audio_url, self.title) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultAudio(self.id, self.audio_url, self.title) + b = InlineQueryResultAudio(self.id, self.title, self.title) + c = InlineQueryResultAudio(self.id, '', self.title) + d = InlineQueryResultAudio('', self.audio_url, self.title) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index 7b4c58c3a..c3cabf962 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -5,93 +5,83 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedAudio""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InputTextMessageContent, InlineQueryResultCachedAudio, InlineKeyboardMarkup, + InlineKeyboardButton, InlineQueryResultCachedVoice) -class InlineQueryResultCachedAudioTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedAudio.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_audio(): + return InlineQueryResultCachedAudio(TestInlineQueryResultCachedAudio.id, + TestInlineQueryResultCachedAudio.audio_file_id, + caption=TestInlineQueryResultCachedAudio.caption, + input_message_content=TestInlineQueryResultCachedAudio.input_message_content, + reply_markup=TestInlineQueryResultCachedAudio.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'audio' - self.audio_file_id = 'audio file id' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'audio_file_id': self.audio_file_id, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedAudio(object): + id = 'id' + type = 'audio' + audio_file_id = 'audio file id' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_audio_de_json(self): - audio = telegram.InlineQueryResultCachedAudio.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_audio): + assert inline_query_result_cached_audio.type == self.type + assert inline_query_result_cached_audio.id == self.id + assert inline_query_result_cached_audio.audio_file_id == self.audio_file_id + assert inline_query_result_cached_audio.caption == self.caption + assert inline_query_result_cached_audio.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_audio.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(audio.type, self.type) - self.assertEqual(audio.id, self._id) - self.assertEqual(audio.audio_file_id, self.audio_file_id) - self.assertEqual(audio.caption, self.caption) - self.assertDictEqual(audio.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(audio.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_audio): + inline_query_result_cached_audio_dict = inline_query_result_cached_audio.to_dict() - def test_audio_to_json(self): - audio = telegram.InlineQueryResultCachedAudio.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(audio.to_json())) - - def test_audio_to_dict(self): - audio = telegram.InlineQueryResultCachedAudio.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(audio)) - self.assertDictEqual(self.json_dict, audio) + assert isinstance(inline_query_result_cached_audio_dict, dict) + assert inline_query_result_cached_audio_dict['type'] == \ + inline_query_result_cached_audio.type + assert inline_query_result_cached_audio_dict['id'] == inline_query_result_cached_audio.id + assert inline_query_result_cached_audio_dict['audio_file_id'] == \ + inline_query_result_cached_audio.audio_file_id + assert inline_query_result_cached_audio_dict['caption'] == \ + inline_query_result_cached_audio.caption + assert inline_query_result_cached_audio_dict['input_message_content'] == \ + inline_query_result_cached_audio.input_message_content.to_dict() + assert inline_query_result_cached_audio_dict['reply_markup'] == \ + inline_query_result_cached_audio.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedAudio(self._id, self.audio_file_id) - b = telegram.InlineQueryResultCachedAudio(self._id, self.audio_file_id) - c = telegram.InlineQueryResultCachedAudio(self._id, "") - d = telegram.InlineQueryResultCachedAudio("", self.audio_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedAudio(self.id, self.audio_file_id) + b = InlineQueryResultCachedAudio(self.id, self.audio_file_id) + c = InlineQueryResultCachedAudio(self.id, '') + d = InlineQueryResultCachedAudio('', self.audio_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 9b2885f2f..5c6878d65 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -5,99 +5,94 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedDocument""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultCachedDocument, InlineKeyboardButton, InlineKeyboardMarkup, + InputTextMessageContent, InlineQueryResultCachedVoice) -class InlineQueryResultCachedDocumentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedDocument.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_document(): + return InlineQueryResultCachedDocument(TestInlineQueryResultCachedDocument.id, + TestInlineQueryResultCachedDocument.title, + TestInlineQueryResultCachedDocument.document_file_id, + caption=TestInlineQueryResultCachedDocument.caption, + description=TestInlineQueryResultCachedDocument.description, + input_message_content=TestInlineQueryResultCachedDocument.input_message_content, + reply_markup=TestInlineQueryResultCachedDocument.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'document' - self.document_file_id = 'document file id' - self.title = 'title' - self.caption = 'caption' - self.description = 'description' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'id': self._id, - 'type': self.type, - 'document_file_id': self.document_file_id, - 'title': self.title, - 'caption': self.caption, - 'description': self.description, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } - def test_document_de_json(self): - document = telegram.InlineQueryResultCachedDocument.de_json(self.json_dict, self._bot) +class TestInlineQueryResultCachedDocument(object): + id = 'id' + type = 'document' + document_file_id = 'document file id' + title = 'title' + caption = 'caption' + description = 'description' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - self.assertEqual(document.id, self._id) - self.assertEqual(document.type, self.type) - self.assertEqual(document.document_file_id, self.document_file_id) - self.assertEqual(document.title, self.title) - self.assertEqual(document.caption, self.caption) - self.assertEqual(document.description, self.description) - self.assertDictEqual(document.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(document.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_expected_values(self, inline_query_result_cached_document): + assert inline_query_result_cached_document.id == self.id + assert inline_query_result_cached_document.type == self.type + assert inline_query_result_cached_document.document_file_id == self.document_file_id + assert inline_query_result_cached_document.title == self.title + assert inline_query_result_cached_document.caption == self.caption + assert inline_query_result_cached_document.description == self.description + assert inline_query_result_cached_document.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_document.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - def test_document_to_json(self): - document = telegram.InlineQueryResultCachedDocument.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_query_result_cached_document): + inline_query_result_cached_document_dict = inline_query_result_cached_document.to_dict() - self.assertTrue(self.is_json(document.to_json())) - - def test_document_to_dict(self): - document = telegram.InlineQueryResultCachedDocument.de_json(self.json_dict, - self._bot).to_dict() - - self.assertTrue(self.is_dict(document)) - self.assertDictEqual(self.json_dict, document) + assert isinstance(inline_query_result_cached_document_dict, dict) + assert inline_query_result_cached_document_dict['id'] == \ + inline_query_result_cached_document.id + assert inline_query_result_cached_document_dict['type'] == \ + inline_query_result_cached_document.type + assert inline_query_result_cached_document_dict['document_file_id'] == \ + inline_query_result_cached_document.document_file_id + assert inline_query_result_cached_document_dict['title'] == \ + inline_query_result_cached_document.title + assert inline_query_result_cached_document_dict['caption'] == \ + inline_query_result_cached_document.caption + assert inline_query_result_cached_document_dict['description'] == \ + inline_query_result_cached_document.description + assert inline_query_result_cached_document_dict['input_message_content'] == \ + inline_query_result_cached_document.input_message_content.to_dict() + assert inline_query_result_cached_document_dict['reply_markup'] == \ + inline_query_result_cached_document.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedDocument(self._id, self.title, self.document_file_id) - b = telegram.InlineQueryResultCachedDocument(self._id, self.title, self.document_file_id) - c = telegram.InlineQueryResultCachedDocument(self._id, self.title, "") - d = telegram.InlineQueryResultCachedDocument("", self.title, self.document_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedDocument(self.id, self.title, self.document_file_id) + b = InlineQueryResultCachedDocument(self.id, self.title, self.document_file_id) + c = InlineQueryResultCachedDocument(self.id, self.title, '') + d = InlineQueryResultCachedDocument('', self.title, self.document_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index c054dd33a..cf49a0959 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -5,95 +5,85 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedGif""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultCachedVoice, + InlineKeyboardMarkup, InlineQueryResultCachedGif) -class InlineQueryResultCachedGifTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultCachedGif.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_gif(): + return InlineQueryResultCachedGif(TestInlineQueryResultCachedGif.id, + TestInlineQueryResultCachedGif.gif_file_id, + title=TestInlineQueryResultCachedGif.title, + caption=TestInlineQueryResultCachedGif.caption, + input_message_content=TestInlineQueryResultCachedGif.input_message_content, + reply_markup=TestInlineQueryResultCachedGif.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'gif' - self.gif_file_id = 'gif file id' - self.title = 'title' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'gif_file_id': self.gif_file_id, - 'title': self.title, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedGif(object): + id = 'id' + type = 'gif' + gif_file_id = 'gif file id' + title = 'title' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_gif_de_json(self): - gif = telegram.InlineQueryResultCachedGif.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_gif): + assert inline_query_result_cached_gif.type == self.type + assert inline_query_result_cached_gif.id == self.id + assert inline_query_result_cached_gif.gif_file_id == self.gif_file_id + assert inline_query_result_cached_gif.title == self.title + assert inline_query_result_cached_gif.caption == self.caption + assert inline_query_result_cached_gif.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_gif.reply_markup.to_dict() == self.reply_markup.to_dict() - self.assertEqual(gif.type, self.type) - self.assertEqual(gif.id, self._id) - self.assertEqual(gif.gif_file_id, self.gif_file_id) - self.assertEqual(gif.title, self.title) - self.assertEqual(gif.caption, self.caption) - self.assertDictEqual(gif.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(gif.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_gif): + inline_query_result_cached_gif_dict = inline_query_result_cached_gif.to_dict() - def test_gif_to_json(self): - gif = telegram.InlineQueryResultCachedGif.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(gif.to_json())) - - def test_gif_to_dict(self): - gif = telegram.InlineQueryResultCachedGif.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(gif)) - self.assertDictEqual(self.json_dict, gif) + assert isinstance(inline_query_result_cached_gif_dict, dict) + assert inline_query_result_cached_gif_dict['type'] == inline_query_result_cached_gif.type + assert inline_query_result_cached_gif_dict['id'] == inline_query_result_cached_gif.id + assert inline_query_result_cached_gif_dict['gif_file_id'] == \ + inline_query_result_cached_gif.gif_file_id + assert inline_query_result_cached_gif_dict['title'] == inline_query_result_cached_gif.title + assert inline_query_result_cached_gif_dict['caption'] == \ + inline_query_result_cached_gif.caption + assert inline_query_result_cached_gif_dict['input_message_content'] == \ + inline_query_result_cached_gif.input_message_content.to_dict() + assert inline_query_result_cached_gif_dict['reply_markup'] == \ + inline_query_result_cached_gif.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedGif(self._id, self.gif_file_id) - b = telegram.InlineQueryResultCachedGif(self._id, self.gif_file_id) - c = telegram.InlineQueryResultCachedGif(self._id, "") - d = telegram.InlineQueryResultCachedGif("", self.gif_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedGif(self.id, self.gif_file_id) + b = InlineQueryResultCachedGif(self.id, self.gif_file_id) + c = InlineQueryResultCachedGif(self.id, '') + d = InlineQueryResultCachedGif('', self.gif_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index def2d4153..dff3b13bd 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -5,97 +5,89 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedMpeg4Gif""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultCachedMpeg4Gif, InlineKeyboardButton, + InputTextMessageContent, InlineKeyboardMarkup, InlineQueryResultCachedVoice) -class InlineQueryResultCachedMpeg4GifTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedMpeg4Gif.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_mpeg4_gif(): + return InlineQueryResultCachedMpeg4Gif(TestInlineQueryResultCachedMpeg4Gif.id, + TestInlineQueryResultCachedMpeg4Gif.mpeg4_file_id, + title=TestInlineQueryResultCachedMpeg4Gif.title, + caption=TestInlineQueryResultCachedMpeg4Gif.caption, + input_message_content=TestInlineQueryResultCachedMpeg4Gif.input_message_content, + reply_markup=TestInlineQueryResultCachedMpeg4Gif.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'mpeg4_gif' - self.mpeg4_file_id = 'mpeg4 file id' - self.title = 'title' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'mpeg4_file_id': self.mpeg4_file_id, - 'title': self.title, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedMpeg4Gif(object): + id = 'id' + type = 'mpeg4_gif' + mpeg4_file_id = 'mpeg4 file id' + title = 'title' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_mpeg4_de_json(self): - mpeg4 = telegram.InlineQueryResultCachedMpeg4Gif.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_mpeg4_gif): + assert inline_query_result_cached_mpeg4_gif.type == self.type + assert inline_query_result_cached_mpeg4_gif.id == self.id + assert inline_query_result_cached_mpeg4_gif.mpeg4_file_id == self.mpeg4_file_id + assert inline_query_result_cached_mpeg4_gif.title == self.title + assert inline_query_result_cached_mpeg4_gif.caption == self.caption + assert inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(mpeg4.type, self.type) - self.assertEqual(mpeg4.id, self._id) - self.assertEqual(mpeg4.mpeg4_file_id, self.mpeg4_file_id) - self.assertEqual(mpeg4.title, self.title) - self.assertEqual(mpeg4.caption, self.caption) - self.assertDictEqual(mpeg4.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(mpeg4.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_mpeg4_gif): + inline_query_result_cached_mpeg4_gif_dict = inline_query_result_cached_mpeg4_gif.to_dict() - def test_mpeg4_to_json(self): - mpeg4 = telegram.InlineQueryResultCachedMpeg4Gif.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(mpeg4.to_json())) - - def test_mpeg4_to_dict(self): - mpeg4 = telegram.InlineQueryResultCachedMpeg4Gif.de_json(self.json_dict, - self._bot).to_dict() - - self.assertTrue(self.is_dict(mpeg4)) - self.assertDictEqual(self.json_dict, mpeg4) + assert isinstance(inline_query_result_cached_mpeg4_gif_dict, dict) + assert inline_query_result_cached_mpeg4_gif_dict['type'] == \ + inline_query_result_cached_mpeg4_gif.type + assert inline_query_result_cached_mpeg4_gif_dict['id'] == \ + inline_query_result_cached_mpeg4_gif.id + assert inline_query_result_cached_mpeg4_gif_dict['mpeg4_file_id'] == \ + inline_query_result_cached_mpeg4_gif.mpeg4_file_id + assert inline_query_result_cached_mpeg4_gif_dict['title'] == \ + inline_query_result_cached_mpeg4_gif.title + assert inline_query_result_cached_mpeg4_gif_dict['caption'] == \ + inline_query_result_cached_mpeg4_gif.caption + assert inline_query_result_cached_mpeg4_gif_dict['input_message_content'] == \ + inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() + assert inline_query_result_cached_mpeg4_gif_dict['reply_markup'] == \ + inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedMpeg4Gif(self._id, self.mpeg4_file_id) - b = telegram.InlineQueryResultCachedMpeg4Gif(self._id, self.mpeg4_file_id) - c = telegram.InlineQueryResultCachedMpeg4Gif(self._id, "") - d = telegram.InlineQueryResultCachedMpeg4Gif("", self.mpeg4_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedMpeg4Gif(self.id, self.mpeg4_file_id) + b = InlineQueryResultCachedMpeg4Gif(self.id, self.mpeg4_file_id) + c = InlineQueryResultCachedMpeg4Gif(self.id, '') + d = InlineQueryResultCachedMpeg4Gif('', self.mpeg4_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index a6872f741..a481a95e6 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -5,99 +5,93 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedPhoto""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InputTextMessageContent, InlineQueryResultCachedPhoto, InlineKeyboardButton, + InlineQueryResultCachedVoice, InlineKeyboardMarkup) -class InlineQueryResultCachedPhotoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedPhoto.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_photo(): + return InlineQueryResultCachedPhoto(TestInlineQueryResultCachedPhoto.id, + TestInlineQueryResultCachedPhoto.photo_file_id, + title=TestInlineQueryResultCachedPhoto.title, + description=TestInlineQueryResultCachedPhoto.description, + caption=TestInlineQueryResultCachedPhoto.caption, + input_message_content=TestInlineQueryResultCachedPhoto.input_message_content, + reply_markup=TestInlineQueryResultCachedPhoto.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'photo' - self.photo_file_id = 'photo file id' - self.title = 'title' - self.description = 'description' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'photo_file_id': self.photo_file_id, - 'title': self.title, - 'description': self.description, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedPhoto(object): + id = 'id' + type = 'photo' + photo_file_id = 'photo file id' + title = 'title' + description = 'description' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_photo_de_json(self): - photo = telegram.InlineQueryResultCachedPhoto.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_photo): + assert inline_query_result_cached_photo.type == self.type + assert inline_query_result_cached_photo.id == self.id + assert inline_query_result_cached_photo.photo_file_id == self.photo_file_id + assert inline_query_result_cached_photo.title == self.title + assert inline_query_result_cached_photo.description == self.description + assert inline_query_result_cached_photo.caption == self.caption + assert inline_query_result_cached_photo.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_photo.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(photo.type, self.type) - self.assertEqual(photo.id, self._id) - self.assertEqual(photo.photo_file_id, self.photo_file_id) - self.assertEqual(photo.title, self.title) - self.assertEqual(photo.description, self.description) - self.assertEqual(photo.caption, self.caption) - self.assertDictEqual(photo.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(photo.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_photo): + inline_query_result_cached_photo_dict = inline_query_result_cached_photo.to_dict() - def test_photo_to_json(self): - photo = telegram.InlineQueryResultCachedPhoto.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(photo.to_json())) - - def test_photo_to_dict(self): - photo = telegram.InlineQueryResultCachedPhoto.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(photo)) - self.assertDictEqual(self.json_dict, photo) + assert isinstance(inline_query_result_cached_photo_dict, dict) + assert inline_query_result_cached_photo_dict['type'] == \ + inline_query_result_cached_photo.type + assert inline_query_result_cached_photo_dict['id'] == inline_query_result_cached_photo.id + assert inline_query_result_cached_photo_dict['photo_file_id'] == \ + inline_query_result_cached_photo.photo_file_id + assert inline_query_result_cached_photo_dict['title'] == \ + inline_query_result_cached_photo.title + assert inline_query_result_cached_photo_dict['description'] == \ + inline_query_result_cached_photo.description + assert inline_query_result_cached_photo_dict['caption'] == \ + inline_query_result_cached_photo.caption + assert inline_query_result_cached_photo_dict['input_message_content'] == \ + inline_query_result_cached_photo.input_message_content.to_dict() + assert inline_query_result_cached_photo_dict['reply_markup'] == \ + inline_query_result_cached_photo.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedPhoto(self._id, self.photo_file_id) - b = telegram.InlineQueryResultCachedPhoto(self._id, self.photo_file_id) - c = telegram.InlineQueryResultCachedPhoto(self._id, "") - d = telegram.InlineQueryResultCachedPhoto("", self.photo_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedPhoto(self.id, self.photo_file_id) + b = InlineQueryResultCachedPhoto(self.id, self.photo_file_id) + c = InlineQueryResultCachedPhoto(self.id, '') + d = InlineQueryResultCachedPhoto('', self.photo_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index a8696fcb1..85c056687 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -5,91 +5,80 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedSticker""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InputTextMessageContent, InlineKeyboardButton, + InlineQueryResultCachedSticker, InlineQueryResultCachedVoice, + InlineKeyboardMarkup) -class InlineQueryResultCachedStickerTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedSticker.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_sticker(): + return InlineQueryResultCachedSticker(TestInlineQueryResultCachedSticker.id, + TestInlineQueryResultCachedSticker.sticker_file_id, + input_message_content=TestInlineQueryResultCachedSticker.input_message_content, + reply_markup=TestInlineQueryResultCachedSticker.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'sticker' - self.sticker_file_id = 'sticker file id' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'sticker_file_id': self.sticker_file_id, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedSticker(object): + id = 'id' + type = 'sticker' + sticker_file_id = 'sticker file id' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_sticker_de_json(self): - sticker = telegram.InlineQueryResultCachedSticker.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_sticker): + assert inline_query_result_cached_sticker.type == self.type + assert inline_query_result_cached_sticker.id == self.id + assert inline_query_result_cached_sticker.sticker_file_id == self.sticker_file_id + assert inline_query_result_cached_sticker.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_sticker.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(sticker.type, self.type) - self.assertEqual(sticker.id, self._id) - self.assertEqual(sticker.sticker_file_id, self.sticker_file_id) - self.assertDictEqual(sticker.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(sticker.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_sticker): + inline_query_result_cached_sticker_dict = inline_query_result_cached_sticker.to_dict() - def test_sticker_to_json(self): - sticker = telegram.InlineQueryResultCachedSticker.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(sticker.to_json())) - - def test_sticker_to_dict(self): - sticker = telegram.InlineQueryResultCachedSticker.de_json(self.json_dict, - self._bot).to_dict() - - self.assertTrue(self.is_dict(sticker)) - self.assertDictEqual(self.json_dict, sticker) + assert isinstance(inline_query_result_cached_sticker_dict, dict) + assert inline_query_result_cached_sticker_dict['type'] == \ + inline_query_result_cached_sticker.type + assert inline_query_result_cached_sticker_dict['id'] == \ + inline_query_result_cached_sticker.id + assert inline_query_result_cached_sticker_dict['sticker_file_id'] == \ + inline_query_result_cached_sticker.sticker_file_id + assert inline_query_result_cached_sticker_dict['input_message_content'] == \ + inline_query_result_cached_sticker.input_message_content.to_dict() + assert inline_query_result_cached_sticker_dict['reply_markup'] == \ + inline_query_result_cached_sticker.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedSticker(self._id, self.sticker_file_id) - b = telegram.InlineQueryResultCachedSticker(self._id, self.sticker_file_id) - c = telegram.InlineQueryResultCachedSticker(self._id, "") - d = telegram.InlineQueryResultCachedSticker("", self.sticker_file_id) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedSticker(self.id, self.sticker_file_id) + b = InlineQueryResultCachedSticker(self.id, self.sticker_file_id) + c = InlineQueryResultCachedSticker(self.id, '') + d = InlineQueryResultCachedSticker('', self.sticker_file_id) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index 0f676fa46..cf63fb0df 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -5,99 +5,93 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedVideo""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardMarkup, InlineKeyboardButton, InputTextMessageContent, + InlineQueryResultCachedVideo, InlineQueryResultCachedVoice) -class InlineQueryResultCachedVideoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedVideo.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_video(): + return InlineQueryResultCachedVideo(TestInlineQueryResultCachedVideo.id, + TestInlineQueryResultCachedVideo.video_file_id, + TestInlineQueryResultCachedVideo.title, + caption=TestInlineQueryResultCachedVideo.caption, + description=TestInlineQueryResultCachedVideo.description, + input_message_content=TestInlineQueryResultCachedVideo.input_message_content, + reply_markup=TestInlineQueryResultCachedVideo.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'video' - self.video_file_id = 'video file id' - self.title = 'title' - self.caption = 'caption' - self.description = 'description' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'video_file_id': self.video_file_id, - 'title': self.title, - 'caption': self.caption, - 'description': self.description, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedVideo(object): + id = 'id' + type = 'video' + video_file_id = 'video file id' + title = 'title' + caption = 'caption' + description = 'description' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_video_de_json(self): - video = telegram.InlineQueryResultCachedVideo.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_video): + assert inline_query_result_cached_video.type == self.type + assert inline_query_result_cached_video.id == self.id + assert inline_query_result_cached_video.video_file_id == self.video_file_id + assert inline_query_result_cached_video.title == self.title + assert inline_query_result_cached_video.description == self.description + assert inline_query_result_cached_video.caption == self.caption + assert inline_query_result_cached_video.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_video.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(video.type, self.type) - self.assertEqual(video.id, self._id) - self.assertEqual(video.video_file_id, self.video_file_id) - self.assertEqual(video.title, self.title) - self.assertEqual(video.description, self.description) - self.assertEqual(video.caption, self.caption) - self.assertDictEqual(video.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(video.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_video): + inline_query_result_cached_video_dict = inline_query_result_cached_video.to_dict() - def test_video_to_json(self): - video = telegram.InlineQueryResultCachedVideo.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(video.to_json())) - - def test_video_to_dict(self): - video = telegram.InlineQueryResultCachedVideo.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(video)) - self.assertDictEqual(self.json_dict, video) + assert isinstance(inline_query_result_cached_video_dict, dict) + assert inline_query_result_cached_video_dict['type'] == \ + inline_query_result_cached_video.type + assert inline_query_result_cached_video_dict['id'] == inline_query_result_cached_video.id + assert inline_query_result_cached_video_dict['video_file_id'] == \ + inline_query_result_cached_video.video_file_id + assert inline_query_result_cached_video_dict['title'] == \ + inline_query_result_cached_video.title + assert inline_query_result_cached_video_dict['description'] == \ + inline_query_result_cached_video.description + assert inline_query_result_cached_video_dict['caption'] == \ + inline_query_result_cached_video.caption + assert inline_query_result_cached_video_dict['input_message_content'] == \ + inline_query_result_cached_video.input_message_content.to_dict() + assert inline_query_result_cached_video_dict['reply_markup'] == \ + inline_query_result_cached_video.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedVideo(self._id, self.video_file_id, self.title) - b = telegram.InlineQueryResultCachedVideo(self._id, self.video_file_id, self.title) - c = telegram.InlineQueryResultCachedVideo(self._id, "", self.title) - d = telegram.InlineQueryResultCachedVideo("", self.video_file_id, self.title) - e = telegram.InlineQueryResultCachedVoice(self._id, "", "") + a = InlineQueryResultCachedVideo(self.id, self.video_file_id, self.title) + b = InlineQueryResultCachedVideo(self.id, self.video_file_id, self.title) + c = InlineQueryResultCachedVideo(self.id, '', self.title) + d = InlineQueryResultCachedVideo('', self.video_file_id, self.title) + e = InlineQueryResultCachedVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index 9f099a4cb..7a997354b 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -5,96 +5,88 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultCachedVoice""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultCachedVoice, InlineKeyboardButton, InlineKeyboardMarkup, + InlineQueryResultCachedAudio, InputTextMessageContent) -class InlineQueryResultCachedVoiceTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram - InlineQueryResultCachedVoice.""" +@pytest.fixture(scope='class') +def inline_query_result_cached_voice(): + return InlineQueryResultCachedVoice(TestInlineQueryResultCachedVoice.id, + TestInlineQueryResultCachedVoice.voice_file_id, + TestInlineQueryResultCachedVoice.title, + caption=TestInlineQueryResultCachedVoice.caption, + input_message_content=TestInlineQueryResultCachedVoice.input_message_content, + reply_markup=TestInlineQueryResultCachedVoice.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'voice' - self.voice_file_id = 'voice file id' - self.title = 'title' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'voice_file_id': self.voice_file_id, - 'title': self.title, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultCachedVoice(object): + id = 'id' + type = 'voice' + voice_file_id = 'voice file id' + title = 'title' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_voice_de_json(self): - voice = telegram.InlineQueryResultCachedVoice.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_cached_voice): + assert inline_query_result_cached_voice.type == self.type + assert inline_query_result_cached_voice.id == self.id + assert inline_query_result_cached_voice.voice_file_id == self.voice_file_id + assert inline_query_result_cached_voice.title == self.title + assert inline_query_result_cached_voice.caption == self.caption + assert inline_query_result_cached_voice.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_cached_voice.reply_markup.to_dict() == \ + self.reply_markup.to_dict() - self.assertEqual(voice.type, self.type) - self.assertEqual(voice.id, self._id) - self.assertEqual(voice.voice_file_id, self.voice_file_id) - self.assertEqual(voice.title, self.title) - self.assertEqual(voice.caption, self.caption) - self.assertDictEqual(voice.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(voice.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_cached_voice): + inline_query_result_cached_voice_dict = inline_query_result_cached_voice.to_dict() - def test_voice_to_json(self): - voice = telegram.InlineQueryResultCachedVoice.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(voice.to_json())) - - def test_voice_to_dict(self): - voice = telegram.InlineQueryResultCachedVoice.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(voice)) - self.assertDictEqual(self.json_dict, voice) + assert isinstance(inline_query_result_cached_voice_dict, dict) + assert inline_query_result_cached_voice_dict['type'] == \ + inline_query_result_cached_voice.type + assert inline_query_result_cached_voice_dict['id'] == inline_query_result_cached_voice.id + assert inline_query_result_cached_voice_dict['voice_file_id'] == \ + inline_query_result_cached_voice.voice_file_id + assert inline_query_result_cached_voice_dict['title'] == \ + inline_query_result_cached_voice.title + assert inline_query_result_cached_voice_dict['caption'] == \ + inline_query_result_cached_voice.caption + assert inline_query_result_cached_voice_dict['input_message_content'] == \ + inline_query_result_cached_voice.input_message_content.to_dict() + assert inline_query_result_cached_voice_dict['reply_markup'] == \ + inline_query_result_cached_voice.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultCachedVoice(self._id, self.voice_file_id, self.title) - b = telegram.InlineQueryResultCachedVoice(self._id, self.voice_file_id, self.title) - c = telegram.InlineQueryResultCachedVoice(self._id, "", self.title) - d = telegram.InlineQueryResultCachedVoice("", self.voice_file_id, self.title) - e = telegram.InlineQueryResultCachedAudio(self._id, "", "") + a = InlineQueryResultCachedVoice(self.id, self.voice_file_id, self.title) + b = InlineQueryResultCachedVoice(self.id, self.voice_file_id, self.title) + c = InlineQueryResultCachedVoice(self.id, '', self.title) + d = InlineQueryResultCachedVoice('', self.voice_file_id, self.title) + e = InlineQueryResultCachedAudio(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index 572981158..395fb0437 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -5,103 +5,101 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultContact""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultVoice, InputTextMessageContent, InlineKeyboardButton, + InlineKeyboardMarkup, InlineQueryResultContact) -class InlineQueryResultContactTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultContact.""" +@pytest.fixture(scope='class') +def inline_query_result_contact(): + return InlineQueryResultContact(TestInlineQueryResultContact.id, + TestInlineQueryResultContact.phone_number, + TestInlineQueryResultContact.first_name, + last_name=TestInlineQueryResultContact.last_name, + thumb_url=TestInlineQueryResultContact.thumb_url, + thumb_width=TestInlineQueryResultContact.thumb_width, + thumb_height=TestInlineQueryResultContact.thumb_height, + input_message_content=TestInlineQueryResultContact.input_message_content, + reply_markup=TestInlineQueryResultContact.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'contact' - self.phone_number = 'phone_number' - self.first_name = 'first_name' - self.last_name = 'last_name' - self.thumb_url = 'thumb url' - self.thumb_width = 10 - self.thumb_height = 15 - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'id': self._id, - 'type': self.type, - 'phone_number': self.phone_number, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'thumb_url': self.thumb_url, - 'thumb_width': self.thumb_width, - 'thumb_height': self.thumb_height, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } - def test_contact_de_json(self): - contact = telegram.InlineQueryResultContact.de_json(self.json_dict, self._bot) +class TestInlineQueryResultContact(object): + id = 'id' + type = 'contact' + phone_number = 'phone_number' + first_name = 'first_name' + last_name = 'last_name' + thumb_url = 'thumb url' + thumb_width = 10 + thumb_height = 15 + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - self.assertEqual(contact.id, self._id) - self.assertEqual(contact.type, self.type) - self.assertEqual(contact.phone_number, self.phone_number) - self.assertEqual(contact.first_name, self.first_name) - self.assertEqual(contact.last_name, self.last_name) - self.assertEqual(contact.thumb_url, self.thumb_url) - self.assertEqual(contact.thumb_width, self.thumb_width) - self.assertEqual(contact.thumb_height, self.thumb_height) - self.assertDictEqual(contact.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(contact.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_expected_values(self, inline_query_result_contact): + assert inline_query_result_contact.id == self.id + assert inline_query_result_contact.type == self.type + assert inline_query_result_contact.phone_number == self.phone_number + assert inline_query_result_contact.first_name == self.first_name + assert inline_query_result_contact.last_name == self.last_name + assert inline_query_result_contact.thumb_url == self.thumb_url + assert inline_query_result_contact.thumb_width == self.thumb_width + assert inline_query_result_contact.thumb_height == self.thumb_height + assert inline_query_result_contact.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_contact.reply_markup.to_dict() == self.reply_markup.to_dict() - def test_contact_to_json(self): - contact = telegram.InlineQueryResultContact.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_query_result_contact): + inline_query_result_contact_dict = inline_query_result_contact.to_dict() - self.assertTrue(self.is_json(contact.to_json())) - - def test_contact_to_dict(self): - contact = telegram.InlineQueryResultContact.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(contact)) - self.assertDictEqual(self.json_dict, contact) + assert isinstance(inline_query_result_contact_dict, dict) + assert inline_query_result_contact_dict['id'] == inline_query_result_contact.id + assert inline_query_result_contact_dict['type'] == inline_query_result_contact.type + assert inline_query_result_contact_dict['phone_number'] == \ + inline_query_result_contact.phone_number + assert inline_query_result_contact_dict['first_name'] == \ + inline_query_result_contact.first_name + assert inline_query_result_contact_dict['last_name'] == \ + inline_query_result_contact.last_name + assert inline_query_result_contact_dict['thumb_url'] == \ + inline_query_result_contact.thumb_url + assert inline_query_result_contact_dict['thumb_width'] == \ + inline_query_result_contact.thumb_width + assert inline_query_result_contact_dict['thumb_height'] == \ + inline_query_result_contact.thumb_height + assert inline_query_result_contact_dict['input_message_content'] == \ + inline_query_result_contact.input_message_content.to_dict() + assert inline_query_result_contact_dict['reply_markup'] == \ + inline_query_result_contact.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultContact(self._id, self.phone_number, self.first_name) - b = telegram.InlineQueryResultContact(self._id, self.phone_number, self.first_name) - c = telegram.InlineQueryResultContact(self._id, "", self.first_name) - d = telegram.InlineQueryResultContact("", self.phone_number, self.first_name) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultContact(self.id, self.phone_number, self.first_name) + b = InlineQueryResultContact(self.id, self.phone_number, self.first_name) + c = InlineQueryResultContact(self.id, '', self.first_name) + d = InlineQueryResultContact('', self.phone_number, self.first_name) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index df2b7b91a..dd03a91fb 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -5,111 +5,111 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultDocument""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultDocument, + InlineKeyboardMarkup, InlineQueryResultVoice) -class InlineQueryResultDocumentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultDocument.""" +@pytest.fixture(scope='class') +def inline_query_result_document(): + return InlineQueryResultDocument(TestInlineQueryResultDocument.id, + TestInlineQueryResultDocument.document_url, + TestInlineQueryResultDocument.title, + TestInlineQueryResultDocument.mime_type, + caption=TestInlineQueryResultDocument.caption, + description=TestInlineQueryResultDocument.description, + thumb_url=TestInlineQueryResultDocument.thumb_url, + thumb_width=TestInlineQueryResultDocument.thumb_width, + thumb_height=TestInlineQueryResultDocument.thumb_height, + input_message_content=TestInlineQueryResultDocument.input_message_content, + reply_markup=TestInlineQueryResultDocument.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'document' - self.document_url = 'document url' - self.title = 'title' - self.caption = 'caption' - self.mime_type = 'mime type' - self.description = 'description' - self.thumb_url = 'thumb url' - self.thumb_width = 10 - self.thumb_height = 15 - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'id': self._id, - 'type': self.type, - 'document_url': self.document_url, - 'title': self.title, - 'caption': self.caption, - 'mime_type': self.mime_type, - 'description': self.description, - 'thumb_url': self.thumb_url, - 'thumb_width': self.thumb_width, - 'thumb_height': self.thumb_height, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } - def test_document_de_json(self): - document = telegram.InlineQueryResultDocument.de_json(self.json_dict, self._bot) +class TestInlineQueryResultDocument(object): + id = 'id' + type = 'document' + document_url = 'document url' + title = 'title' + caption = 'caption' + mime_type = 'mime type' + description = 'description' + thumb_url = 'thumb url' + thumb_width = 10 + thumb_height = 15 + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - self.assertEqual(document.id, self._id) - self.assertEqual(document.type, self.type) - self.assertEqual(document.document_url, self.document_url) - self.assertEqual(document.title, self.title) - self.assertEqual(document.caption, self.caption) - self.assertEqual(document.mime_type, self.mime_type) - self.assertEqual(document.description, self.description) - self.assertEqual(document.thumb_url, self.thumb_url) - self.assertEqual(document.thumb_width, self.thumb_width) - self.assertEqual(document.thumb_height, self.thumb_height) - self.assertDictEqual(document.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(document.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_expected_values(self, inline_query_result_document): + assert inline_query_result_document.id == self.id + assert inline_query_result_document.type == self.type + assert inline_query_result_document.document_url == self.document_url + assert inline_query_result_document.title == self.title + assert inline_query_result_document.caption == self.caption + assert inline_query_result_document.mime_type == self.mime_type + assert inline_query_result_document.description == self.description + assert inline_query_result_document.thumb_url == self.thumb_url + assert inline_query_result_document.thumb_width == self.thumb_width + assert inline_query_result_document.thumb_height == self.thumb_height + assert inline_query_result_document.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_document.reply_markup.to_dict() == self.reply_markup.to_dict() - def test_document_to_json(self): - document = telegram.InlineQueryResultDocument.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_query_result_document): + inline_query_result_document_dict = inline_query_result_document.to_dict() - self.assertTrue(self.is_json(document.to_json())) - - def test_document_to_dict(self): - document = telegram.InlineQueryResultDocument.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(document)) - self.assertDictEqual(self.json_dict, document) + assert isinstance(inline_query_result_document_dict, dict) + assert inline_query_result_document_dict['id'] == inline_query_result_document.id + assert inline_query_result_document_dict['type'] == inline_query_result_document.type + assert inline_query_result_document_dict['document_url'] == \ + inline_query_result_document.document_url + assert inline_query_result_document_dict['title'] == inline_query_result_document.title + assert inline_query_result_document_dict['caption'] == inline_query_result_document.caption + assert inline_query_result_document_dict['mime_type'] == \ + inline_query_result_document.mime_type + assert inline_query_result_document_dict['description'] == \ + inline_query_result_document.description + assert inline_query_result_document_dict['thumb_url'] == \ + inline_query_result_document.thumb_url + assert inline_query_result_document_dict['thumb_width'] == \ + inline_query_result_document.thumb_width + assert inline_query_result_document_dict['thumb_height'] == \ + inline_query_result_document.thumb_height + assert inline_query_result_document_dict['input_message_content'] == \ + inline_query_result_document.input_message_content.to_dict() + assert inline_query_result_document_dict['reply_markup'] == \ + inline_query_result_document.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultDocument(self._id, self.document_url, self.title, - self.mime_type) - b = telegram.InlineQueryResultDocument(self._id, self.document_url, self.title, - self.mime_type) - c = telegram.InlineQueryResultDocument(self._id, "", self.title, self.mime_type) - d = telegram.InlineQueryResultDocument("", self.document_url, self.title, self.mime_type) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultDocument(self.id, self.document_url, self.title, + self.mime_type) + b = InlineQueryResultDocument(self.id, self.document_url, self.title, + self.mime_type) + c = InlineQueryResultDocument(self.id, '', self.title, self.mime_type) + d = InlineQueryResultDocument('', self.document_url, self.title, self.mime_type) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py new file mode 100644 index 000000000..026e591c9 --- /dev/null +++ b/tests/test_inlinequeryresultgame.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (InlineKeyboardButton, InlineQueryResultGame, + InlineQueryResultVoice, InlineKeyboardMarkup) + + +@pytest.fixture(scope='class') +def inline_query_result_game(): + return InlineQueryResultGame(TestInlineQueryResultGame.id, + TestInlineQueryResultGame.game_short_name, + reply_markup=TestInlineQueryResultGame.reply_markup) + + +class TestInlineQueryResultGame(object): + id = 'id' + type = 'game' + game_short_name = 'game short name' + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) + + def test_expected_values(self, inline_query_result_game): + assert inline_query_result_game.type == self.type + assert inline_query_result_game.id == self.id + assert inline_query_result_game.game_short_name == self.game_short_name + assert inline_query_result_game.reply_markup.to_dict() == \ + self.reply_markup.to_dict() + + def test_to_dict(self, inline_query_result_game): + inline_query_result_game_dict = inline_query_result_game.to_dict() + + assert isinstance(inline_query_result_game_dict, dict) + assert inline_query_result_game_dict['type'] == inline_query_result_game.type + assert inline_query_result_game_dict['id'] == inline_query_result_game.id + assert inline_query_result_game_dict['game_short_name'] == \ + inline_query_result_game.game_short_name + assert inline_query_result_game_dict['reply_markup'] == \ + inline_query_result_game.reply_markup.to_dict() + + def test_equality(self): + a = InlineQueryResultGame(self.id, self.game_short_name) + b = InlineQueryResultGame(self.id, self.game_short_name) + c = InlineQueryResultGame(self.id, '') + d = InlineQueryResultGame('', self.game_short_name) + e = InlineQueryResultVoice(self.id, '', '') + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 4c7cf82c1..678406a0d 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -5,107 +5,99 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultGif""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultGif, + InlineQueryResultVoice, InlineKeyboardMarkup) -class InlineQueryResultGifTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultGif.""" +@pytest.fixture(scope='class') +def inline_query_result_gif(): + return InlineQueryResultGif(TestInlineQueryResultGif.id, + TestInlineQueryResultGif.gif_url, + TestInlineQueryResultGif.thumb_url, + gif_width=TestInlineQueryResultGif.gif_width, + gif_height=TestInlineQueryResultGif.gif_height, + gif_duration=TestInlineQueryResultGif.gif_duration, + title=TestInlineQueryResultGif.title, + caption=TestInlineQueryResultGif.caption, + input_message_content=TestInlineQueryResultGif.input_message_content, + reply_markup=TestInlineQueryResultGif.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'gif' - self.gif_url = 'gif url' - self.gif_width = 10 - self.gif_height = 15 - self.gif_duration = 1 - self.thumb_url = 'thumb url' - self.title = 'title' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'gif_url': self.gif_url, - 'gif_width': self.gif_width, - 'gif_height': self.gif_height, - 'gif_duration': self.gif_duration, - 'thumb_url': self.thumb_url, - 'title': self.title, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultGif(object): + id = 'id' + type = 'gif' + gif_url = 'gif url' + gif_width = 10 + gif_height = 15 + gif_duration = 1 + thumb_url = 'thumb url' + title = 'title' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_gif_de_json(self): - gif = telegram.InlineQueryResultGif.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_gif): + assert inline_query_result_gif.type == self.type + assert inline_query_result_gif.id == self.id + assert inline_query_result_gif.gif_url == self.gif_url + assert inline_query_result_gif.gif_width == self.gif_width + assert inline_query_result_gif.gif_height == self.gif_height + assert inline_query_result_gif.gif_duration == self.gif_duration + assert inline_query_result_gif.thumb_url == self.thumb_url + assert inline_query_result_gif.title == self.title + assert inline_query_result_gif.caption == self.caption + assert inline_query_result_gif.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_gif.reply_markup.to_dict() == self.reply_markup.to_dict() - 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) - self.assertEqual(gif.gif_height, self.gif_height) - self.assertEqual(gif.gif_duration, self.gif_duration) - self.assertEqual(gif.thumb_url, self.thumb_url) - self.assertEqual(gif.title, self.title) - self.assertEqual(gif.caption, self.caption) - self.assertDictEqual(gif.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(gif.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_gif): + inline_query_result_gif_dict = inline_query_result_gif.to_dict() - def test_gif_to_json(self): - gif = telegram.InlineQueryResultGif.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(gif.to_json())) - - def test_gif_to_dict(self): - gif = telegram.InlineQueryResultGif.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(gif)) - self.assertDictEqual(self.json_dict, gif) + assert isinstance(inline_query_result_gif_dict, dict) + assert inline_query_result_gif_dict['type'] == inline_query_result_gif.type + assert inline_query_result_gif_dict['id'] == inline_query_result_gif.id + assert inline_query_result_gif_dict['gif_url'] == inline_query_result_gif.gif_url + assert inline_query_result_gif_dict['gif_width'] == inline_query_result_gif.gif_width + assert inline_query_result_gif_dict['gif_height'] == inline_query_result_gif.gif_height + assert inline_query_result_gif_dict['gif_duration'] == inline_query_result_gif.gif_duration + assert inline_query_result_gif_dict['thumb_url'] == inline_query_result_gif.thumb_url + assert inline_query_result_gif_dict['title'] == inline_query_result_gif.title + assert inline_query_result_gif_dict['caption'] == inline_query_result_gif.caption + assert inline_query_result_gif_dict['input_message_content'] == \ + inline_query_result_gif.input_message_content.to_dict() + assert inline_query_result_gif_dict['reply_markup'] == \ + inline_query_result_gif.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultGif(self._id, self.gif_url, self.thumb_url) - b = telegram.InlineQueryResultGif(self._id, self.gif_url, self.thumb_url) - c = telegram.InlineQueryResultGif(self._id, "", self.thumb_url) - d = telegram.InlineQueryResultGif("", self.gif_url, self.thumb_url) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultGif(self.id, self.gif_url, self.thumb_url) + b = InlineQueryResultGif(self.id, self.gif_url, self.thumb_url) + c = InlineQueryResultGif(self.id, '', self.thumb_url) + d = InlineQueryResultGif('', self.gif_url, self.thumb_url) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 16a5cd6b7..f3ededca7 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -5,103 +5,100 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultLocation""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InputTextMessageContent, InlineQueryResultLocation, InlineKeyboardButton, + InlineQueryResultVoice, InlineKeyboardMarkup) -class InlineQueryResultLocationTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultLocation.""" +@pytest.fixture(scope='class') +def inline_query_result_location(): + return InlineQueryResultLocation(TestInlineQueryResultLocation.id, + TestInlineQueryResultLocation.latitude, + TestInlineQueryResultLocation.longitude, + TestInlineQueryResultLocation.title, + thumb_url=TestInlineQueryResultLocation.thumb_url, + thumb_width=TestInlineQueryResultLocation.thumb_width, + thumb_height=TestInlineQueryResultLocation.thumb_height, + input_message_content=TestInlineQueryResultLocation.input_message_content, + reply_markup=TestInlineQueryResultLocation.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'location' - self.latitude = 0.0 - self.longitude = 0.0 - self.title = 'title' - self.thumb_url = 'thumb url' - self.thumb_width = 10 - self.thumb_height = 15 - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'id': self._id, - 'type': self.type, - 'latitude': self.latitude, - 'longitude': self.longitude, - 'title': self.title, - 'thumb_url': self.thumb_url, - 'thumb_width': self.thumb_width, - 'thumb_height': self.thumb_height, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } - def test_location_de_json(self): - location = telegram.InlineQueryResultLocation.de_json(self.json_dict, self._bot) +class TestInlineQueryResultLocation(object): + id = 'id' + type = 'location' + latitude = 0.0 + longitude = 1.0 + title = 'title' + thumb_url = 'thumb url' + thumb_width = 10 + thumb_height = 15 + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - self.assertEqual(location.id, self._id) - self.assertEqual(location.type, self.type) - self.assertEqual(location.latitude, self.latitude) - self.assertEqual(location.longitude, self.longitude) - self.assertEqual(location.title, self.title) - self.assertEqual(location.thumb_url, self.thumb_url) - self.assertEqual(location.thumb_width, self.thumb_width) - self.assertEqual(location.thumb_height, self.thumb_height) - self.assertDictEqual(location.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(location.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_expected_values(self, inline_query_result_location): + assert inline_query_result_location.id == self.id + assert inline_query_result_location.type == self.type + assert inline_query_result_location.latitude == self.latitude + assert inline_query_result_location.longitude == self.longitude + assert inline_query_result_location.title == self.title + assert inline_query_result_location.thumb_url == self.thumb_url + assert inline_query_result_location.thumb_width == self.thumb_width + assert inline_query_result_location.thumb_height == self.thumb_height + assert inline_query_result_location.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_location.reply_markup.to_dict() == self.reply_markup.to_dict() - def test_location_to_json(self): - location = telegram.InlineQueryResultLocation.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_query_result_location): + inline_query_result_location_dict = inline_query_result_location.to_dict() - self.assertTrue(self.is_json(location.to_json())) - - def test_location_to_dict(self): - location = telegram.InlineQueryResultLocation.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(location)) - self.assertDictEqual(self.json_dict, location) + assert isinstance(inline_query_result_location_dict, dict) + assert inline_query_result_location_dict['id'] == inline_query_result_location.id + assert inline_query_result_location_dict['type'] == inline_query_result_location.type + assert inline_query_result_location_dict['latitude'] == \ + inline_query_result_location.latitude + assert inline_query_result_location_dict['longitude'] == \ + inline_query_result_location.longitude + assert inline_query_result_location_dict['title'] == inline_query_result_location.title + assert inline_query_result_location_dict['thumb_url'] == \ + inline_query_result_location.thumb_url + assert inline_query_result_location_dict['thumb_width'] == \ + inline_query_result_location.thumb_width + assert inline_query_result_location_dict['thumb_height'] == \ + inline_query_result_location.thumb_height + assert inline_query_result_location_dict['input_message_content'] == \ + inline_query_result_location.input_message_content.to_dict() + assert inline_query_result_location_dict['reply_markup'] == \ + inline_query_result_location.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultLocation(self._id, self.longitude, self.latitude, self.title) - b = telegram.InlineQueryResultLocation(self._id, self.longitude, self.latitude, self.title) - c = telegram.InlineQueryResultLocation(self._id, 0, self.latitude, self.title) - d = telegram.InlineQueryResultLocation("", self.longitude, self.latitude, self.title) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultLocation(self.id, self.longitude, self.latitude, self.title) + b = InlineQueryResultLocation(self.id, self.longitude, self.latitude, self.title) + c = InlineQueryResultLocation(self.id, 0, self.latitude, self.title) + d = InlineQueryResultLocation('', self.longitude, self.latitude, self.title) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index a9420f99f..fae52280b 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -5,107 +5,105 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultMpeg4Gif""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultMpeg4Gif, InlineKeyboardButton, InlineQueryResultVoice, + InlineKeyboardMarkup, InputTextMessageContent) -class InlineQueryResultMpeg4GifTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultMpeg4Gif.""" +@pytest.fixture(scope='class') +def inline_query_result_mpeg4_gif(): + return InlineQueryResultMpeg4Gif(TestInlineQueryResultMpeg4Gif.id, + TestInlineQueryResultMpeg4Gif.mpeg4_url, + TestInlineQueryResultMpeg4Gif.thumb_url, + mpeg4_width=TestInlineQueryResultMpeg4Gif.mpeg4_width, + mpeg4_height=TestInlineQueryResultMpeg4Gif.mpeg4_height, + mpeg4_duration=TestInlineQueryResultMpeg4Gif.mpeg4_duration, + title=TestInlineQueryResultMpeg4Gif.title, + caption=TestInlineQueryResultMpeg4Gif.caption, + input_message_content=TestInlineQueryResultMpeg4Gif.input_message_content, + reply_markup=TestInlineQueryResultMpeg4Gif.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'mpeg4_gif' - self.mpeg4_url = 'mpeg4 url' - self.mpeg4_width = 10 - self.mpeg4_height = 15 - self.mpeg4_duration = 1 - self.thumb_url = 'thumb url' - self.title = 'title' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'mpeg4_url': self.mpeg4_url, - 'mpeg4_width': self.mpeg4_width, - 'mpeg4_height': self.mpeg4_height, - 'mpeg4_duration': self.mpeg4_duration, - 'thumb_url': self.thumb_url, - 'title': self.title, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultMpeg4Gif(object): + id = 'id' + type = 'mpeg4_gif' + mpeg4_url = 'mpeg4 url' + mpeg4_width = 10 + mpeg4_height = 15 + mpeg4_duration = 1 + thumb_url = 'thumb url' + title = 'title' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_mpeg4_de_json(self): - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_mpeg4_gif): + assert inline_query_result_mpeg4_gif.type == self.type + assert inline_query_result_mpeg4_gif.id == self.id + assert inline_query_result_mpeg4_gif.mpeg4_url == self.mpeg4_url + assert inline_query_result_mpeg4_gif.mpeg4_width == self.mpeg4_width + assert inline_query_result_mpeg4_gif.mpeg4_height == self.mpeg4_height + assert inline_query_result_mpeg4_gif.mpeg4_duration == self.mpeg4_duration + assert inline_query_result_mpeg4_gif.thumb_url == self.thumb_url + assert inline_query_result_mpeg4_gif.title == self.title + assert inline_query_result_mpeg4_gif.caption == self.caption + assert inline_query_result_mpeg4_gif.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == self.reply_markup.to_dict() - 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) - self.assertEqual(mpeg4.mpeg4_height, self.mpeg4_height) - self.assertEqual(mpeg4.mpeg4_duration, self.mpeg4_duration) - self.assertEqual(mpeg4.thumb_url, self.thumb_url) - self.assertEqual(mpeg4.title, self.title) - self.assertEqual(mpeg4.caption, self.caption) - self.assertDictEqual(mpeg4.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(mpeg4.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_mpeg4_gif): + inline_query_result_mpeg4_gif_dict = inline_query_result_mpeg4_gif.to_dict() - def test_mpeg4_to_json(self): - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(mpeg4.to_json())) - - def test_mpeg4_to_dict(self): - mpeg4 = telegram.InlineQueryResultMpeg4Gif.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(mpeg4)) - self.assertDictEqual(self.json_dict, mpeg4) + assert isinstance(inline_query_result_mpeg4_gif_dict, dict) + assert inline_query_result_mpeg4_gif_dict['type'] == inline_query_result_mpeg4_gif.type + assert inline_query_result_mpeg4_gif_dict['id'] == inline_query_result_mpeg4_gif.id + assert inline_query_result_mpeg4_gif_dict['mpeg4_url'] == \ + inline_query_result_mpeg4_gif.mpeg4_url + assert inline_query_result_mpeg4_gif_dict['mpeg4_width'] == \ + inline_query_result_mpeg4_gif.mpeg4_width + assert inline_query_result_mpeg4_gif_dict['mpeg4_height'] == \ + inline_query_result_mpeg4_gif.mpeg4_height + assert inline_query_result_mpeg4_gif_dict['mpeg4_duration'] == \ + inline_query_result_mpeg4_gif.mpeg4_duration + assert inline_query_result_mpeg4_gif_dict['thumb_url'] == \ + inline_query_result_mpeg4_gif.thumb_url + assert inline_query_result_mpeg4_gif_dict['title'] == inline_query_result_mpeg4_gif.title + assert inline_query_result_mpeg4_gif_dict['caption'] == \ + inline_query_result_mpeg4_gif.caption + assert inline_query_result_mpeg4_gif_dict['input_message_content'] == \ + inline_query_result_mpeg4_gif.input_message_content.to_dict() + assert inline_query_result_mpeg4_gif_dict['reply_markup'] == \ + inline_query_result_mpeg4_gif.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultMpeg4Gif(self._id, self.mpeg4_url, self.thumb_url) - b = telegram.InlineQueryResultMpeg4Gif(self._id, self.mpeg4_url, self.thumb_url) - c = telegram.InlineQueryResultMpeg4Gif(self._id, "", self.thumb_url) - d = telegram.InlineQueryResultMpeg4Gif("", self.mpeg4_url, self.thumb_url) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultMpeg4Gif(self.id, self.mpeg4_url, self.thumb_url) + b = InlineQueryResultMpeg4Gif(self.id, self.mpeg4_url, self.thumb_url) + c = InlineQueryResultMpeg4Gif(self.id, '', self.thumb_url) + d = InlineQueryResultMpeg4Gif('', self.mpeg4_url, self.thumb_url) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 14a7d8d6e..8a6a986e7 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -5,107 +5,102 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultPhoto""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InputTextMessageContent, InlineKeyboardButton, InlineKeyboardMarkup, + InlineQueryResultPhoto, InlineQueryResultVoice) -class InlineQueryResultPhotoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultPhoto.""" +@pytest.fixture(scope='class') +def inline_query_result_photo(): + return InlineQueryResultPhoto(TestInlineQueryResultPhoto.id, + TestInlineQueryResultPhoto.photo_url, + TestInlineQueryResultPhoto.thumb_url, + photo_width=TestInlineQueryResultPhoto.photo_width, + photo_height=TestInlineQueryResultPhoto.photo_height, + title=TestInlineQueryResultPhoto.title, + description=TestInlineQueryResultPhoto.description, + caption=TestInlineQueryResultPhoto.caption, + input_message_content=TestInlineQueryResultPhoto.input_message_content, + reply_markup=TestInlineQueryResultPhoto.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'photo' - self.photo_url = 'photo url' - self.photo_width = 10 - self.photo_height = 15 - self.thumb_url = 'thumb url' - self.title = 'title' - self.description = 'description' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'photo_url': self.photo_url, - 'photo_width': self.photo_width, - 'photo_height': self.photo_height, - 'thumb_url': self.thumb_url, - 'title': self.title, - 'description': self.description, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultPhoto(object): + id = 'id' + type = 'photo' + photo_url = 'photo url' + photo_width = 10 + photo_height = 15 + thumb_url = 'thumb url' + title = 'title' + description = 'description' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_photo_de_json(self): - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_photo): + assert inline_query_result_photo.type == self.type + assert inline_query_result_photo.id == self.id + assert inline_query_result_photo.photo_url == self.photo_url + assert inline_query_result_photo.photo_width == self.photo_width + assert inline_query_result_photo.photo_height == self.photo_height + assert inline_query_result_photo.thumb_url == self.thumb_url + assert inline_query_result_photo.title == self.title + assert inline_query_result_photo.description == self.description + assert inline_query_result_photo.caption == self.caption + assert inline_query_result_photo.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_photo.reply_markup.to_dict() == self.reply_markup.to_dict() - self.assertEqual(photo.type, self.type) - self.assertEqual(photo.id, self._id) - self.assertEqual(photo.photo_url, self.photo_url) - 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.description, self.description) - self.assertEqual(photo.caption, self.caption) - self.assertDictEqual(photo.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(photo.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_photo): + inline_query_result_photo_dict = inline_query_result_photo.to_dict() - def test_photo_to_json(self): - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(photo.to_json())) - - def test_photo_to_dict(self): - photo = telegram.InlineQueryResultPhoto.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(photo)) - self.assertDictEqual(self.json_dict, photo) + assert isinstance(inline_query_result_photo_dict, dict) + assert inline_query_result_photo_dict['type'] == inline_query_result_photo.type + assert inline_query_result_photo_dict['id'] == inline_query_result_photo.id + assert inline_query_result_photo_dict['photo_url'] == inline_query_result_photo.photo_url + assert inline_query_result_photo_dict['photo_width'] == \ + inline_query_result_photo.photo_width + assert inline_query_result_photo_dict['photo_height'] == \ + inline_query_result_photo.photo_height + assert inline_query_result_photo_dict['thumb_url'] == inline_query_result_photo.thumb_url + assert inline_query_result_photo_dict['title'] == inline_query_result_photo.title + assert inline_query_result_photo_dict['description'] == \ + inline_query_result_photo.description + assert inline_query_result_photo_dict['caption'] == inline_query_result_photo.caption + assert inline_query_result_photo_dict['input_message_content'] == \ + inline_query_result_photo.input_message_content.to_dict() + assert inline_query_result_photo_dict['reply_markup'] == \ + inline_query_result_photo.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultPhoto(self._id, self.photo_url, self.thumb_url) - b = telegram.InlineQueryResultPhoto(self._id, self.photo_url, self.thumb_url) - c = telegram.InlineQueryResultPhoto(self._id, "", self.thumb_url) - d = telegram.InlineQueryResultPhoto("", self.photo_url, self.thumb_url) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultPhoto(self.id, self.photo_url, self.thumb_url) + b = InlineQueryResultPhoto(self.id, self.photo_url, self.thumb_url) + c = InlineQueryResultPhoto(self.id, '', self.thumb_url) + d = InlineQueryResultPhoto('', self.photo_url, self.thumb_url) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index 8c012f334..8f12ccb19 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -5,112 +5,109 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultVenue""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineQueryResultVoice, InputTextMessageContent, InlineKeyboardButton, + InlineQueryResultVenue, InlineKeyboardMarkup) -class InlineQueryResultVenueTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultVenue.""" +@pytest.fixture(scope='class') +def inline_query_result_venue(): + return InlineQueryResultVenue(TestInlineQueryResultVenue.id, + TestInlineQueryResultVenue.latitude, + TestInlineQueryResultVenue.longitude, + TestInlineQueryResultVenue.title, + TestInlineQueryResultVenue.address, + foursquare_id=TestInlineQueryResultVenue.foursquare_id, + thumb_url=TestInlineQueryResultVenue.thumb_url, + thumb_width=TestInlineQueryResultVenue.thumb_width, + thumb_height=TestInlineQueryResultVenue.thumb_height, + input_message_content=TestInlineQueryResultVenue.input_message_content, + reply_markup=TestInlineQueryResultVenue.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'venue' - self.latitude = 'latitude' - self.longitude = 'longitude' - self.title = 'title' - self._address = 'address' # nose binds self.address for testing - self.foursquare_id = 'foursquare id' - self.thumb_url = 'thumb url' - self.thumb_width = 10 - self.thumb_height = 15 - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'id': self._id, - 'type': self.type, - 'latitude': self.latitude, - 'longitude': self.longitude, - 'title': self.title, - 'address': self._address, - 'foursquare_id': self.foursquare_id, - 'thumb_url': self.thumb_url, - 'thumb_width': self.thumb_width, - 'thumb_height': self.thumb_height, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } - def test_venue_de_json(self): - venue = telegram.InlineQueryResultVenue.de_json(self.json_dict, self._bot) +class TestInlineQueryResultVenue(object): + id = 'id' + type = 'venue' + latitude = 'latitude' + longitude = 'longitude' + title = 'title' + address = 'address' + foursquare_id = 'foursquare id' + thumb_url = 'thumb url' + thumb_width = 10 + thumb_height = 15 + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - self.assertEqual(venue.id, self._id) - self.assertEqual(venue.type, self.type) - self.assertEqual(venue.latitude, self.latitude) - self.assertEqual(venue.longitude, self.longitude) - self.assertEqual(venue.title, self.title) - self.assertEqual(venue.address, self._address) - self.assertEqual(venue.foursquare_id, self.foursquare_id) - self.assertEqual(venue.thumb_url, self.thumb_url) - self.assertEqual(venue.thumb_width, self.thumb_width) - self.assertEqual(venue.thumb_height, self.thumb_height) - self.assertDictEqual(venue.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(venue.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_expected_values(self, inline_query_result_venue): + assert inline_query_result_venue.id == self.id + assert inline_query_result_venue.type == self.type + assert inline_query_result_venue.latitude == self.latitude + assert inline_query_result_venue.longitude == self.longitude + assert inline_query_result_venue.title == self.title + assert inline_query_result_venue.address == self.address + assert inline_query_result_venue.foursquare_id == self.foursquare_id + assert inline_query_result_venue.thumb_url == self.thumb_url + assert inline_query_result_venue.thumb_width == self.thumb_width + assert inline_query_result_venue.thumb_height == self.thumb_height + assert inline_query_result_venue.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_venue.reply_markup.to_dict() == self.reply_markup.to_dict() - def test_venue_to_json(self): - venue = telegram.InlineQueryResultVenue.de_json(self.json_dict, self._bot) + def test_to_dict(self, inline_query_result_venue): + inline_query_result_venue_dict = inline_query_result_venue.to_dict() - self.assertTrue(self.is_json(venue.to_json())) - - def test_venue_to_dict(self): - venue = telegram.InlineQueryResultVenue.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(venue)) - self.assertDictEqual(self.json_dict, venue) + assert isinstance(inline_query_result_venue_dict, dict) + assert inline_query_result_venue_dict['id'] == inline_query_result_venue.id + assert inline_query_result_venue_dict['type'] == inline_query_result_venue.type + assert inline_query_result_venue_dict['latitude'] == inline_query_result_venue.latitude + assert inline_query_result_venue_dict['longitude'] == inline_query_result_venue.longitude + assert inline_query_result_venue_dict['title'] == inline_query_result_venue.title + assert inline_query_result_venue_dict['address'] == inline_query_result_venue.address + assert inline_query_result_venue_dict['foursquare_id'] == \ + inline_query_result_venue.foursquare_id + assert inline_query_result_venue_dict['thumb_url'] == inline_query_result_venue.thumb_url + assert inline_query_result_venue_dict['thumb_width'] == \ + inline_query_result_venue.thumb_width + assert inline_query_result_venue_dict['thumb_height'] == \ + inline_query_result_venue.thumb_height + assert inline_query_result_venue_dict['input_message_content'] == \ + inline_query_result_venue.input_message_content.to_dict() + assert inline_query_result_venue_dict['reply_markup'] == \ + inline_query_result_venue.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultVenue(self._id, self.longitude, self.latitude, self.title, - self._address) - b = telegram.InlineQueryResultVenue(self._id, self.longitude, self.latitude, self.title, - self._address) - c = telegram.InlineQueryResultVenue(self._id, "", self.latitude, self.title, self._address) - d = telegram.InlineQueryResultVenue("", self.longitude, self.latitude, self.title, - self._address) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultVenue(self.id, self.longitude, self.latitude, self.title, + self.address) + b = InlineQueryResultVenue(self.id, self.longitude, self.latitude, self.title, + self.address) + c = InlineQueryResultVenue(self.id, '', self.latitude, self.title, self.address) + d = InlineQueryResultVenue('', self.longitude, self.latitude, self.title, + self.address) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index e4838ad13..8c42f2e40 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -5,117 +5,115 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultVideo""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultVideo, + InlineKeyboardMarkup, InlineQueryResultVoice) -class InlineQueryResultVideoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultVideo.""" +@pytest.fixture(scope='class') +def inline_query_result_video(): + return InlineQueryResultVideo(TestInlineQueryResultVideo.id, + TestInlineQueryResultVideo.video_url, + TestInlineQueryResultVideo.mime_type, + TestInlineQueryResultVideo.thumb_url, + TestInlineQueryResultVideo.title, + video_width=TestInlineQueryResultVideo.video_width, + video_height=TestInlineQueryResultVideo.video_height, + video_duration=TestInlineQueryResultVideo.video_duration, + caption=TestInlineQueryResultVideo.caption, + description=TestInlineQueryResultVideo.description, + input_message_content=TestInlineQueryResultVideo.input_message_content, + reply_markup=TestInlineQueryResultVideo.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'video' - self.video_url = 'video 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.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - '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, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultVideo(object): + id = 'id' + type = 'video' + video_url = 'video url' + mime_type = 'mime type' + video_width = 10 + video_height = 15 + video_duration = 15 + thumb_url = 'thumb url' + title = 'title' + caption = 'caption' + description = 'description' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_video_de_json(self): - video = telegram.InlineQueryResultVideo.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_video): + assert inline_query_result_video.type == self.type + assert inline_query_result_video.id == self.id + assert inline_query_result_video.video_url == self.video_url + assert inline_query_result_video.mime_type == self.mime_type + assert inline_query_result_video.video_width == self.video_width + assert inline_query_result_video.video_height == self.video_height + assert inline_query_result_video.video_duration == self.video_duration + assert inline_query_result_video.thumb_url == self.thumb_url + assert inline_query_result_video.title == self.title + assert inline_query_result_video.description == self.description + assert inline_query_result_video.caption == self.caption + assert inline_query_result_video.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_video.reply_markup.to_dict() == self.reply_markup.to_dict() - 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) - 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.assertDictEqual(video.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(video.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_video): + inline_query_result_video_dict = inline_query_result_video.to_dict() - def test_video_to_json(self): - video = telegram.InlineQueryResultVideo.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(video.to_json())) - - def test_video_to_dict(self): - video = telegram.InlineQueryResultVideo.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(video)) - self.assertDictEqual(self.json_dict, video) + assert isinstance(inline_query_result_video_dict, dict) + assert inline_query_result_video_dict['type'] == inline_query_result_video.type + assert inline_query_result_video_dict['id'] == inline_query_result_video.id + assert inline_query_result_video_dict['video_url'] == inline_query_result_video.video_url + assert inline_query_result_video_dict['mime_type'] == inline_query_result_video.mime_type + assert inline_query_result_video_dict['video_width'] == \ + inline_query_result_video.video_width + assert inline_query_result_video_dict['video_height'] == \ + inline_query_result_video.video_height + assert inline_query_result_video_dict['video_duration'] == \ + inline_query_result_video.video_duration + assert inline_query_result_video_dict['thumb_url'] == inline_query_result_video.thumb_url + assert inline_query_result_video_dict['title'] == inline_query_result_video.title + assert inline_query_result_video_dict['description'] == \ + inline_query_result_video.description + assert inline_query_result_video_dict['caption'] == inline_query_result_video.caption + assert inline_query_result_video_dict['input_message_content'] == \ + inline_query_result_video.input_message_content.to_dict() + assert inline_query_result_video_dict['reply_markup'] == \ + inline_query_result_video.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultVideo(self._id, self.video_url, self.mime_type, - self.thumb_url, self.title) - b = telegram.InlineQueryResultVideo(self._id, self.video_url, self.mime_type, - self.thumb_url, self.title) - c = telegram.InlineQueryResultVideo(self._id, "", self.mime_type, self.thumb_url, - self.title) - d = telegram.InlineQueryResultVideo("", self.video_url, self.mime_type, self.thumb_url, - self.title) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultVideo(self.id, self.video_url, self.mime_type, + self.thumb_url, self.title) + b = InlineQueryResultVideo(self.id, self.video_url, self.mime_type, + self.thumb_url, self.title) + c = InlineQueryResultVideo(self.id, '', self.mime_type, self.thumb_url, + self.title) + d = InlineQueryResultVideo('', self.video_url, self.mime_type, self.thumb_url, + self.title) + e = InlineQueryResultVoice(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index 67566ebea..55188db31 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -5,98 +5,89 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InlineQueryResultVoice""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (InlineKeyboardButton, InputTextMessageContent, InlineQueryResultAudio, + InlineQueryResultVoice, InlineKeyboardMarkup) -class InlineQueryResultVoiceTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InlineQueryResultVoice.""" +@pytest.fixture(scope='class') +def inline_query_result_voice(): + return InlineQueryResultVoice(type=TestInlineQueryResultVoice.type, + id=TestInlineQueryResultVoice.id, + voice_url=TestInlineQueryResultVoice.voice_url, + title=TestInlineQueryResultVoice.title, + voice_duration=TestInlineQueryResultVoice.voice_duration, + caption=TestInlineQueryResultVoice.caption, + input_message_content=TestInlineQueryResultVoice.input_message_content, + reply_markup=TestInlineQueryResultVoice.reply_markup) - def setUp(self): - self._id = 'id' - self.type = 'voice' - self.voice_url = 'voice url' - self.title = 'title' - self.voice_duration = 'voice_duration' - self.caption = 'caption' - self.input_message_content = telegram.InputTextMessageContent('input_message_content') - self.reply_markup = telegram.InlineKeyboardMarkup( - [[telegram.InlineKeyboardButton('reply_markup')]]) - self.json_dict = { - 'type': self.type, - 'id': self._id, - 'voice_url': self.voice_url, - 'title': self.title, - 'voice_duration': self.voice_duration, - 'caption': self.caption, - 'input_message_content': self.input_message_content.to_dict(), - 'reply_markup': self.reply_markup.to_dict(), - } +class TestInlineQueryResultVoice(object): + id = 'id' + type = 'voice' + voice_url = 'voice url' + title = 'title' + voice_duration = 'voice_duration' + caption = 'caption' + input_message_content = InputTextMessageContent('input_message_content') + reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton('reply_markup')]]) - def test_voice_de_json(self): - voice = telegram.InlineQueryResultVoice.de_json(self.json_dict, self._bot) + def test_expected_values(self, inline_query_result_voice): + assert inline_query_result_voice.type == self.type + assert inline_query_result_voice.id == self.id + assert inline_query_result_voice.voice_url == self.voice_url + assert inline_query_result_voice.title == self.title + assert inline_query_result_voice.voice_duration == self.voice_duration + assert inline_query_result_voice.caption == self.caption + assert inline_query_result_voice.input_message_content.to_dict() == \ + self.input_message_content.to_dict() + assert inline_query_result_voice.reply_markup.to_dict() == self.reply_markup.to_dict() - self.assertEqual(voice.type, self.type) - self.assertEqual(voice.id, self._id) - self.assertEqual(voice.voice_url, self.voice_url) - self.assertEqual(voice.title, self.title) - self.assertEqual(voice.voice_duration, self.voice_duration) - self.assertEqual(voice.caption, self.caption) - self.assertDictEqual(voice.input_message_content.to_dict(), - self.input_message_content.to_dict()) - self.assertDictEqual(voice.reply_markup.to_dict(), self.reply_markup.to_dict()) + def test_to_dict(self, inline_query_result_voice): + inline_query_result_voice_dict = inline_query_result_voice.to_dict() - def test_voice_to_json(self): - voice = telegram.InlineQueryResultVoice.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(voice.to_json())) - - def test_voice_to_dict(self): - voice = telegram.InlineQueryResultVoice.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(voice)) - self.assertDictEqual(self.json_dict, voice) + assert isinstance(inline_query_result_voice_dict, dict) + assert inline_query_result_voice_dict['type'] == inline_query_result_voice.type + assert inline_query_result_voice_dict['id'] == inline_query_result_voice.id + assert inline_query_result_voice_dict['voice_url'] == inline_query_result_voice.voice_url + assert inline_query_result_voice_dict['title'] == inline_query_result_voice.title + assert inline_query_result_voice_dict['voice_duration'] == \ + inline_query_result_voice.voice_duration + assert inline_query_result_voice_dict['caption'] == inline_query_result_voice.caption + assert inline_query_result_voice_dict['input_message_content'] == \ + inline_query_result_voice.input_message_content.to_dict() + assert inline_query_result_voice_dict['reply_markup'] == \ + inline_query_result_voice.reply_markup.to_dict() def test_equality(self): - a = telegram.InlineQueryResultVoice(self._id, self.voice_url, self.title) - b = telegram.InlineQueryResultVoice(self._id, self.voice_url, self.title) - c = telegram.InlineQueryResultVoice(self._id, "", self.title) - d = telegram.InlineQueryResultVoice("", self.voice_url, self.title) - e = telegram.InlineQueryResultArticle(self._id, "", "") + a = InlineQueryResultVoice(self.id, self.voice_url, self.title) + b = InlineQueryResultVoice(self.id, self.voice_url, self.title) + c = InlineQueryResultVoice(self.id, '', self.title) + d = InlineQueryResultVoice('', self.voice_url, self.title) + e = InlineQueryResultAudio(self.id, '', '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index d8298087d..1373820e9 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -5,76 +5,71 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InputContactMessageContent""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InputContactMessageContent, InputMessageContent -class InputContactMessageContentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InputContactMessageContent.""" +@pytest.fixture(scope='function') +def json_dict(): + return { + 'first_name': TestInputContactMessageContent.first_name, + 'phone_number': TestInputContactMessageContent.phone_number, + 'last_name': TestInputContactMessageContent.last_name, + } - def setUp(self): - self.phone_number = 'phone number' - self.first_name = 'first name' - self.last_name = 'last name' - self.json_dict = { - 'first_name': self.first_name, - 'phone_number': self.phone_number, - 'last_name': self.last_name, - } +@pytest.fixture(scope='class') +def input_contact_message_content(): + return InputContactMessageContent(TestInputContactMessageContent.phone_number, + TestInputContactMessageContent.first_name, + last_name=TestInputContactMessageContent.last_name) - def test_icmc_de_json(self): - icmc = telegram.InputContactMessageContent.de_json(self.json_dict, self._bot) - self.assertEqual(icmc.first_name, self.first_name) - self.assertEqual(icmc.phone_number, self.phone_number) - self.assertEqual(icmc.last_name, self.last_name) +class TestInputContactMessageContent(object): + phone_number = 'phone number' + first_name = 'first name' + last_name = 'last name' - def test_icmc_de_json_factory(self): - icmc = telegram.InputMessageContent.de_json(self.json_dict, self._bot) + def test_de_json(self, json_dict, bot): + input_contact_message_content_json = InputContactMessageContent.de_json(json_dict, bot) - self.assertTrue(isinstance(icmc, telegram.InputContactMessageContent)) + assert input_contact_message_content_json.first_name == self.first_name + assert input_contact_message_content_json.phone_number == self.phone_number + assert input_contact_message_content_json.last_name == self.last_name - def test_icmc_de_json_factory_without_required_args(self): - json_dict = self.json_dict + def test_de_json_factory(self, json_dict, bot): + input_contact_message_content_json = InputMessageContent.de_json(json_dict, bot) + assert isinstance(input_contact_message_content_json, InputContactMessageContent) + + def test_de_json_factory_without_required_args(self, json_dict, bot): del (json_dict['phone_number']) del (json_dict['first_name']) - icmc = telegram.InputMessageContent.de_json(json_dict, self._bot) + input_contact_message_content_json = InputMessageContent.de_json(json_dict, bot) - self.assertFalse(icmc) + assert input_contact_message_content_json is None - def test_icmc_to_json(self): - icmc = telegram.InputContactMessageContent.de_json(self.json_dict, self._bot) + def test_to_dict(self, input_contact_message_content): + input_contact_message_content_dict = input_contact_message_content.to_dict() - self.assertTrue(self.is_json(icmc.to_json())) - - def test_icmc_to_dict(self): - icmc = telegram.InputContactMessageContent.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(icmc)) - self.assertDictEqual(self.json_dict, icmc) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(input_contact_message_content_dict, dict) + assert input_contact_message_content_dict['phone_number'] == \ + input_contact_message_content.phone_number + assert input_contact_message_content_dict['first_name'] == \ + input_contact_message_content.first_name + assert input_contact_message_content_dict['last_name'] == \ + input_contact_message_content.last_name diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index fc886f713..f2a833e60 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -5,74 +5,66 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InputLocationMessageContent""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InputMessageContent, InputLocationMessageContent -class InputLocationMessageContentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InputLocationMessageContent.""" +@pytest.fixture(scope='function') +def json_dict(): + return { + 'longitude': TestInputLocationMessageContent.longitude, + 'latitude': TestInputLocationMessageContent.latitude, + } - def setUp(self): - self.latitude = 1. - self.longitude = 2. - self.json_dict = { - 'longitude': self.longitude, - 'latitude': self.latitude, - } +@pytest.fixture(scope='class') +def input_location_message_content(): + return InputLocationMessageContent(TestInputLocationMessageContent.longitude, + TestInputLocationMessageContent.latitude) - def test_ilmc_de_json(self): - ilmc = telegram.InputLocationMessageContent.de_json(self.json_dict, self._bot) - self.assertEqual(ilmc.longitude, self.longitude) - self.assertEqual(ilmc.latitude, self.latitude) +class TestInputLocationMessageContent(object): + latitude = 1. + longitude = 2. - def test_ilmc_de_json_factory(self): - ilmc = telegram.InputMessageContent.de_json(self.json_dict, self._bot) + def test_de_json(self, json_dict, bot): + input_location_message_content_json = InputLocationMessageContent.de_json(json_dict, bot) - self.assertTrue(isinstance(ilmc, telegram.InputLocationMessageContent)) + assert input_location_message_content_json.longitude == self.longitude + assert input_location_message_content_json.latitude == self.latitude - def test_ilmc_de_json_factory_without_required_args(self): - json_dict = self.json_dict + def test_input_location_message_content_json_de_json_factory(self, json_dict, bot): + input_location_message_content_json = InputMessageContent.de_json(json_dict, bot) + assert isinstance(input_location_message_content_json, InputLocationMessageContent) + + def test_de_json_factory_without_required_args(self, json_dict, bot): del (json_dict['longitude']) - # If none args are sent it will fall in a different condition + # If no args are passed it will fall in a different condition # del (json_dict['latitude']) - ilmc = telegram.InputMessageContent.de_json(json_dict, self._bot) + input_location_message_content_json = InputMessageContent.de_json(json_dict, bot) - self.assertFalse(ilmc) + assert input_location_message_content_json is None - def test_ilmc_to_json(self): - ilmc = telegram.InputLocationMessageContent.de_json(self.json_dict, self._bot) + def test_to_dict(self, input_location_message_content): + input_location_message_content_dict = input_location_message_content.to_dict() - self.assertTrue(self.is_json(ilmc.to_json())) - - def test_ilmc_to_dict(self): - ilmc = telegram.InputLocationMessageContent.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(ilmc)) - self.assertDictEqual(self.json_dict, ilmc) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(input_location_message_content_dict, dict) + assert input_location_message_content_dict['latitude'] == \ + input_location_message_content.latitude + assert input_location_message_content_dict['longitude'] == \ + input_location_message_content.longitude diff --git a/tests/test_inputmessagecontent.py b/tests/test_inputmessagecontent.py index a7485d15e..738638c23 100644 --- a/tests/test_inputmessagecontent.py +++ b/tests/test_inputmessagecontent.py @@ -5,37 +5,23 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InputMessageContent""" -import sys -import unittest - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InputMessageContent -class InputMessageContentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InputMessageContent.""" +class TestInputMessageContent(object): + def test_de_json(self, bot): + input_message_content = InputMessageContent.de_json(None, bot) - def test_imc_de_json(self): - imc = telegram.InputMessageContent.de_json(None, self._bot) - - self.assertFalse(imc) - - -if __name__ == '__main__': - unittest.main() + assert input_message_content is None diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 77c178d42..d0f8829f7 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -5,75 +5,71 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InputTextMessageContent""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InputTextMessageContent, InputMessageContent, ParseMode -class InputTextMessageContentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InputTextMessageContent.""" +@pytest.fixture(scope='function') +def json_dict(): + return { + 'parse_mode': TestInputTextMessageContent.parse_mode, + 'message_text': TestInputTextMessageContent.message_text, + 'disable_web_page_preview': TestInputTextMessageContent.disable_web_page_preview, + } - def setUp(self): - self.message_text = '*message text*' - self.parse_mode = telegram.ParseMode.MARKDOWN - self.disable_web_page_preview = True - self.json_dict = { - 'parse_mode': self.parse_mode, - 'message_text': self.message_text, - 'disable_web_page_preview': self.disable_web_page_preview, - } +@pytest.fixture(scope='class') +def input_text_message_content(): + return InputTextMessageContent(TestInputTextMessageContent.message_text, + parse_mode=TestInputTextMessageContent.parse_mode, + disable_web_page_preview=TestInputTextMessageContent.disable_web_page_preview) - def test_itmc_de_json(self): - itmc = telegram.InputTextMessageContent.de_json(self.json_dict, self._bot) - self.assertEqual(itmc.parse_mode, self.parse_mode) - self.assertEqual(itmc.message_text, self.message_text) - self.assertEqual(itmc.disable_web_page_preview, self.disable_web_page_preview) +class TestInputTextMessageContent(object): + message_text = '*message text*' + parse_mode = ParseMode.MARKDOWN + disable_web_page_preview = True - def test_itmc_de_json_factory(self): - itmc = telegram.InputMessageContent.de_json(self.json_dict, self._bot) + def test_de_json(self, json_dict, bot): + input_text_message_content_json = InputTextMessageContent.de_json(json_dict, bot) - self.assertTrue(isinstance(itmc, telegram.InputTextMessageContent)) + assert input_text_message_content_json.parse_mode == self.parse_mode + assert input_text_message_content_json.message_text == self.message_text + assert input_text_message_content_json.disable_web_page_preview == \ + self.disable_web_page_preview - def test_itmc_de_json_factory_without_required_args(self): - json_dict = self.json_dict + def test_input_text_message_content_json_de_json_factory(self, json_dict, bot): + input_text_message_content_json = InputMessageContent.de_json(json_dict, bot) + assert isinstance(input_text_message_content_json, InputTextMessageContent) + + def test_de_json_factory_without_required_args(self, json_dict, bot): del (json_dict['message_text']) - itmc = telegram.InputMessageContent.de_json(json_dict, self._bot) + input_text_message_content_json = InputMessageContent.de_json(json_dict, bot) - self.assertFalse(itmc) + assert input_text_message_content_json is None - def test_itmc_to_json(self): - itmc = telegram.InputTextMessageContent.de_json(self.json_dict, self._bot) + def test_to_dict(self, input_text_message_content): + input_text_message_content_dict = input_text_message_content.to_dict() - self.assertTrue(self.is_json(itmc.to_json())) - - def test_itmc_to_dict(self): - itmc = telegram.InputTextMessageContent.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(itmc)) - self.assertDictEqual(self.json_dict, itmc) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(input_text_message_content_dict, dict) + assert input_text_message_content_dict['message_text'] == \ + input_text_message_content.message_text + assert input_text_message_content_dict['parse_mode'] == \ + input_text_message_content.parse_mode + assert input_text_message_content_dict['disable_web_page_preview'] == \ + input_text_message_content.disable_web_page_preview diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index ff7d6629d..2bbe39ce7 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -5,84 +5,85 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -InputVenueMessageContent""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import InputVenueMessageContent, InputMessageContent -class InputVenueMessageContentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram InputVenueMessageContent.""" +@pytest.fixture(scope='function') +def json_dict(): + return { + 'longitude': TestInputVenueMessageContent.longitude, + 'latitude': TestInputVenueMessageContent.latitude, + 'title': TestInputVenueMessageContent.title, + 'address': TestInputVenueMessageContent.address, + 'foursquare_id': TestInputVenueMessageContent.foursquare_id, + } - def setUp(self): - self.latitude = 1. - self.longitude = 2. - self.title = 'title' - self._address = 'address' # nose binds self.address for testing - self.foursquare_id = 'foursquare id' - self.json_dict = { - 'longitude': self.longitude, - 'latitude': self.latitude, - 'title': self.title, - 'address': self._address, - 'foursquare_id': self.foursquare_id, - } +@pytest.fixture(scope='class') +def input_venue_message_content(): + return InputVenueMessageContent(TestInputVenueMessageContent.latitude, + TestInputVenueMessageContent.longitude, + TestInputVenueMessageContent.title, + TestInputVenueMessageContent.address, + foursquare_id=TestInputVenueMessageContent.foursquare_id) - def test_ivmc_de_json(self): - ivmc = telegram.InputVenueMessageContent.de_json(self.json_dict, self._bot) - self.assertEqual(ivmc.longitude, self.longitude) - self.assertEqual(ivmc.latitude, self.latitude) - self.assertEqual(ivmc.title, self.title) - self.assertEqual(ivmc.address, self._address) - self.assertEqual(ivmc.foursquare_id, self.foursquare_id) +class TestInputVenueMessageContent(object): + latitude = 1. + longitude = 2. + title = 'title' + address = 'address' + foursquare_id = 'foursquare id' - def test_ivmc_de_json_factory(self): - ivmc = telegram.InputMessageContent.de_json(self.json_dict, self._bot) + def test_de_json(self, json_dict, bot): + input_venue_message_content_json = InputVenueMessageContent.de_json(json_dict, bot) - self.assertTrue(isinstance(ivmc, telegram.InputVenueMessageContent)) + assert input_venue_message_content_json.longitude == self.longitude + assert input_venue_message_content_json.latitude == self.latitude + assert input_venue_message_content_json.title == self.title + assert input_venue_message_content_json.address == self.address + assert input_venue_message_content_json.foursquare_id == self.foursquare_id - def test_ivmc_de_json_factory_without_required_args(self): - json_dict = self.json_dict + def test_de_json_factory(self, json_dict, bot): + input_venue_message_content_json = InputMessageContent.de_json(json_dict, bot) + + assert isinstance(input_venue_message_content_json, InputVenueMessageContent) + + def test_de_json_factory_without_required_args(self, json_dict, bot): + json_dict = json_dict del (json_dict['longitude']) del (json_dict['latitude']) del (json_dict['title']) del (json_dict['address']) - ivmc = telegram.InputMessageContent.de_json(json_dict, self._bot) + input_venue_message_content_json = InputMessageContent.de_json(json_dict, bot) - self.assertFalse(ivmc) + assert input_venue_message_content_json is None - def test_ivmc_to_json(self): - ivmc = telegram.InputVenueMessageContent.de_json(self.json_dict, self._bot) + def test_to_dict(self, input_venue_message_content): + input_venue_message_content_dict = input_venue_message_content.to_dict() - self.assertTrue(self.is_json(ivmc.to_json())) - - def test_ivmc_to_dict(self): - ivmc = telegram.InputVenueMessageContent.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(ivmc)) - self.assertDictEqual(self.json_dict, ivmc) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(input_venue_message_content_dict, dict) + assert input_venue_message_content_dict['latitude'] == \ + input_venue_message_content.latitude + assert input_venue_message_content_dict['longitude'] == \ + input_venue_message_content.longitude + assert input_venue_message_content_dict['title'] == input_venue_message_content.title + assert input_venue_message_content_dict['address'] == input_venue_message_content.address + assert input_venue_message_content_dict['foursquare_id'] == \ + input_venue_message_content.foursquare_id diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 2a04f624f..c6b6ffc5a 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -5,117 +5,103 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -Invoice""" - -import sys -import unittest +import pytest from flaky import flaky -sys.path.append('.') - -import telegram -from tests.base import BaseTest, timeout +from telegram import LabeledPrice, Invoice -class InvoiceTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Invoice.""" +@pytest.fixture(scope='class') +def invoice(): + return Invoice(TestInvoice.title, TestInvoice.description, TestInvoice.start_parameter, + TestInvoice.currency, TestInvoice.total_amount) - def setUp(self): - self.payload = 'payload' - self.provider_token = self._payment_provider_token - self.prices = [telegram.LabeledPrice('Fish', 100), telegram.LabeledPrice('Fish Tax', 1000)] - self.title = 'title' - self.description = 'description' - self.start_parameter = 'start_parameter' - self.currency = 'EUR' - self.total_amount = sum([p.amount for p in self.prices]) +class TestInvoice(object): + payload = 'payload' + prices = [LabeledPrice('Fish', 100), LabeledPrice('Fish Tax', 1000)] + title = 'title' + description = 'description' + start_parameter = 'start_parameter' + currency = 'EUR' + total_amount = sum([p.amount for p in prices]) - self.json_dict = { - 'title': self.title, - 'description': self.description, - 'start_parameter': self.start_parameter, - 'currency': self.currency, - 'total_amount': self.total_amount - } + def test_de_json(self, bot): + invoice_json = Invoice.de_json({ + 'title': TestInvoice.title, + 'description': TestInvoice.description, + 'start_parameter': TestInvoice.start_parameter, + 'currency': TestInvoice.currency, + 'total_amount': TestInvoice.total_amount + }, bot) - def test_invoice_de_json(self): - invoice = telegram.Invoice.de_json(self.json_dict, self._bot) + assert invoice_json.title == self.title + assert invoice_json.description == self.description + assert invoice_json.start_parameter == self.start_parameter + assert invoice_json.currency == self.currency + assert invoice_json.total_amount == self.total_amount - self.assertEqual(invoice.title, self.title) - self.assertEqual(invoice.description, self.description) - self.assertEqual(invoice.start_parameter, self.start_parameter) - self.assertEqual(invoice.currency, self.currency) - self.assertEqual(invoice.total_amount, self.total_amount) + def test_to_dict(self, invoice): + invoice_dict = invoice.to_dict() - def test_invoice_to_json(self): - invoice = telegram.Invoice.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(invoice.to_json())) - - def test_invoice_to_dict(self): - invoice = telegram.Invoice.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(invoice)) - self.assertDictEqual(self.json_dict, invoice) + assert isinstance(invoice_dict, dict) + assert invoice_dict['title'] == invoice.title + assert invoice_dict['description'] == invoice.description + assert invoice_dict['start_parameter'] == invoice.start_parameter + assert invoice_dict['currency'] == invoice.currency + assert invoice_dict['total_amount'] == invoice.total_amount @flaky(3, 1) - @timeout(10) - def test_send_invoice_required_args_only(self): - message = self._bot.send_invoice(self._chat_id, self.title, self.description, self.payload, - self.provider_token, self.start_parameter, self.currency, - self.prices) - invoice = message.invoice + @pytest.mark.timeout(10) + def test_send_required_args_only(self, bot, chat_id, provider_token): + message = bot.send_invoice(chat_id, self.title, self.description, self.payload, + provider_token, self.start_parameter, self.currency, + self.prices) - self.assertEqual(invoice.currency, self.currency) - self.assertEqual(invoice.start_parameter, self.start_parameter) - self.assertEqual(invoice.description, self.description) - self.assertEqual(invoice.title, self.title) - self.assertEqual(invoice.total_amount, self.total_amount) + assert message.invoice.currency == self.currency + assert message.invoice.start_parameter == self.start_parameter + assert message.invoice.description == self.description + assert message.invoice.title == self.title + assert message.invoice.total_amount == self.total_amount @flaky(3, 1) - @timeout(10) - def test_send_invoice_all_args(self): - message = self._bot.send_invoice( - self._chat_id, + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, provider_token): + message = bot.send_invoice( + chat_id, self.title, self.description, self.payload, - self.provider_token, + provider_token, self.start_parameter, self.currency, self.prices, photo_url='https://raw.githubusercontent.com/' - 'python-telegram-bot/logos/master/' - 'logo/png/ptb-logo_240.png', + 'python-telegram-bot/logos/master/' + 'logo/png/ptb-logo_240.png', photo_size=240, photo_width=240, photo_height=240, need_name=True, need_phone_number=True, + need_email=True, need_shipping_address=True, is_flexible=True) - invoice = message.invoice - self.assertEqual(invoice.currency, self.currency) - self.assertEqual(invoice.start_parameter, self.start_parameter) - self.assertEqual(invoice.description, self.description) - self.assertEqual(invoice.title, self.title) - self.assertEqual(invoice.total_amount, self.total_amount) - - -if __name__ == '__main__': - unittest.main() + assert message.invoice.currency == self.currency + assert message.invoice.start_parameter == self.start_parameter + assert message.invoice.description == self.description + assert message.invoice.title == self.title + assert message.invoice.total_amount == self.total_amount diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 88899f920..a3381858d 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -1,256 +1,238 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for JobQueue -""" -import logging -import sys -import unittest import datetime import time -from math import ceil from time import sleep -from tests.test_updater import MockBot +import pytest +from flaky import flaky -sys.path.append('.') - -from telegram.ext import JobQueue, Job, Updater -from tests.base import BaseTest - -# Enable logging -root = logging.getLogger() -root.setLevel(logging.INFO) - -ch = logging.StreamHandler(sys.stdout) -ch.setLevel(logging.WARN) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') -ch.setFormatter(formatter) -root.addHandler(ch) +from telegram.ext import JobQueue, Updater, Job -class JobQueueTest(BaseTest, unittest.TestCase): - """ - This object represents Tests for Updater, Dispatcher, WebhookServer and - WebhookHandler - """ +@pytest.fixture(scope='function') +def job_queue(bot): + jq = JobQueue(bot) + jq.start() + yield jq + jq.stop() - def setUp(self): - self.jq = JobQueue(MockBot('jobqueue_test')) - self.jq.start() + +@flaky(10, 1) # Timings aren't quite perfect +class TestJobQueue(object): + result = 0 + job_time = 0 + + @pytest.fixture(autouse=True) + def reset(self): self.result = 0 self.job_time = 0 - def tearDown(self): - if self.jq is not None: - self.jq.stop() - - def job1(self, bot, job): + def job_run_once(self, bot, job): self.result += 1 - def job2(self, bot, job): - raise Exception("Test Error") + def job_with_exception(self, bot, job): + raise Exception('Test Error') - def job3(self, bot, job): + def job_remove_self(self, bot, job): self.result += 1 job.schedule_removal() - def job4(self, bot, job): + def job_run_once_with_context(self, bot, job): self.result += job.context - def job5(self, bot, job): + def job_datetime_tests(self, bot, job): self.job_time = time.time() - def test_basic(self): - self.jq.put(Job(self.job1, 0.1)) - sleep(1.5) - self.assertGreaterEqual(self.result, 10) + def test_run_once(self, job_queue): + job_queue.run_once(self.job_run_once, 0.01) + sleep(0.02) + assert self.result == 1 - def test_job_with_context(self): - self.jq.put(Job(self.job4, 0.1, context=5)) - sleep(1.5) - self.assertGreaterEqual(self.result, 50) + def test_job_with_context(self, job_queue): + job_queue.run_once(self.job_run_once_with_context, 0.01, context=5) + sleep(0.02) + assert self.result == 5 - def test_noRepeat(self): - self.jq.put(Job(self.job1, 0.1, repeat=False)) - sleep(0.5) - self.assertEqual(1, self.result) + def test_run_repeating(self, job_queue): + job_queue.run_repeating(self.job_run_once, 0.02) + sleep(0.05) + assert self.result == 2 - def test_nextT(self): - self.jq.put(Job(self.job1, 0.1), next_t=0.5) - sleep(0.45) - self.assertEqual(0, self.result) - sleep(0.1) - self.assertEqual(1, self.result) - - def test_multiple(self): - self.jq.put(Job(self.job1, 0.1, repeat=False)) - self.jq.put(Job(self.job1, 0.2, repeat=False)) - self.jq.put(Job(self.job1, 0.4)) - sleep(1) - self.assertEqual(4, self.result) - - def test_disabled(self): - j0 = Job(self.job1, 0.1) - j1 = Job(self.job1, 0.2) - - self.jq.put(j0) - self.jq.put(Job(self.job1, 0.4)) - self.jq.put(j1) - - j0.enabled = False - j1.enabled = False - - sleep(1) - self.assertEqual(2, self.result) - - def test_schedule_removal(self): - j0 = Job(self.job1, 0.1) - j1 = Job(self.job1, 0.2) - - self.jq.put(j0) - self.jq.put(Job(self.job1, 0.4)) - self.jq.put(j1) - - j0.schedule_removal() - j1.schedule_removal() - - sleep(1) - self.assertEqual(2, self.result) - - def test_schedule_removal_from_within(self): - self.jq.put(Job(self.job1, 0.4)) - self.jq.put(Job(self.job3, 0.2)) - - sleep(1) - self.assertEqual(3, self.result) - - def test_longer_first(self): - self.jq.put(Job(self.job1, 0.2, repeat=False)) - self.jq.put(Job(self.job1, 0.1, repeat=False)) + def test_run_repeating_first(self, job_queue): + job_queue.run_repeating(self.job_run_once, 0.05, first=0.2) sleep(0.15) - self.assertEqual(1, self.result) + assert self.result == 0 + sleep(0.07) + assert self.result == 1 - def test_error(self): - self.jq.put(Job(self.job2, 0.1)) - self.jq.put(Job(self.job1, 0.2)) - sleep(0.5) - self.assertEqual(2, self.result) + def test_multiple(self, job_queue): + job_queue.run_once(self.job_run_once, 0.01) + job_queue.run_once(self.job_run_once, 0.02) + job_queue.run_repeating(self.job_run_once, 0.02) + sleep(0.055) + assert self.result == 4 - def test_jobs_tuple(self): - self.jq.stop() - jobs = tuple(Job(self.job1, t) for t in range(5, 25)) + def test_disabled(self, job_queue): + j1 = job_queue.run_once(self.job_run_once, 0.1) + j2 = job_queue.run_repeating(self.job_run_once, 0.05) - for job in jobs: - self.jq.put(job) + j1.enabled = False + j2.enabled = False - self.assertTupleEqual(jobs, self.jq.jobs()) + sleep(0.06) - def test_inUpdater(self): - u = Updater(bot="MockBot") + assert self.result == 0 + + j1.enabled = True + + sleep(0.2) + + assert self.result == 1 + + def test_schedule_removal(self, job_queue): + j1 = job_queue.run_once(self.job_run_once, 0.03) + j2 = job_queue.run_repeating(self.job_run_once, 0.02) + + sleep(0.025) + + j1.schedule_removal() + j2.schedule_removal() + + sleep(0.04) + + assert self.result == 1 + + def test_schedule_removal_from_within(self, job_queue): + job_queue.run_repeating(self.job_remove_self, 0.01) + + sleep(0.05) + + assert self.result == 1 + + def test_longer_first(self, job_queue): + job_queue.run_once(self.job_run_once, 0.02) + job_queue.run_once(self.job_run_once, 0.01) + + sleep(0.015) + + assert self.result == 1 + + def test_error(self, job_queue): + job_queue.run_repeating(self.job_with_exception, 0.01) + job_queue.run_repeating(self.job_run_once, 0.02) + sleep(0.03) + assert self.result == 1 + + def test_in_updater(self, bot): + u = Updater(bot=bot) u.job_queue.start() try: - u.job_queue.put(Job(self.job1, 0.5)) - sleep(0.75) - self.assertEqual(1, self.result) + u.job_queue.run_repeating(self.job_run_once, 0.02) + sleep(0.03) + assert self.result == 1 u.stop() - sleep(2) - self.assertEqual(1, self.result) + sleep(1) + assert self.result == 1 finally: u.stop() - def test_time_unit_int(self): + def test_time_unit_int(self, job_queue): # Testing seconds in int - delta = 2 + delta = 0.05 expected_time = time.time() + delta - self.jq.put(Job(self.job5, delta, repeat=False)) - sleep(2.5) - self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) + job_queue.run_once(self.job_datetime_tests, delta) + sleep(0.06) + assert pytest.approx(self.job_time) == expected_time - def test_time_unit_dt_timedelta(self): + def test_time_unit_dt_timedelta(self, job_queue): # Testing seconds, minutes and hours as datetime.timedelta object # This is sufficient to test that it actually works. - interval = datetime.timedelta(seconds=2) + interval = datetime.timedelta(seconds=0.05) expected_time = time.time() + interval.total_seconds() - self.jq.put(Job(self.job5, interval, repeat=False)) - sleep(2.5) - self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) + job_queue.run_once(self.job_datetime_tests, interval) + sleep(0.06) + assert pytest.approx(self.job_time) == expected_time - def test_time_unit_dt_datetime(self): + def test_time_unit_dt_datetime(self, job_queue): # Testing running at a specific datetime - delta = datetime.timedelta(seconds=2) - next_t = datetime.datetime.now() + delta + delta = datetime.timedelta(seconds=0.05) + when = datetime.datetime.now() + delta expected_time = time.time() + delta.total_seconds() - self.jq.put(Job(self.job5, repeat=False), next_t=next_t) - sleep(2.5) - self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) + job_queue.run_once(self.job_datetime_tests, when) + sleep(0.06) + assert pytest.approx(self.job_time) == expected_time - def test_time_unit_dt_time_today(self): + def test_time_unit_dt_time_today(self, job_queue): # Testing running at a specific time today - delta = 2 - next_t = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() + delta = 0.05 + when = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + delta - self.jq.put(Job(self.job5, repeat=False), next_t=next_t) - sleep(2.5) - self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) + job_queue.run_once(self.job_datetime_tests, when) + sleep(0.06) + assert pytest.approx(self.job_time) == expected_time - def test_time_unit_dt_time_tomorrow(self): + def test_time_unit_dt_time_tomorrow(self, job_queue): # Testing running at a specific time that has passed today. Since we can't wait a day, we # test if the jobs next_t has been calculated correctly delta = -2 - next_t = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() + when = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + delta + 60 * 60 * 24 - self.jq.put(Job(self.job5, repeat=False), next_t=next_t) - self.assertAlmostEqual(self.jq.queue.get(False)[0], expected_time, delta=0.1) + job_queue.run_once(self.job_datetime_tests, when) + assert pytest.approx(job_queue.queue.get(False)[0]) == expected_time - def test_run_once(self): - delta = 2 - expected_time = time.time() + delta - - self.jq.run_once(self.job5, delta) - sleep(2.5) - self.assertAlmostEqual(self.job_time, expected_time, delta=0.1) - - def test_run_repeating(self): - interval = 0.1 - first = 1.5 - - self.jq.run_repeating(self.job1, interval, first=first) - sleep(2.505) - self.assertAlmostEqual(self.result, 10, delta=1) - - def test_run_daily(self): - delta = 1 + def test_run_daily(self, job_queue): + delta = 0.5 time_of_day = (datetime.datetime.now() + datetime.timedelta(seconds=delta)).time() expected_time = time.time() + 60 * 60 * 24 + delta - self.jq.run_daily(self.job1, time_of_day) - sleep(2 * delta) - self.assertEqual(self.result, 1) - self.assertAlmostEqual(self.jq.queue.get(False)[0], expected_time, delta=0.1) + job_queue.run_daily(self.job_run_once, time_of_day) + sleep(0.6) + assert self.result == 1 + assert pytest.approx(job_queue.queue.get(False)[0]) == expected_time + def test_warnings(self, job_queue): + j = Job(self.job_run_once, repeat=False) + with pytest.warns(UserWarning): + job_queue.put(j, next_t=0) + j.schedule_removal() + with pytest.raises(ValueError, match='can not be set to'): + j.repeat = True + j.interval = 15 + assert j.interval_seconds == 15 + j.repeat = True + with pytest.raises(ValueError, match='can not be'): + j.interval = None + j.repeat = False + with pytest.raises(ValueError, match='must be of type'): + j.interval = 'every 3 minutes' + j.interval = 15 + assert j.interval_seconds == 15 -if __name__ == '__main__': - unittest.main() + with pytest.raises(ValueError, match='argument should be of type'): + j.days = 'every day' + with pytest.raises(ValueError, match='The elements of the'): + j.days = ('mon', 'wed') + with pytest.raises(ValueError, match='from 0 up to and'): + j.days = (0, 6, 12, 14) diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index fb6fd812a..117affcf2 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -1,76 +1,54 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -KeyboardButton""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import KeyboardButton -class KeyboardButtonTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram KeyboardButton.""" - - def setUp(self): - self.text = 'text' - self.request_location = True - self.request_contact = True - - self.json_dict = { - 'text': self.text, - 'request_location': self.request_location, - 'request_contact': self.request_contact, - } - - def test_keyboard_button_de_json(self): - keyboard_button = telegram.KeyboardButton.de_json(self.json_dict, self._bot) - - self.assertEqual(keyboard_button.text, self.text) - self.assertEqual(keyboard_button.request_location, self.request_location) - self.assertEqual(keyboard_button.request_contact, self.request_contact) - - def test_keyboard_button_de_json_empty(self): - keyboard_button = telegram.KeyboardButton.de_json(None, self._bot) - - self.assertFalse(keyboard_button) - - def test_keyboard_button_de_list_empty(self): - keyboard_button = telegram.KeyboardButton.de_list(None, self._bot) - - self.assertFalse(keyboard_button) - - def test_keyboard_button_to_json(self): - keyboard_button = telegram.KeyboardButton.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(keyboard_button.to_json())) - - def test_keyboard_button_to_dict(self): - keyboard_button = telegram.KeyboardButton.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(keyboard_button)) - self.assertDictEqual(self.json_dict, keyboard_button) +@pytest.fixture(scope='class') +def keyboard_button(): + return KeyboardButton(TestKeyboardButton.text, + request_location=TestKeyboardButton.request_location, + request_contact=TestKeyboardButton.request_contact) -if __name__ == '__main__': - unittest.main() +class TestKeyboardButton(object): + text = 'text' + request_location = True + request_contact = True + + def test_expected_values(self, keyboard_button): + assert keyboard_button.text == self.text + assert keyboard_button.request_location == self.request_location + assert keyboard_button.request_contact == self.request_contact + + def test_de_list(self, bot, keyboard_button): + keyboard_json = [keyboard_button.to_dict(), keyboard_button.to_dict()] + inline_keyboard_buttons = KeyboardButton.de_list(keyboard_json, bot) + + assert inline_keyboard_buttons == [keyboard_button, keyboard_button] + + def test_to_dict(self, keyboard_button): + keyboard_button_dict = keyboard_button.to_dict() + + assert isinstance(keyboard_button_dict, dict) + assert keyboard_button_dict['text'] == keyboard_button.text + assert keyboard_button_dict['request_location'] == keyboard_button.request_location + assert keyboard_button_dict['request_contact'] == keyboard_button.request_contact diff --git a/tests/test_labeledprice.py b/tests/test_labeledprice.py index ab03ed51a..958d93d8c 100644 --- a/tests/test_labeledprice.py +++ b/tests/test_labeledprice.py @@ -5,55 +5,39 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -LabeledPrice""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import LabeledPrice -class LabeledPriceTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram LabeledPrice.""" - - def setUp(self): - self.label = 'label' - self.amount = 100 - - self.json_dict = {'label': self.label, 'amount': self.amount} - - def test_labeledprice_de_json(self): - labeledprice = telegram.LabeledPrice.de_json(self.json_dict, self._bot) - - self.assertEqual(labeledprice.label, self.label) - self.assertEqual(labeledprice.amount, self.amount) - - def test_labeledprice_to_json(self): - labeledprice = telegram.LabeledPrice.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(labeledprice.to_json())) - - def test_labeledprice_to_dict(self): - labeledprice = telegram.LabeledPrice.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(labeledprice)) - self.assertDictEqual(self.json_dict, labeledprice) +@pytest.fixture(scope='class') +def labeled_price(): + return LabeledPrice(TestLabeledPrice.label, TestLabeledPrice.amount) -if __name__ == '__main__': - unittest.main() +class TestLabeledPrice(object): + label = 'label' + amount = 100 + + def test_expected_values(self, labeled_price): + assert labeled_price.label == self.label + assert labeled_price.amount == self.amount + + def test_to_dict(self, labeled_price): + labeled_price_dict = labeled_price.to_dict() + + assert isinstance(labeled_price_dict, dict) + assert labeled_price_dict['label'] == labeled_price.label + assert labeled_price_dict['amount'] == labeled_price.amount diff --git a/tests/test_location.py b/tests/test_location.py index fd1386b09..901c6002e 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -5,110 +5,67 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Location""" -import unittest -import sys +import pytest -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Location -class LocationTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Location.""" +@pytest.fixture(scope='class') +def location(): + return Location(latitude=TestLocation.latitude, longitude=TestLocation.longitude) - def setUp(self): - self.latitude = -23.691288 - self.longitude = -46.788279 - self.json_dict = {'latitude': self.latitude, 'longitude': self.longitude} +class TestLocation(object): + latitude = -23.691288 + longitude = -46.788279 - def test_send_location_implicit_args(self): - message = self._bot.sendLocation(self._chat_id, self.latitude, self.longitude) + def test_de_json(self, bot): + json_dict = {'latitude': TestLocation.latitude, + 'longitude': TestLocation.longitude} + location = Location.de_json(json_dict, bot) - location = message.location + assert location.latitude == self.latitude + assert location.longitude == self.longitude - self.assertEqual(location.latitude, self.latitude) - self.assertEqual(location.longitude, self.longitude) + def test_send_with_location(self, monkeypatch, bot, chat_id, location): + def test(_, url, data, **kwargs): + lat = data['latitude'] == location.latitude + lon = data['longitude'] == location.longitude + return lat and lon - def test_send_location_explicit_args(self): - message = self._bot.sendLocation( - chat_id=self._chat_id, latitude=self.latitude, longitude=self.longitude) + monkeypatch.setattr('telegram.utils.request.Request.post', test) + assert bot.send_location(location=location, chat_id=chat_id) - location = message.location + def test_send_location_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match='Either location or latitude and longitude'): + bot.send_location(chat_id=chat_id) - self.assertEqual(location.latitude, self.latitude) - self.assertEqual(location.longitude, self.longitude) + def test_to_dict(self, location): + location_dict = location.to_dict() - def test_send_location_with_location(self): - loc = telegram.Location(longitude=self.longitude, latitude=self.latitude) - message = self._bot.send_location(location=loc, chat_id=self._chat_id) - location = message.location - - self.assertEqual(location, loc) - - def test_location_de_json(self): - location = telegram.Location.de_json(self.json_dict, self._bot) - - self.assertEqual(location.latitude, self.latitude) - self.assertEqual(location.longitude, self.longitude) - - def test_location_to_json(self): - location = telegram.Location.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(location.to_json())) - - def test_location_to_dict(self): - location = telegram.Location.de_json(self.json_dict, self._bot) - - self.assertEqual(location['latitude'], self.latitude) - self.assertEqual(location['longitude'], self.longitude) - - def test_error_location_without_required_args(self): - json_dict = self.json_dict - - del (json_dict['latitude']) - del (json_dict['longitude']) - - with self.assertRaises(ValueError): - self._bot.sendLocation(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - def test_reply_location(self): - """Test for Message.reply_location""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_location(self.latitude, self.longitude) - - self.assertEqual(message.location.latitude, self.latitude) - self.assertEqual(message.location.longitude, self.longitude) + assert location_dict['latitude'] == location.latitude + assert location_dict['longitude'] == location.longitude def test_equality(self): - a = telegram.Location(self.longitude, self.latitude) - b = telegram.Location(self.longitude, self.latitude) - d = telegram.Location(0, self.latitude) + a = Location(self.longitude, self.latitude) + b = Location(self.longitude, self.latitude) + d = Location(0, self.latitude) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - -if __name__ == '__main__': - unittest.main() + assert a != d + assert hash(a) != hash(d) diff --git a/tests/test_message.py b/tests/test_message.py index 893ad09e1..9208de1c5 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -1,222 +1,432 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Message""" +from datetime import datetime -import sys -import unittest +import pytest -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import (Update, Message, User, MessageEntity, Chat, Audio, Document, + Game, PhotoSize, Sticker, Video, Voice, VideoNote, Contact, Location, Venue, + Invoice, SuccessfulPayment) -class MessageTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram MessageTest.""" +@pytest.fixture(scope='class') +def message(bot): + return Message(TestMessage.id, TestMessage.from_user, TestMessage.date, TestMessage.chat, + bot=bot) - def setUp(self): - self.test_entities = [ - { - 'length': 4, - 'offset': 10, - 'type': 'bold' - }, - { - 'length': 7, - 'offset': 16, - 'type': 'italic' - }, - { - 'length': 4, - 'offset': 25, - 'type': 'code' - }, - { - 'length': 5, - 'offset': 31, - 'type': 'text_link', - 'url': 'http://github.com/' - }, - { - 'length': 3, - 'offset': 41, - 'type': 'pre' - }, - ] - self.test_text = 'Test for bold, ita_lic, code, ' + 'links and

pre
. ' + 'http://google.com') text_html = self.test_message.text_html - self.assertEquals(test_html_string, text_html) + assert text_html == test_html_string + + def test_text_html_urled(self): + test_html_string = ('Test for <bold, ita_lic, code, ' + 'links and
pre
. ' + 'http://google.com') + text_html = self.test_message.text_html_urled + assert text_html == test_html_string def test_text_markdown_simple(self): - test_md_string = 'Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and ```pre```.' + test_md_string = ('Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and ' + '```pre```. http://google.com') text_markdown = self.test_message.text_markdown - self.assertEquals(test_md_string, text_markdown) + assert text_markdown == test_md_string + + def test_text_markdown_urled(self): + test_md_string = ('Test for <*bold*, _ita\_lic_, `code`, [links](http://github.com/) and ' + '```pre```. [http://google.com](http://google.com)') + text_markdown = self.test_message.text_markdown_urled + assert text_markdown == test_md_string def test_text_html_emoji(self): - text = (b'\\U0001f469\\u200d\\U0001f469\\u200d ABC').decode('unicode-escape') - expected = (b'\\U0001f469\\u200d\\U0001f469\\u200d ABC').decode('unicode-escape') - bold_entity = telegram.MessageEntity(type=telegram.MessageEntity.BOLD, offset=7, length=3) - message = telegram.Message( - message_id=1, from_user=None, date=None, chat=None, text=text, entities=[bold_entity]) - self.assertEquals(expected, message.text_html) + text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') + expected = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') + bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) + message = Message(1, self.from_user, self.date, self.chat, + text=text, entities=[bold_entity]) + assert expected == message.text_html def test_text_markdown_emoji(self): - text = (b'\\U0001f469\\u200d\\U0001f469\\u200d ABC').decode('unicode-escape') - expected = (b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*').decode('unicode-escape') - bold_entity = telegram.MessageEntity(type=telegram.MessageEntity.BOLD, offset=7, length=3) - message = telegram.Message( - message_id=1, from_user=None, date=None, chat=None, text=text, entities=[bold_entity]) - self.assertEquals(expected, message.text_markdown) + text = b'\\U0001f469\\u200d\\U0001f469\\u200d ABC'.decode('unicode-escape') + expected = b'\\U0001f469\\u200d\\U0001f469\\u200d *ABC*'.decode('unicode-escape') + bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) + message = Message(1, self.from_user, self.date, self.chat, + text=text, entities=[bold_entity]) + assert expected == message.text_markdown def test_parse_entities_url_emoji(self): url = b'http://github.com/?unicode=\\u2713\\U0001f469'.decode('unicode-escape') text = 'some url' - link_entity = telegram.MessageEntity(type=telegram.MessageEntity.URL, offset=0, length=8, url=url) - message = telegram.Message( - message_id=1, - from_user=None, - date=None, - chat=None, - text=text, - entities=[link_entity]) - self.assertDictEqual(message.parse_entities(), {link_entity: text}) - self.assertEqual(next(iter(message.parse_entities())).url, url) + link_entity = MessageEntity(type=MessageEntity.URL, offset=0, length=8, url=url) + message = Message(1, self.from_user, self.date, self.chat, + text=text, entities=[link_entity]) + assert message.parse_entities() == {link_entity: text} + assert next(iter(message.parse_entities())).url == url - @flaky(3, 1) - def test_reply_text(self): - """Test for Message.reply_text""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_text('Testing class method') + def test_chat_id(self, message): + assert message.chat_id == message.chat.id - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, 'Testing class method') - - @flaky(3, 1) - def test_forward(self): - """Test for Message.forward""" - message = self._bot.sendMessage(self._chat_id, 'Testing class method') - message = message.forward(self._chat_id) - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, 'Testing class method') - - @flaky(3, 1) - def test_edit_text(self): - """Test for Message.edit_text""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.edit_text('Testing class method') - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, 'Testing class method') - - @flaky(3, 1) - def test_delete1(self): - """Test for Message.delete""" - message = self._bot.send_message( - chat_id=self._chat_id, text='This message will be deleted') - - self.assertTrue(message.delete()) - - @flaky(3, 1) - def test_delete2(self): - """Another test for Message.delete""" - message = self._bot.send_message( - chat_id=self._chat_id, - text='This ^ message will not be deleted', - reply_to_message_id=1) - - with self.assertRaisesRegexp(telegram.TelegramError, "can't be deleted"): - message.reply_to_message.delete() - - def test_equality(self): - _id = 1 - a = telegram.Message(_id, telegram.User(1, ""), None, None) - b = telegram.Message(_id, telegram.User(1, ""), None, None) - c = telegram.Message(_id, telegram.User(0, ""), None, None) - d = telegram.Message(0, telegram.User(1, ""), None, None) - e = telegram.Update(_id) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - def test_effective_attachment(self): + def test_effective_attachment(self, message_params): for i in ('audio', 'game', 'document', 'photo', 'sticker', 'video', 'voice', 'video_note', 'contact', 'location', 'venue', 'invoice', 'invoice', 'successful_payment'): - dummy = object() - kwargs = {i: dummy} - msg = telegram.Message(1, telegram.User(1, ""), None, None, **kwargs) - self.assertIs(msg.effective_attachment, dummy, - 'invalid {} effective attachment'.format(i)) - - msg = telegram.Message(1, telegram.User(1, ""), None, None) - self.assertIsNone(msg.effective_attachment) + item = getattr(message_params, i, None) + if item: + break + else: + item = None + assert message_params.effective_attachment == item -if __name__ == '__main__': - unittest.main() + def test_reply_text(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + text = args[2] == 'test' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and text and reply + + monkeypatch.setattr('telegram.Bot.send_message', test) + assert message.reply_text('test') + assert message.reply_text('test', quote=True) + assert message.reply_text('test', reply_to_message_id=message.message_id, quote=True) + + def test_reply_photo(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + photo = kwargs['photo'] == 'test_photo' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and photo and reply + + monkeypatch.setattr('telegram.Bot.send_photo', test) + assert message.reply_photo(photo='test_photo') + assert message.reply_photo(photo='test_photo', quote=True) + + def test_reply_audio(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + audio = kwargs['audio'] == 'test_audio' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and audio and reply + + monkeypatch.setattr('telegram.Bot.send_audio', test) + assert message.reply_audio(audio='test_audio') + assert message.reply_audio(audio='test_audio', quote=True) + + def test_reply_document(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + document = kwargs['document'] == 'test_document' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and document and reply + + monkeypatch.setattr('telegram.Bot.send_document', test) + assert message.reply_document(document='test_document') + assert message.reply_document(document='test_document', quote=True) + + def test_reply_sticker(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + sticker = kwargs['sticker'] == 'test_sticker' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and sticker and reply + + monkeypatch.setattr('telegram.Bot.send_sticker', test) + assert message.reply_sticker(sticker='test_sticker') + assert message.reply_sticker(sticker='test_sticker', quote=True) + + def test_reply_video(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + video = kwargs['video'] == 'test_video' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and video and reply + + monkeypatch.setattr('telegram.Bot.send_video', test) + assert message.reply_video(video='test_video') + assert message.reply_video(video='test_video', quote=True) + + def test_reply_video_note(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + video_note = kwargs['video_note'] == 'test_video_note' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and video_note and reply + + monkeypatch.setattr('telegram.Bot.send_video_note', test) + assert message.reply_video_note(video_note='test_video_note') + assert message.reply_video_note(video_note='test_video_note', quote=True) + + def test_reply_voice(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + voice = kwargs['voice'] == 'test_voice' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and voice and reply + + monkeypatch.setattr('telegram.Bot.send_voice', test) + assert message.reply_voice(voice='test_voice') + assert message.reply_voice(voice='test_voice', quote=True) + + def test_reply_location(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + location = kwargs['location'] == 'test_location' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and location and reply + + monkeypatch.setattr('telegram.Bot.send_location', test) + assert message.reply_location(location='test_location') + assert message.reply_location(location='test_location', quote=True) + + def test_reply_venue(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + venue = kwargs['venue'] == 'test_venue' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and venue and reply + + monkeypatch.setattr('telegram.Bot.send_venue', test) + assert message.reply_venue(venue='test_venue') + assert message.reply_venue(venue='test_venue', quote=True) + + def test_reply_contact(self, monkeypatch, message): + def test(*args, **kwargs): + id = args[1] == message.chat_id + contact = kwargs['contact'] == 'test_contact' + if kwargs.get('reply_to_message_id'): + reply = kwargs['reply_to_message_id'] == message.message_id + else: + reply = True + return id and contact and reply + + monkeypatch.setattr('telegram.Bot.send_contact', test) + assert message.reply_contact(contact='test_contact') + assert message.reply_contact(contact='test_contact', quote=True) + + def test_forward(self, monkeypatch, message): + def test(*args, **kwargs): + chat_id = kwargs['chat_id'] == 123456 + from_chat = kwargs['from_chat_id'] == message.chat_id + message_id = kwargs['message_id'] == message.message_id + if kwargs.get('disable_notification'): + notification = kwargs['disable_notification'] is True + else: + notification = True + return chat_id and from_chat and message_id and notification + + monkeypatch.setattr('telegram.Bot.forward_message', test) + assert message.forward(123456) + assert message.forward(123456, disable_notification=True) + assert not message.forward(635241) + + def test_edit_text(self, monkeypatch, message): + def test(*args, **kwargs): + chat_id = kwargs['chat_id'] == message.chat_id + message_id = kwargs['message_id'] == message.message_id + text = kwargs['text'] == 'test' + return chat_id and message_id and text + + monkeypatch.setattr('telegram.Bot.edit_message_text', test) + assert message.edit_text(text='test') + + def test_edit_caption(self, monkeypatch, message): + def test(*args, **kwargs): + chat_id = kwargs['chat_id'] == message.chat_id + message_id = kwargs['message_id'] == message.message_id + caption = kwargs['caption'] == 'new caption' + return chat_id and message_id and caption + + monkeypatch.setattr('telegram.Bot.edit_message_caption', test) + assert message.edit_caption(caption='new caption') + + def test_edit_reply_markup(self, monkeypatch, message): + def test(*args, **kwargs): + chat_id = kwargs['chat_id'] == message.chat_id + message_id = kwargs['message_id'] == message.message_id + reply_markup = kwargs['reply_markup'] == [['1', '2']] + return chat_id and message_id and reply_markup + + monkeypatch.setattr('telegram.Bot.edit_message_reply_markup', test) + assert message.edit_reply_markup(reply_markup=[['1', '2']]) + + def test_delete(self, monkeypatch, message): + def test(*args, **kwargs): + chat_id = kwargs['chat_id'] == message.chat_id + message_id = kwargs['message_id'] == message.message_id + return chat_id and message_id + + monkeypatch.setattr('telegram.Bot.delete_message', test) + assert message.delete() + + def test_equality(self): + id = 1 + a = Message(id, self.from_user, self.date, self.chat) + b = Message(id, self.from_user, self.date, self.chat) + c = Message(id, User(0, ''), self.date, self.chat) + d = Message(0, self.from_user, self.date, self.chat) + e = Update(id) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 8483a68d7..24a64f7fd 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -5,64 +5,62 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -MessageEntity""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import MessageEntity, User -class MessageEntityTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram MessageEntity.""" +@pytest.fixture(scope="class", + params=MessageEntity.ALL_TYPES) +def message_entity(request): + type = request.param + url = None + if type == MessageEntity.TEXT_LINK: + url = 't.me' + user = None + if type == MessageEntity.TEXT_MENTION: + user = User(1, 'test_user') + return MessageEntity(type, 1, 3, url=url, user=user) - def setUp(self): - self.type = 'type' - self.offset = 1 - self.length = 2 - self.url = 'url' - self.json_dict = { +class TestMessageEntity(object): + type = 'url' + offset = 1 + length = 2 + url = 'url' + + def test_de_json(self, bot): + json_dict = { 'type': self.type, 'offset': self.offset, - 'length': self.length, - 'url': self.url + 'length': self.length } + entity = MessageEntity.de_json(json_dict, bot) - def test_messageentity_de_json(self): - entity = telegram.MessageEntity.de_json(self.json_dict, self._bot) + assert entity.type == self.type + assert entity.offset == self.offset + assert entity.length == self.length - self.assertEqual(entity.type, self.type) - self.assertEqual(entity.offset, self.offset) - self.assertEqual(entity.length, self.length) - self.assertEqual(entity.url, self.url) + def test_to_dict(self, message_entity): + entity_dict = message_entity.to_dict() - def test_messageentity_to_json(self): - entity = telegram.MessageEntity.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(entity.to_json())) - - def test_messageentity_to_dict(self): - entity = telegram.MessageEntity.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(entity)) - self.assertDictEqual(self.json_dict, entity) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(entity_dict, dict) + assert entity_dict['type'] == message_entity.type + assert entity_dict['offset'] == message_entity.offset + assert entity_dict['length'] == message_entity.length + if message_entity.url: + assert entity_dict['url'] == message_entity.url + if message_entity.user: + assert entity_dict['user'] == message_entity.user.to_dict() diff --git a/tests/test_messagehandler.py b/tests/test_messagehandler.py new file mode 100644 index 000000000..fb11dd67e --- /dev/null +++ b/tests/test_messagehandler.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import Filters, MessageHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('callback_query', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='class') +def message(bot): + return Message(1, None, None, None, bot=bot) + + +class TestMessageHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def test_basic(self, dp, message): + handler = MessageHandler(None, self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(Update(0, message)) + dp.process_update(Update(0, message)) + assert self.test_flag + + def test_edited(self, message): + handler = MessageHandler(None, self.callback_basic, edited_updates=True, + message_updates=False, channel_post_updates=False) + + assert handler.check_update(Update(0, edited_message=message)) + assert not handler.check_update(Update(0, message=message)) + assert not handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_channel_post(self, message): + handler = MessageHandler(None, self.callback_basic, edited_updates=False, + message_updates=False, channel_post_updates=True) + + assert not handler.check_update(Update(0, edited_message=message)) + assert not handler.check_update(Update(0, message=message)) + assert handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_multiple_flags(self, message): + handler = MessageHandler(None, self.callback_basic, edited_updates=True, + message_updates=True, channel_post_updates=True) + + assert handler.check_update(Update(0, edited_message=message)) + assert handler.check_update(Update(0, message=message)) + assert handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_allow_updated(self, message): + with pytest.warns(UserWarning): + handler = MessageHandler(None, self.callback_basic, message_updates=True, + allow_edited=True) + + assert handler.check_update(Update(0, edited_message=message)) + assert handler.check_update(Update(0, message=message)) + assert handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_none_allowed(self): + with pytest.raises(ValueError, match='are all False'): + handler = MessageHandler(None, self.callback_basic, message_updates=False, + channel_post_updates=False, edited_updates=False) + + def test_with_filter(self, message): + handler = MessageHandler(Filters.command, self.callback_basic) + + message.text = '/test' + assert handler.check_update(Update(0, message)) + + message.text = 'test' + assert not handler.check_update(Update(0, message)) + + def test_pass_user_or_chat_data(self, dp, message): + handler = MessageHandler(None, self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = MessageHandler(None, self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = MessageHandler(None, self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, message): + handler = MessageHandler(None, self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = MessageHandler(None, self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = MessageHandler(None, self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = MessageHandler(None, self.callback_basic, edited_updates=True) + assert not handler.check_update(false_update) diff --git a/tests/test_messagequeue.py b/tests/test_messagequeue.py index 3aa33c75a..50e0def08 100644 --- a/tests/test_messagequeue.py +++ b/tests/test_messagequeue.py @@ -1,91 +1,63 @@ -'''This module contains telegram.ext.messagequeue test logic''' -from __future__ import print_function, division +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. -import sys -import os -import time -import unittest +from time import sleep -sys.path.insert(0, os.path.dirname(__file__) + os.sep + '..') -from tests.base import BaseTest - -from telegram.ext import messagequeue as mq +import telegram.ext.messagequeue as mq -class DelayQueueTest(BaseTest, unittest.TestCase): +class TestDelayQueue(object): + N = 128 + burst_limit = 30 + time_limit_ms = 1000 + margin_ms = 0 + testtimes = [] - def __init__(self, *args, **kwargs): - self._N = kwargs.pop('N', 128) - self._msglimit = kwargs.pop('burst_limit', 30) - self._timelimit = kwargs.pop('time_limit_ms', 1000) - self._margin = kwargs.pop('margin_ms', 0) - isprint = kwargs.pop('isprint', False) - - def noprint(*args, **kwargs): - pass - - self._print = print if isprint else noprint - super(DelayQueueTest, self).__init__(*args, **kwargs) - - def setUp(self): - print = self._print - print('Self-test with N = {} msgs, burst_limit = {} msgs, ' - 'time_limit = {:.2f} ms, margin = {:.2f} ms' - ''.format(self._N, self._msglimit, self._timelimit, self._margin)) - self.testtimes = [] - - def testcall(): - self.testtimes.append(mq.curtime()) - - self.testcall = testcall + def call(self): + self.testtimes.append(mq.curtime()) def test_delayqueue_limits(self): - '''Test that DelayQueue dispatched calls don't hit time-window limit''' - print = self._print - dsp = mq.DelayQueue( - burst_limit=self._msglimit, time_limit_ms=self._timelimit, autostart=True) - print('Started dispatcher {}\nStatus: {}' - ''.format(dsp, ['inactive', 'active'][dsp.is_alive()])) - self.assertTrue(dsp.is_alive()) + dsp = mq.DelayQueue(burst_limit=self.burst_limit, time_limit_ms=self.time_limit_ms, + autostart=True) + assert dsp.is_alive() is True - print('Dispatching {} calls @ {}'.format(self._N, time.asctime())) - - for i in range(self._N): - dsp(self.testcall) - - print('Queue filled, waiting 4 dispatch finish @ ' + str(time.asctime())) + for i in range(self.N): + dsp(self.call) starttime = mq.curtime() app_endtime = ( - (self._N * self._msglimit / - (1000 * self._timelimit)) + starttime + 20) # wait up to 20 sec more than needed + (self.N * self.burst_limit / + (1000 * self.time_limit_ms)) + starttime + 20) # wait up to 20 sec more than needed while not dsp._queue.empty() and mq.curtime() < app_endtime: - time.sleep(1) - self.assertTrue(dsp._queue.empty()) # check loop exit condition + sleep(1) + assert dsp._queue.empty() is True # check loop exit condition dsp.stop() - print('Dispatcher ' + ['stopped', '!NOT STOPPED!'][dsp.is_alive()] + ' @ ' + str( - time.asctime())) - self.assertFalse(dsp.is_alive()) + assert dsp.is_alive() is False - self.assertTrue(self.testtimes or self._N == 0) - print('Calculating call time windows') + assert self.testtimes or self.N == 0 is True passes, fails = [], [] - delta = (self._timelimit - self._margin) / 1000 - it = enumerate(range(self._msglimit + 1, len(self.testtimes))) - for start, stop in it: + delta = (self.time_limit_ms - self.margin_ms) / 1000 + for start, stop in enumerate(range(self.burst_limit + 1, len(self.testtimes))): part = self.testtimes[start:stop] if (part[-1] - part[0]) >= delta: passes.append(part) else: fails.append(part) - - print('Tested: {}, Passed: {}, Failed: {}' - ''.format(len(passes + fails), len(passes), len(fails))) - if fails: - print('(!) Got mismatches: ' + ';\n'.join(map(str, fails))) - self.assertFalse(fails) - - -if __name__ == '__main__': - unittest.main() + assert fails == [] diff --git a/tests/test_meta.py b/tests/test_meta.py new file mode 100644 index 000000000..472361c9d --- /dev/null +++ b/tests/test_meta.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import os +import subprocess +import sys +from platform import python_implementation + +import pytest + + +def call_pre_commit_hook(hook_id): + __tracebackhide__ = True + return subprocess.call(['pre-commit', 'run', '--all-files', hook_id]) + + +@pytest.mark.parametrize('hook_id', argvalues=('yapf', 'flake8', 'pylint')) +@pytest.mark.skipif(not os.getenv('TRAVIS'), reason='Not running in travis.') +@pytest.mark.skipif(not sys.version_info[:2] == (3, 6) or python_implementation() != 'CPython', + reason='Only running pre-commit-hooks on newest tested python version, ' + 'as they are slow and consistent across platforms.') +def test_pre_commit_hook(hook_id): + assert call_pre_commit_hook(hook_id) == 0 + + +def test_build(): + assert subprocess.call(['python', 'setup.py', 'bdist_dumb']) == 0 diff --git a/tests/test_official.py b/tests/test_official.py index ba2bae649..8e106cbac 100644 --- a/tests/test_official.py +++ b/tests/test_official.py @@ -1,11 +1,28 @@ -import sys +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. import inspect -import warnings +import sys from collections import namedtuple -import platform +from platform import python_implementation import certifi -import logging +import pytest from bs4 import BeautifulSoup sys.path.append('.') @@ -16,8 +33,6 @@ import telegram IGNORED_OBJECTS = ('ResponseParameters', 'CallbackGame') IGNORED_PARAMETERS = {'self', 'args', 'kwargs', 'read_latency', 'network_delay', 'timeout', 'bot'} -logger = logging.getLogger(__name__) - def find_next_sibling_until(tag, name, until): for sibling in tag.next_siblings: @@ -50,7 +65,6 @@ def check_method(h4): checked = [] for parameter in table: param = sig.parameters.get(parameter.Parameters) - logger.debug(parameter) assert param is not None # TODO: Check type via docstring # TODO: Check if optional or required @@ -70,8 +84,6 @@ def check_method(h4): elif name == 'sendVenue': ignored |= {'venue'} # Added for ease of use - logger.debug((sig.parameters.keys(), checked, ignored, - sig.parameters.keys() - checked - ignored)) assert (sig.parameters.keys() ^ checked) - ignored == set() @@ -94,7 +106,6 @@ def check_object(h4): continue param = sig.parameters.get(field) - logger.debug(parameter) assert param is not None # TODO: Check type via docstring # TODO: Check if optional or required @@ -111,50 +122,34 @@ def check_object(h4): if name.startswith('InlineQueryResult'): ignored |= {'type'} - logger.debug((sig.parameters.keys(), checked, ignored, - sig.parameters.keys() - checked - ignored)) assert (sig.parameters.keys() ^ checked) - ignored == set() -def test_official(): - if not sys.version_info >= (3, 5) or platform.python_implementation() != 'CPython': - warnings.warn('Not running "official" tests, since follow_wrapped is not supported' - 'on this platform (cpython version >= 3.5 required)') - return +argvalues = [] +names = [] +http = urllib3.PoolManager( + cert_reqs='CERT_REQUIRED', + ca_certs=certifi.where()) +request = http.request('GET', 'https://core.telegram.org/bots/api') +soup = BeautifulSoup(request.data.decode('utf-8'), 'html.parser') - http = urllib3.PoolManager( - cert_reqs='CERT_REQUIRED', - ca_certs=certifi.where()) - request = http.request('GET', 'https://core.telegram.org/bots/api') - soup = BeautifulSoup(request.data.decode('utf-8'), 'html.parser') +for thing in soup.select('h4 > a.anchor'): + # Methods and types don't have spaces in them, luckily all other sections of the docs do + # TODO: don't depend on that + if '-' not in thing['name']: + h4 = thing.parent - for thing in soup.select('h4 > a.anchor'): - # Methods and types don't have spaces in them, luckily all other sections of the docs do - # TODO: don't depend on that - if '-' not in thing['name']: - h4 = thing.parent - name = h4.text - - test = None - # Is it a method - if h4.text[0].lower() == h4.text[0]: - test = check_method - else: # Or a type/object - if name not in IGNORED_OBJECTS: - test = check_object - - if test: - def fn(): - return test(h4) - fn.description = '{}({}) ({})'.format(test.__name__, h4.text, __name__) - yield fn + # Is it a method + if h4.text[0].lower() == h4.text[0]: + argvalues.append((check_method, h4)) + names.append(h4.text) + elif h4.text not in IGNORED_OBJECTS: # Or a type/object + argvalues.append((check_object, h4)) + names.append(h4.text) -if __name__ == '__main__': - # Since we don't have the nice unittest asserts which show the comparison - # We turn on debugging - logging.basicConfig( - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=logging.DEBUG) - for f in test_official(): - f() +@pytest.mark.parametrize(('method', 'data'), argvalues=argvalues, ids=names) +@pytest.mark.skipif(not sys.version_info >= (3, 5) or python_implementation() != 'CPython', + reason='follow_wrapped (inspect.signature) is not supported on this platform') +def test_official(method, data): + method(data) diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index 87d0522d8..03da929d4 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -5,65 +5,54 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -OrderInfo""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ShippingAddress, OrderInfo -class OrderInfoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram OrderInfo.""" +@pytest.fixture(scope='class') +def order_info(): + return OrderInfo(TestOrderInfo.name, TestOrderInfo.phone_number, + TestOrderInfo.email, TestOrderInfo.shipping_address) - def setUp(self): - self.name = 'name' - self.phone_number = 'phone_number' - self.email = 'email' - self.shipping_address = telegram.ShippingAddress('GB', '', 'London', '12 Grimmauld Place', - '', 'WC1') - self.json_dict = { - 'name': self.name, - 'phone_number': self.phone_number, - 'email': self.email, - 'shipping_address': self.shipping_address.to_dict() +class TestOrderInfo(object): + name = 'name' + phone_number = 'phone_number' + email = 'email' + shipping_address = ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1') + + def test_de_json(self, bot): + json_dict = { + 'name': TestOrderInfo.name, + 'phone_number': TestOrderInfo.phone_number, + 'email': TestOrderInfo.email, + 'shipping_address': TestOrderInfo.shipping_address.to_dict() } + order_info = OrderInfo.de_json(json_dict, bot) - def test_orderinfo_de_json(self): - orderinfo = telegram.OrderInfo.de_json(self.json_dict, self._bot) + assert order_info.name == self.name + assert order_info.phone_number == self.phone_number + assert order_info.email == self.email + assert order_info.shipping_address == self.shipping_address - self.assertEqual(orderinfo.name, self.name) - self.assertEqual(orderinfo.phone_number, self.phone_number) - self.assertEqual(orderinfo.email, self.email) - self.assertEqual(orderinfo.shipping_address, self.shipping_address) + def test_to_dict(self, order_info): + order_info_dict = order_info.to_dict() - def test_orderinfo_to_json(self): - orderinfo = telegram.OrderInfo.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(orderinfo.to_json())) - - def test_orderinfo_to_dict(self): - orderinfo = telegram.OrderInfo.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(orderinfo)) - self.assertDictEqual(self.json_dict, orderinfo) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(order_info_dict, dict) + assert order_info_dict['name'] == order_info.name + assert order_info_dict['phone_number'] == order_info.phone_number + assert order_info_dict['email'] == order_info.email + assert order_info_dict['shipping_address'] == order_info.shipping_address.to_dict() diff --git a/tests/test_parsemode.py b/tests/test_parsemode.py index f487d5d3d..f2b969c36 100644 --- a/tests/test_parsemode.py +++ b/tests/test_parsemode.py @@ -1,55 +1,38 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram ParseMode""" -import sys -import unittest - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ParseMode -class ParseMode(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ParseMode.""" +class TestParseMode(object): + markdown_text = '*bold* _italic_ [link](http://google.com).' + html_text = 'bold italic link.' + formatted_text_formatted = u'bold italic link.' - def setUp(self): - self.markdown_text = "*bold* _italic_ [link](http://google.com)." - self.html_text = 'bold italic link.' - self.formatted_text_formatted = u'bold italic link.' + def test_send_message_with_parse_mode_markdown(self, bot, chat_id): + message = bot.send_message(chat_id=chat_id, text=self.markdown_text, + parse_mode=ParseMode.MARKDOWN) - def test_send_message_with_parse_mode_markdown(self): - message = self._bot.sendMessage( - chat_id=self._chat_id, text=self.markdown_text, parse_mode=telegram.ParseMode.MARKDOWN) + assert message.text == self.formatted_text_formatted - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, self.formatted_text_formatted) + def test_send_message_with_parse_mode_html(self, bot, chat_id): + message = bot.send_message(chat_id=chat_id, text=self.html_text, + parse_mode=ParseMode.HTML) - def test_send_message_with_parse_mode_html(self): - message = self._bot.sendMessage( - chat_id=self._chat_id, text=self.html_text, parse_mode=telegram.ParseMode.HTML) - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, self.formatted_text_formatted) - - -if __name__ == '__main__': - unittest.main() + assert message.text == self.formatted_text_formatted diff --git a/tests/test_photo.py b/tests/test_photo.py index e29400ff6..7bfcd4b62 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -5,305 +5,263 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Photo""" - import os -import unittest from io import BytesIO +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import Sticker, TelegramError, PhotoSize, InputFile -class PhotoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Photo.""" +@pytest.fixture(scope='function') +def photo_file(): + f = open('tests/data/telegram.jpg', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(PhotoTest, cls).setUpClass() - cls.caption = u'PhotoTest - Caption' - cls.photo_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.jpg' +@pytest.fixture(scope='class') +def _photo(bot, chat_id): + with open('tests/data/telegram.jpg', 'rb') as f: + return bot.send_photo(chat_id, photo=f, timeout=10).photo - photo_file = open('tests/data/telegram.jpg', 'rb') - photo = cls._bot.send_photo(cls._chat_id, photo=photo_file, timeout=10).photo - cls.thumb, cls.photo = photo +@pytest.fixture(scope='class') +def thumb(_photo): + return _photo[0] + + +@pytest.fixture(scope='class') +def photo(_photo): + return _photo[1] + + +class TestPhoto(object): + width = 300 + height = 300 + caption = u'PhotoTest - Caption' + photo_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.jpg' + file_size = 10209 + + def test_creation(self, thumb, photo): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.photo, telegram.PhotoSize) - assert isinstance(cls.thumb, telegram.PhotoSize) - assert isinstance(cls.photo.file_id, str) - assert isinstance(cls.thumb.file_id, str) - assert cls.photo.file_id is not '' - assert cls.thumb.file_id is not '' + assert isinstance(photo, PhotoSize) + assert isinstance(photo.file_id, str) + assert photo.file_id is not '' - def setUp(self): - self.photo_file = open('tests/data/telegram.jpg', 'rb') - self.photo_bytes_jpg_no_standard = 'tests/data/telegram_no_standard_header.jpg' - self.json_dict = { - 'file_id': self.photo.file_id, - 'width': self.photo.width, - 'height': self.photo.height, - 'file_size': self.photo.file_size - } + assert isinstance(thumb, PhotoSize) + assert isinstance(thumb.file_id, str) + assert thumb.file_id is not '' - def test_expected_values(self): - self.assertEqual(self.photo.width, 300) - self.assertEqual(self.photo.height, 300) - self.assertEqual(self.photo.file_size, 10209) - self.assertEqual(self.thumb.width, 90) - self.assertEqual(self.thumb.height, 90) - self.assertEqual(self.thumb.file_size, 1478) + def test_expected_values(self, photo, thumb): + assert photo.width == self.width + assert photo.height == self.height + assert photo.file_size == self.file_size + assert thumb.width == 90 + assert thumb.height == 90 + assert thumb.file_size == 1478 @flaky(3, 1) - @timeout(10) - def test_sendphoto_all_args(self): - message = self._bot.sendPhoto(self._chat_id, self.photo_file, caption=self.caption, disable_notification=False) - thumb, photo = message.photo + @pytest.mark.timeout(10) + def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo): + message = bot.send_photo(chat_id, photo_file, caption=self.caption, + disable_notification=False) - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertIsInstance(thumb.file_id, str) - self.assertNotEqual(thumb.file_id, '') - self.assertEqual(thumb.width, self.thumb.width) - self.assertEqual(thumb.height, self.thumb.height) - self.assertEqual(thumb.file_size, self.thumb.file_size) + assert isinstance(message.photo[0], PhotoSize) + assert isinstance(message.photo[0].file_id, str) + assert message.photo[0].file_id != '' + assert message.photo[0].width == thumb.width + assert message.photo[0].height == thumb.height + assert message.photo[0].file_size == thumb.file_size - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') - self.assertEqual(photo.width, self.photo.width) - self.assertEqual(photo.height, self.photo.height) - self.assertEqual(photo.file_size, self.photo.file_size) + assert isinstance(message.photo[1], PhotoSize) + assert isinstance(message.photo[1].file_id, str) + assert message.photo[1].file_id != '' + assert message.photo[1].width == photo.width + assert message.photo[1].height == photo.height + assert message.photo[1].file_size == photo.file_size - self.assertEqual(message.caption, self.caption) + assert message.caption == TestPhoto.caption @flaky(3, 1) - @timeout(10) - def test_get_and_download_photo(self): - new_file = self._bot.getFile(self.photo.file_id) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, photo): + new_file = bot.getFile(photo.file_id) - self.assertEqual(new_file.file_size, self.photo.file_size) - self.assertEqual(new_file.file_id, self.photo.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == photo.file_size + assert new_file.file_id == photo.file_id + assert new_file.file_path.startswith('https://') is True new_file.download('telegram.jpg') - self.assertTrue(os.path.isfile('telegram.jpg')) - + assert os.path.isfile('telegram.jpg') is True @flaky(3, 1) - @timeout(10) - def test_send_photo_url_jpg_file(self): - message = self._bot.sendPhoto(self._chat_id, photo=self.photo_file_url) + @pytest.mark.timeout(10) + def test_send_url_jpg_file(self, bot, chat_id, thumb, photo): + message = bot.send_photo(chat_id, photo=self.photo_file_url) - thumb, photo = message.photo + assert isinstance(message.photo[0], PhotoSize) + assert isinstance(message.photo[0].file_id, str) + assert message.photo[0].file_id != '' + assert message.photo[0].width == thumb.width + assert message.photo[0].height == thumb.height + assert message.photo[0].file_size == thumb.file_size - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertIsInstance(thumb.file_id, str) - self.assertNotEqual(thumb.file_id, '') - self.assertEqual(thumb.width, self.thumb.width) - self.assertEqual(thumb.height, self.thumb.height) - self.assertEqual(thumb.file_size, self.thumb.file_size) - - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') - self.assertEqual(photo.width, self.photo.width) - self.assertEqual(photo.height, self.photo.height) - self.assertEqual(photo.file_size, self.photo.file_size) + assert isinstance(message.photo[1], PhotoSize) + assert isinstance(message.photo[1].file_id, str) + assert message.photo[1].file_id != '' + assert message.photo[1].width == photo.width + assert message.photo[1].height == photo.height + assert message.photo[1].file_size == photo.file_size @flaky(3, 1) - @timeout(10) - def test_send_photo_url_png_file(self): - message = self._bot.sendPhoto( - photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=self._chat_id) + @pytest.mark.timeout(10) + def test_send_url_png_file(self, bot, chat_id): + message = bot.send_photo(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', + chat_id=chat_id) photo = message.photo[-1] - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') + assert isinstance(photo, PhotoSize) + assert isinstance(photo.file_id, str) + assert photo.file_id != '' @flaky(3, 1) - @timeout(10) - def test_send_photo_url_gif_file(self): - message = self._bot.sendPhoto( - photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', chat_id=self._chat_id) + @pytest.mark.timeout(10) + def test_send_url_gif_file(self, bot, chat_id): + message = bot.send_photo(photo='http://dummyimage.com/600x400/000/fff.png&text=telegram', + chat_id=chat_id) photo = message.photo[-1] - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') + assert isinstance(photo, PhotoSize) + assert isinstance(photo.file_id, str) + assert photo.file_id != '' @flaky(3, 1) - @timeout(10) - def test_send_photo_bytesio_jpg_file(self): + @pytest.mark.timeout(10) + def test_send_bytesio_jpg_file(self, bot, chat_id): + file_name = 'tests/data/telegram_no_standard_header.jpg' + # raw image bytes - raw_bytes = BytesIO(open(self.photo_bytes_jpg_no_standard, 'rb').read()) - inputfile = telegram.InputFile({"photo": raw_bytes}) - self.assertEqual(inputfile.mimetype, 'application/octet-stream') + raw_bytes = BytesIO(open(file_name, 'rb').read()) + inputfile = InputFile({'photo': raw_bytes}) + assert inputfile.mimetype == 'application/octet-stream' # raw image bytes with name info - raw_bytes = BytesIO(open(self.photo_bytes_jpg_no_standard, 'rb').read()) - raw_bytes.name = self.photo_bytes_jpg_no_standard - inputfile = telegram.InputFile({"photo": raw_bytes}) - self.assertEqual(inputfile.mimetype, 'image/jpeg') + raw_bytes = BytesIO(open(file_name, 'rb').read()) + raw_bytes.name = file_name + inputfile = InputFile({'photo': raw_bytes}) + assert inputfile.mimetype == 'image/jpeg' # send raw photo - raw_bytes = BytesIO(open(self.photo_bytes_jpg_no_standard, 'rb').read()) - message = self._bot.sendPhoto(self._chat_id, photo=raw_bytes) + raw_bytes = BytesIO(open(file_name, 'rb').read()) + message = bot.send_photo(chat_id, photo=raw_bytes) photo = message.photo[-1] - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertEqual(photo.width, 1920) - self.assertEqual(photo.height, 1080) - self.assertEqual(photo.file_size, 30907) + assert isinstance(photo.file_id, str) + assert photo.file_id != '' + assert isinstance(photo, PhotoSize) + assert photo.width == 1920 + assert photo.height == 1080 + assert photo.file_size == 30907 + + def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): + def test(_, url, data, **kwargs): + return data['photo'] == photo.file_id + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_photo(photo=photo, chat_id=chat_id) + assert message @flaky(3, 1) - @timeout(10) - def test_silent_send_photo(self): - message = self._bot.sendPhoto(photo=self.photo_file, chat_id=self._chat_id, - disable_notification=True) - thumb, photo = message.photo - - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertIsInstance(thumb.file_id, str) - self.assertNotEqual(thumb.file_id, '') - - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') - - @flaky(3, 1) - @timeout(10) - def test_send_photo_with_photosize(self): - message = self._bot.send_photo(photo=self.photo, chat_id=self._chat_id) - thumb, photo = message.photo - - self.assertEqual(photo, self.photo) - self.assertEqual(thumb, self.thumb) - - @flaky(3, 1) - @timeout(10) - def test_send_photo_resend(self): - message = self._bot.sendPhoto(chat_id=self._chat_id, photo=self.photo.file_id) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, photo): + message = bot.send_photo(chat_id=chat_id, photo=photo.file_id) thumb, photo = message.photo - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertEqual(thumb.file_id, self.thumb.file_id) - self.assertEqual(thumb.width, self.thumb.width) - self.assertEqual(thumb.height, self.thumb.height) - self.assertEqual(thumb.file_size, self.thumb.file_size) + assert isinstance(message.photo[0], PhotoSize) + assert isinstance(message.photo[0].file_id, str) + assert message.photo[0].file_id != '' + assert message.photo[0].width == thumb.width + assert message.photo[0].height == thumb.height + assert message.photo[0].file_size == thumb.file_size - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertEqual(photo.file_id, self.photo.file_id) - self.assertEqual(photo.width, self.photo.width) - self.assertEqual(photo.height, self.photo.height) - self.assertEqual(photo.file_size, self.photo.file_size) + assert isinstance(message.photo[1], PhotoSize) + assert isinstance(message.photo[1].file_id, str) + assert message.photo[1].file_id != '' + assert message.photo[1].width == photo.width + assert message.photo[1].height == photo.height + assert message.photo[1].file_size == photo.file_size - def test_photo_de_json(self): - photo = telegram.PhotoSize.de_json(self.json_dict, self._bot) + def test_de_json(self, bot, photo): + json_dict = { + 'file_id': photo.file_id, + 'width': self.width, + 'height': self.height, + 'file_size': self.file_size + } + json_photo = PhotoSize.de_json(json_dict, bot) - self.assertEqual(photo, self.photo) + assert json_photo.file_id == photo.file_id + assert json_photo.width == self.width + assert json_photo.height == self.height + assert json_photo.file_size == self.file_size - def test_photo_to_json(self): - self.assertTrue(self.is_json(self.photo.to_json())) + def test_to_dict(self, photo): + photo_dict = photo.to_dict() - def test_photo_to_dict(self): - photo = self.photo.to_dict() - - self.assertTrue(self.is_dict(photo)) - self.assertEqual(photo['file_id'], self.photo.file_id) - self.assertEqual(photo['width'], self.photo.width) - self.assertEqual(photo['height'], self.photo.height) - self.assertEqual(photo['file_size'], self.photo.file_size) + assert isinstance(photo_dict, dict) + assert photo_dict['file_id'] == photo.file_id + assert photo_dict['width'] == photo.width + assert photo_dict['height'] == photo.height + assert photo_dict['file_size'] == photo.file_size @flaky(3, 1) - @timeout(10) - def test_error_send_photo_empty_file(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['photo'] = open(os.devnull, 'rb') - - with self.assertRaises(telegram.TelegramError): - self._bot.sendPhoto(chat_id=self._chat_id, **json_dict) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_photo(chat_id=chat_id, photo=open(os.devnull, 'rb')) @flaky(3, 1) - @timeout(10) - def test_error_send_photo_empty_file_id(self): - json_dict = self.json_dict + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_photo(chat_id=chat_id, photo='') - del (json_dict['file_id']) - json_dict['photo'] = '' + def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_photo(chat_id=chat_id) - with self.assertRaises(telegram.TelegramError): - self._bot.sendPhoto(chat_id=self._chat_id, **json_dict) + def test_equality(self, photo): + a = PhotoSize(photo.file_id, self.width, self.height) + b = PhotoSize(photo.file_id, self.width, self.height) + c = PhotoSize(photo.file_id, 0, 0) + d = PhotoSize('', self.width, self.height) + e = Sticker(photo.file_id, self.width, self.height) - @flaky(3, 1) - @timeout(10) - def test_error_photo_without_required_args(self): - json_dict = self.json_dict + assert a == b + assert hash(a) == hash(b) + assert a is not b - del (json_dict['file_id']) - del (json_dict['width']) - del (json_dict['height']) + assert a == c + assert hash(a) == hash(c) - with self.assertRaises(TypeError): - self._bot.sendPhoto(chat_id=self._chat_id, **json_dict) + assert a != d + assert hash(a) != hash(d) - @flaky(3, 1) - @timeout(10) - def test_reply_photo(self): - """Test for Message.reply_photo""" - message = self._bot.sendMessage(self._chat_id, '.') - thumb, photo = message.reply_photo(self.photo_file).photo - - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertIsInstance(thumb.file_id, str) - self.assertNotEqual(thumb.file_id, '') - - self.assertIsInstance(photo, telegram.PhotoSize) - self.assertIsInstance(photo.file_id, str) - self.assertNotEqual(photo.file_id, '') - - def test_equality(self): - a = telegram.PhotoSize(self.photo.file_id, self.photo.width, self.photo.height) - b = telegram.PhotoSize(self.photo.file_id, self.photo.width, self.photo.height) - c = telegram.PhotoSize(self.photo.file_id, 0, 0) - d = telegram.PhotoSize("", self.photo.width, self.photo.height) - e = telegram.Sticker(self.photo.file_id, self.photo.width, self.photo.height) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index e98ce442b..9cd1061f2 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -5,43 +5,47 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -PreCheckoutQuery""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Update, User, PreCheckoutQuery, OrderInfo -class PreCheckoutQueryTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram PreCheckoutQuery.""" +@pytest.fixture(scope='class') +def pre_checkout_query(bot): + return PreCheckoutQuery(TestPreCheckoutQuery.id, + TestPreCheckoutQuery.from_user, + TestPreCheckoutQuery.currency, + TestPreCheckoutQuery.total_amount, + TestPreCheckoutQuery.invoice_payload, + shipping_option_id=TestPreCheckoutQuery.shipping_option_id, + order_info=TestPreCheckoutQuery.order_info, + bot=bot) - def setUp(self): - self._id = 5 - self.invoice_payload = 'invoice_payload' - self.shipping_option_id = 'shipping_option_id' - self.currency = 'EUR' - self.total_amount = 100 - self.from_user = telegram.User(0, '') - self.order_info = telegram.OrderInfo() - self.json_dict = { - 'id': self._id, +class TestPreCheckoutQuery(object): + id = 5 + invoice_payload = 'invoice_payload' + shipping_option_id = 'shipping_option_id' + currency = 'EUR' + total_amount = 100 + from_user = User(0, '') + order_info = OrderInfo() + + def test_de_json(self, bot): + json_dict = { + 'id': self.id, 'invoice_payload': self.invoice_payload, 'shipping_option_id': self.shipping_option_id, 'currency': self.currency, @@ -49,51 +53,53 @@ class PreCheckoutQueryTest(BaseTest, unittest.TestCase): 'from': self.from_user.to_dict(), 'order_info': self.order_info.to_dict() } + pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot) - def test_precheckoutquery_de_json(self): - precheckoutquery = telegram.PreCheckoutQuery.de_json(self.json_dict, self._bot) + assert pre_checkout_query.id == self.id + assert pre_checkout_query.invoice_payload == self.invoice_payload + assert pre_checkout_query.shipping_option_id == self.shipping_option_id + assert pre_checkout_query.currency == self.currency + assert pre_checkout_query.from_user == self.from_user + assert pre_checkout_query.order_info == self.order_info - self.assertEqual(precheckoutquery.id, self._id) - self.assertEqual(precheckoutquery.invoice_payload, self.invoice_payload) - self.assertEqual(precheckoutquery.shipping_option_id, self.shipping_option_id) - self.assertEqual(precheckoutquery.currency, self.currency) - self.assertEqual(precheckoutquery.from_user, self.from_user) - self.assertEqual(precheckoutquery.order_info, self.order_info) + def test_to_dict(self, pre_checkout_query): + pre_checkout_query_dict = pre_checkout_query.to_dict() - def test_precheckoutquery_to_json(self): - precheckoutquery = telegram.PreCheckoutQuery.de_json(self.json_dict, self._bot) + assert isinstance(pre_checkout_query_dict, dict) + assert pre_checkout_query_dict['id'] == pre_checkout_query.id + assert pre_checkout_query_dict['invoice_payload'] == pre_checkout_query.invoice_payload + assert pre_checkout_query_dict['shipping_option_id'] == \ + pre_checkout_query.shipping_option_id + assert pre_checkout_query_dict['currency'] == pre_checkout_query.currency + assert pre_checkout_query_dict['from'] == pre_checkout_query.from_user.to_dict() + assert pre_checkout_query_dict['order_info'] == pre_checkout_query.order_info.to_dict() - self.assertTrue(self.is_json(precheckoutquery.to_json())) + def test_answer(self, monkeypatch, pre_checkout_query): + def test(*args, **kwargs): + return args[1] == pre_checkout_query.id - def test_precheckoutquery_to_dict(self): - precheckoutquery = telegram.PreCheckoutQuery.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(precheckoutquery)) - self.assertDictEqual(self.json_dict, precheckoutquery) + monkeypatch.setattr('telegram.Bot.answer_pre_checkout_query', test) + assert pre_checkout_query.answer() def test_equality(self): - a = telegram.PreCheckoutQuery(self._id, self.from_user, self.currency, self.total_amount, - self.invoice_payload) - b = telegram.PreCheckoutQuery(self._id, self.from_user, self.currency, self.total_amount, - self.invoice_payload) - c = telegram.PreCheckoutQuery(self._id, None, '', 0, '') - d = telegram.PreCheckoutQuery(0, self.from_user, self.currency, self.total_amount, - self.invoice_payload) - e = telegram.Update(self._id) + a = PreCheckoutQuery(self.id, self.from_user, self.currency, self.total_amount, + self.invoice_payload) + b = PreCheckoutQuery(self.id, self.from_user, self.currency, self.total_amount, + self.invoice_payload) + c = PreCheckoutQuery(self.id, None, '', 0, '') + d = PreCheckoutQuery(0, self.from_user, self.currency, self.total_amount, + self.invoice_payload) + e = Update(self.id) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_precheckoutqueryhandler.py b/tests/test_precheckoutqueryhandler.py new file mode 100644 index 000000000..67eaf40a9 --- /dev/null +++ b/tests/test_precheckoutqueryhandler.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, + InlineQuery, ShippingQuery, PreCheckoutQuery) +from telegram.ext import PreCheckoutQueryHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='class') +def pre_checkout_query(): + return Update(1, pre_checkout_query=PreCheckoutQuery('id', User(1, 'test user'), 'EUR', 223, + 'invoice_payload')) + + +class TestPreCheckoutQueryHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def test_basic(self, dp, pre_checkout_query): + handler = PreCheckoutQueryHandler(self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(pre_checkout_query) + dp.process_update(pre_checkout_query) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, pre_checkout_query): + handler = PreCheckoutQueryHandler(self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(pre_checkout_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = PreCheckoutQueryHandler(self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(pre_checkout_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = PreCheckoutQueryHandler(self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(pre_checkout_query) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, pre_checkout_query): + handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(pre_checkout_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = PreCheckoutQueryHandler(self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(pre_checkout_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = PreCheckoutQueryHandler(self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(pre_checkout_query) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = PreCheckoutQueryHandler(self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_regexhandler.py b/tests/test_regexhandler.py new file mode 100644 index 000000000..44c505e3d --- /dev/null +++ b/tests/test_regexhandler.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Message, Update, Chat, Bot, User, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import RegexHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('callback_query', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='class') +def message(bot): + return Message(1, None, None, None, text='test message', bot=bot) + + +class TestRegexHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def callback_group(self, bot, update, groups=None, groupdict=None): + if groups is not None: + self.test_flag = groups == ('t', ' message') + if groupdict is not None: + self.test_flag = groupdict == {'begin': 't', 'end': ' message'} + + def test_basic(self, dp, message): + handler = RegexHandler('.*', self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(Update(0, message)) + dp.process_update(Update(0, message)) + assert self.test_flag + + def test_pattern(self, message): + handler = RegexHandler('.*est.*', self.callback_basic) + + assert handler.check_update(Update(0, message)) + + handler = RegexHandler('.*not in here.*', self.callback_basic) + assert not handler.check_update(Update(0, message)) + + def test_with_passing_group_dict(self, dp, message): + handler = RegexHandler('(?P.*)est(?P.*)', self.callback_group, + pass_groups=True) + dp.add_handler(handler) + + dp.process_update(Update(0, message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = RegexHandler('(?P.*)est(?P.*)', self.callback_group, + pass_groupdict=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message)) + assert self.test_flag + + def test_edited(self, message): + handler = RegexHandler('.*', self.callback_basic, edited_updates=True, + message_updates=False, channel_post_updates=False) + + assert handler.check_update(Update(0, edited_message=message)) + assert not handler.check_update(Update(0, message=message)) + assert not handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_channel_post(self, message): + handler = RegexHandler('.*', self.callback_basic, edited_updates=False, + message_updates=False, channel_post_updates=True) + + assert not handler.check_update(Update(0, edited_message=message)) + assert not handler.check_update(Update(0, message=message)) + assert handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_multiple_flags(self, message): + handler = RegexHandler('.*', self.callback_basic, edited_updates=True, + message_updates=True, channel_post_updates=True) + + assert handler.check_update(Update(0, edited_message=message)) + assert handler.check_update(Update(0, message=message)) + assert handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_allow_updated(self, message): + with pytest.warns(UserWarning): + handler = RegexHandler('.*', self.callback_basic, message_updates=True, + allow_edited=True) + + assert handler.check_update(Update(0, edited_message=message)) + assert handler.check_update(Update(0, message=message)) + assert not handler.check_update(Update(0, channel_post=message)) + assert not handler.check_update(Update(0, edited_channel_post=message)) + + def test_none_allowed(self): + with pytest.raises(ValueError, match='are all False'): + handler = RegexHandler('.*', self.callback_basic, message_updates=False, + channel_post_updates=False, edited_updates=False) + + def test_pass_user_or_chat_data(self, dp, message): + handler = RegexHandler('.*', self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = RegexHandler('.*', self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = RegexHandler('.*', self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, message): + handler = RegexHandler('.*', self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = RegexHandler('.*', self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + dp.remove_handler(handler) + handler = RegexHandler('.*', self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(Update(0, message=message)) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = RegexHandler('.*', self.callback_basic, edited_updates=True) + assert not handler.check_update(false_update) diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 799cc50f2..633e69764 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -1,86 +1,74 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram ReplyKeyboardMarkup""" -import sys -import unittest +import pytest +from flaky import flaky -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ReplyKeyboardMarkup, KeyboardButton -class ReplyKeyboardMarkupTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ReplyKeyboardMarkup.""" - - def setUp(self): - self.keyboard = [[telegram.KeyboardButton('button1'), telegram.KeyboardButton('button2')]] - self.resize_keyboard = True - self.one_time_keyboard = True - self.selective = True - - self.json_dict = { - 'keyboard': [[self.keyboard[0][0].to_dict(), self.keyboard[0][1].to_dict()]], - 'resize_keyboard': self.resize_keyboard, - 'one_time_keyboard': self.one_time_keyboard, - 'selective': self.selective, - } - - def test_send_message_with_reply_keyboard_markup(self): - message = self._bot.sendMessage( - self._chat_id, - 'Моё судно на воздушной подушке полно угрей', - reply_markup=telegram.ReplyKeyboardMarkup.de_json(self.json_dict, self._bot)) - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') - - def test_reply_markup_empty_de_json_empty(self): - reply_markup_empty = telegram.ReplyKeyboardMarkup.de_json(None, self._bot) - - self.assertFalse(reply_markup_empty) - - def test_reply_keyboard_markup_de_json(self): - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict, self._bot) - - self.assertTrue(isinstance(reply_keyboard_markup.keyboard, list)) - self.assertTrue(isinstance(reply_keyboard_markup.keyboard[0][0], telegram.KeyboardButton)) - self.assertEqual(reply_keyboard_markup.resize_keyboard, self.resize_keyboard) - self.assertEqual(reply_keyboard_markup.one_time_keyboard, self.one_time_keyboard) - self.assertEqual(reply_keyboard_markup.selective, self.selective) - - def test_reply_keyboard_markup_to_json(self): - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(reply_keyboard_markup.to_json())) - - def test_reply_keyboard_markup_to_dict(self): - reply_keyboard_markup = telegram.ReplyKeyboardMarkup.de_json(self.json_dict, self._bot) - - self.assertTrue(isinstance(reply_keyboard_markup.keyboard, list)) - self.assertTrue(isinstance(reply_keyboard_markup.keyboard[0][0], telegram.KeyboardButton)) - self.assertEqual(reply_keyboard_markup['resize_keyboard'], self.resize_keyboard) - self.assertEqual(reply_keyboard_markup['one_time_keyboard'], self.one_time_keyboard) - self.assertEqual(reply_keyboard_markup['selective'], self.selective) +@pytest.fixture(scope='class') +def reply_keyboard_markup(): + return ReplyKeyboardMarkup(TestReplyKeyboardMarkup.keyboard, + resize_keyboard=TestReplyKeyboardMarkup.resize_keyboard, + one_time_keyboard=TestReplyKeyboardMarkup.one_time_keyboard, + selective=TestReplyKeyboardMarkup.selective) -if __name__ == '__main__': - unittest.main() +class TestReplyKeyboardMarkup(object): + keyboard = [[KeyboardButton('button1'), KeyboardButton('button2')]] + resize_keyboard = True + one_time_keyboard = True + selective = True + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_message_with_reply_keyboard_markup(self, bot, chat_id, reply_keyboard_markup): + message = bot.send_message(chat_id, 'Text', reply_markup=reply_keyboard_markup) + + assert message.text == 'Text' + + @flaky(3, 1) + @pytest.mark.timeout(10) + def test_send_message_with_data_markup(self, bot, chat_id): + message = bot.send_message(chat_id, 'text 2', reply_markup={'keyboard': [['1', '2']]}) + + assert message.text == 'text 2' + + def test_expected_values(self, reply_keyboard_markup): + assert isinstance(reply_keyboard_markup.keyboard, list) + assert isinstance(reply_keyboard_markup.keyboard[0][0], KeyboardButton) + assert isinstance(reply_keyboard_markup.keyboard[0][1], KeyboardButton) + assert reply_keyboard_markup.resize_keyboard == self.resize_keyboard + assert reply_keyboard_markup.one_time_keyboard == self.one_time_keyboard + assert reply_keyboard_markup.selective == self.selective + + def test_to_dict(self, reply_keyboard_markup): + reply_keyboard_markup_dict = reply_keyboard_markup.to_dict() + + assert isinstance(reply_keyboard_markup_dict, dict) + assert reply_keyboard_markup_dict['keyboard'][0][0] == \ + reply_keyboard_markup.keyboard[0][0].to_dict() + assert reply_keyboard_markup_dict['keyboard'][0][1] == \ + reply_keyboard_markup.keyboard[0][1].to_dict() + assert reply_keyboard_markup_dict['resize_keyboard'] == \ + reply_keyboard_markup.resize_keyboard + assert reply_keyboard_markup_dict['one_time_keyboard'] == \ + reply_keyboard_markup.one_time_keyboard + assert reply_keyboard_markup_dict['selective'] == reply_keyboard_markup.selective diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index 06acf7601..26ddf113d 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -1,76 +1,48 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram ReplyKeyboardRemove""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ReplyKeyboardRemove -class ReplyKeyboardRemoveTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ReplyKeyboardRemove.""" - - def setUp(self): - self.remove_keyboard = True - self.selective = True - - self.json_dict = { - 'remove_keyboard': self.remove_keyboard, - 'selective': self.selective, - } - - def test_send_message_with_reply_keyboard_remove(self): - message = self._bot.sendMessage( - self._chat_id, - 'Моё судно на воздушной подушке полно угрей', - reply_markup=telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot)) - - self.assertTrue(self.is_json(message.to_json())) - self.assertEqual(message.text, u'Моё судно на воздушной подушке полно угрей') - - def test_reply_keyboard_remove_de_json(self): - reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot) - - self.assertEqual(reply_keyboard_remove.remove_keyboard, self.remove_keyboard) - self.assertEqual(reply_keyboard_remove.selective, self.selective) - - def test_reply_keyboard_remove_de_json_empty(self): - reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(None, self._bot) - - self.assertFalse(reply_keyboard_remove) - - def test_reply_keyboard_remove_to_json(self): - reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(reply_keyboard_remove.to_json())) - - def test_reply_keyboard_remove_to_dict(self): - reply_keyboard_remove = telegram.ReplyKeyboardRemove.de_json(self.json_dict, self._bot) - - self.assertEqual(reply_keyboard_remove['remove_keyboard'], self.remove_keyboard) - self.assertEqual(reply_keyboard_remove['selective'], self.selective) +@pytest.fixture(scope='class') +def reply_keyboard_remove(): + return ReplyKeyboardRemove(selective=TestReplyKeyboardRemove.selective) -if __name__ == '__main__': - unittest.main() +class TestReplyKeyboardRemove(object): + remove_keyboard = True + selective = True + + def test_send_message_with_reply_keyboard_remove(self, bot, chat_id, reply_keyboard_remove): + message = bot.send_message(chat_id, 'Text', reply_markup=reply_keyboard_remove) + + assert message.text == 'Text' + + def test_expected_values(self, reply_keyboard_remove): + assert reply_keyboard_remove.remove_keyboard == self.remove_keyboard + assert reply_keyboard_remove.selective == self.selective + + def test_to_dict(self, reply_keyboard_remove): + reply_keyboard_remove_dict = reply_keyboard_remove.to_dict() + + assert reply_keyboard_remove_dict['remove_keyboard'] == \ + reply_keyboard_remove.remove_keyboard + assert reply_keyboard_remove_dict['selective'] == reply_keyboard_remove.selective diff --git a/tests/test_replymarkup.py b/tests/test_replymarkup.py deleted file mode 100644 index 0c6f09d82..000000000 --- a/tests/test_replymarkup.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2017 -# 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 an object that represents Tests for Telegram -ReplyMarkup""" - -import sys -import unittest - -sys.path.append('.') - -import telegram -from tests.base import BaseTest - - -class ReplyMarkupTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ReplyMarkup.""" - - def test_reply_markup_de_json_empty(self): - reply_markup = telegram.ReplyMarkup.de_json(None, self._bot) - - self.assertFalse(reply_markup) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 3025e1d5d..85ff31c10 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -5,41 +5,43 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -ShippingAddress""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import ShippingAddress -class ShippingAddressTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ShippingAddress.""" +@pytest.fixture(scope='class') +def shipping_address(): + return ShippingAddress(TestShippingAddress.country_code, + TestShippingAddress.state, + TestShippingAddress.city, + TestShippingAddress.street_line1, + TestShippingAddress.street_line2, + TestShippingAddress.post_code) - def setUp(self): - self.country_code = 'GB' - self.state = 'state' - self.city = 'London' - self.street_line1 = '12 Grimmauld Place' - self.street_line2 = 'street_line2' - self.post_code = 'WC1' - self.json_dict = { +class TestShippingAddress(object): + country_code = 'GB' + state = 'state' + city = 'London' + street_line1 = '12 Grimmauld Place' + street_line2 = 'street_line2' + post_code = 'WC1' + + def test_de_json(self, bot): + json_dict = { 'country_code': self.country_code, 'state': self.state, 'city': self.city, @@ -47,68 +49,62 @@ class ShippingAddressTest(BaseTest, unittest.TestCase): 'street_line2': self.street_line2, 'post_code': self.post_code } + shipping_address = ShippingAddress.de_json(json_dict, bot) - def test_shippingaddress_de_json(self): - shippingaddress = telegram.ShippingAddress.de_json(self.json_dict, self._bot) + assert shipping_address.country_code == self.country_code + assert shipping_address.state == self.state + assert shipping_address.city == self.city + assert shipping_address.street_line1 == self.street_line1 + assert shipping_address.street_line2 == self.street_line2 + assert shipping_address.post_code == self.post_code - self.assertEqual(shippingaddress.country_code, self.country_code) - self.assertEqual(shippingaddress.state, self.state) - self.assertEqual(shippingaddress.city, self.city) - self.assertEqual(shippingaddress.street_line1, self.street_line1) - self.assertEqual(shippingaddress.street_line2, self.street_line2) - self.assertEqual(shippingaddress.post_code, self.post_code) + def test_to_dict(self, shipping_address): + shipping_address_dict = shipping_address.to_dict() - def test_shippingaddress_to_json(self): - shippingaddress = telegram.ShippingAddress.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(shippingaddress.to_json())) - - def test_shippingaddress_to_dict(self): - shippingaddress = telegram.ShippingAddress.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(shippingaddress)) - self.assertDictEqual(self.json_dict, shippingaddress) + assert isinstance(shipping_address_dict, dict) + assert shipping_address_dict['country_code'] == shipping_address.country_code + assert shipping_address_dict['state'] == shipping_address.state + assert shipping_address_dict['city'] == shipping_address.city + assert shipping_address_dict['street_line1'] == shipping_address.street_line1 + assert shipping_address_dict['street_line2'] == shipping_address.street_line2 + assert shipping_address_dict['post_code'] == shipping_address.post_code def test_equality(self): - a = telegram.ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - b = telegram.ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - d = telegram.ShippingAddress('', self.state, self.city, self.street_line1, - self.street_line2, self.post_code) - d2 = telegram.ShippingAddress(self.country_code, '', self.city, self.street_line1, - self.street_line2, self.post_code) - d3 = telegram.ShippingAddress(self.country_code, self.state, '', self.street_line1, - self.street_line2, self.post_code) - d4 = telegram.ShippingAddress(self.country_code, self.state, self.city, '', - self.street_line2, self.post_code) - d5 = telegram.ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - '', self.post_code) - d6 = telegram.ShippingAddress(self.country_code, self.state, self.city, self.street_line1, - self.street_line2, '') + a = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, + self.street_line2, self.post_code) + b = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, + self.street_line2, self.post_code) + d = ShippingAddress('', self.state, self.city, self.street_line1, + self.street_line2, self.post_code) + d2 = ShippingAddress(self.country_code, '', self.city, self.street_line1, + self.street_line2, self.post_code) + d3 = ShippingAddress(self.country_code, self.state, '', self.street_line1, + self.street_line2, self.post_code) + d4 = ShippingAddress(self.country_code, self.state, self.city, '', + self.street_line2, self.post_code) + d5 = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, + '', self.post_code) + d6 = ShippingAddress(self.country_code, self.state, self.city, self.street_line1, + self.street_line2, '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, d2) - self.assertNotEqual(hash(a), hash(d2)) + assert a != d2 + assert hash(a) != hash(d2) - self.assertNotEqual(a, d3) - self.assertNotEqual(hash(a), hash(d3)) + assert a != d3 + assert hash(a) != hash(d3) - self.assertNotEqual(a, d4) - self.assertNotEqual(hash(a), hash(d4)) + assert a != d4 + assert hash(a) != hash(d4) - self.assertNotEqual(a, d5) - self.assertNotEqual(hash(a), hash(d5)) + assert a != d5 + assert hash(a) != hash(d5) - self.assertNotEqual(a, d6) - self.assertNotEqual(hash(6), hash(d6)) - - -if __name__ == '__main__': - unittest.main() + assert a != d6 + assert hash(6) != hash(d6) diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 935ecb15b..8bb363d9f 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -5,84 +5,67 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -ShippingOption""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import LabeledPrice, ShippingOption, Voice -class ShippingOptionTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ShippingOption.""" +@pytest.fixture(scope='class') +def shipping_option(): + return ShippingOption(TestShippingOption.id, TestShippingOption.title, + TestShippingOption.prices) - def setUp(self): - self._id = 'id' - self.title = 'title' - self.prices = [ - telegram.LabeledPrice('Fish Container', 100), - telegram.LabeledPrice('Premium Fish Container', 1000) - ] - self.json_dict = { - 'id': self._id, - 'title': self.title, - 'prices': [x.to_dict() for x in self.prices] - } +class TestShippingOption(object): + id = 'id' + title = 'title' + prices = [ + LabeledPrice('Fish Container', 100), + LabeledPrice('Premium Fish Container', 1000) + ] - def test_shippingoption_de_json(self): - shippingoption = telegram.ShippingOption.de_json(self.json_dict, self._bot) + def test_expected_values(self, shipping_option): + assert shipping_option.id == self.id + assert shipping_option.title == self.title + assert shipping_option.prices == self.prices - self.assertEqual(shippingoption.id, self._id) - self.assertEqual(shippingoption.title, self.title) - self.assertEqual(shippingoption.prices, self.prices) + def test_to_dict(self, shipping_option): + shipping_option_dict = shipping_option.to_dict() - def test_shippingoption_to_json(self): - shippingoption = telegram.ShippingOption.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(shippingoption.to_json())) - - def test_shippingoption_to_dict(self): - shippingoption = telegram.ShippingOption.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(shippingoption)) - self.assertDictEqual(self.json_dict, shippingoption) + assert isinstance(shipping_option_dict, dict) + assert shipping_option_dict['id'] == shipping_option.id + assert shipping_option_dict['title'] == shipping_option.title + assert shipping_option_dict['prices'][0] == shipping_option.prices[0].to_dict() + assert shipping_option_dict['prices'][1] == shipping_option.prices[1].to_dict() def test_equality(self): - a = telegram.ShippingOption(self._id, self.title, self.prices) - b = telegram.ShippingOption(self._id, self.title, self.prices) - c = telegram.ShippingOption(self._id, '', []) - d = telegram.ShippingOption(0, self.title, self.prices) - e = telegram.Voice(self._id, 0) + a = ShippingOption(self.id, self.title, self.prices) + b = ShippingOption(self.id, self.title, self.prices) + c = ShippingOption(self.id, '', []) + d = ShippingOption(0, self.title, self.prices) + e = Voice(self.id, 0) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index 04825d6da..f8f29c559 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -5,87 +5,84 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -ShippingQuery""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Update, User, ShippingAddress, ShippingQuery -class ShippingQueryTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram ShippingQuery.""" +@pytest.fixture(scope='class') +def shipping_query(bot): + return ShippingQuery(TestShippingQuery.id, + TestShippingQuery.from_user, + TestShippingQuery.invoice_payload, + TestShippingQuery.shipping_address, + bot=bot) - def setUp(self): - self._id = 5 - self.invoice_payload = 'invoice_payload' - self.from_user = telegram.User(0, '') - self.shipping_address = telegram.ShippingAddress('GB', '', 'London', '12 Grimmauld Place', - '', 'WC1') - self.json_dict = { - 'id': self._id, - 'invoice_payload': self.invoice_payload, - 'from': self.from_user.to_dict(), - 'shipping_address': self.shipping_address.to_dict() +class TestShippingQuery(object): + id = 5 + invoice_payload = 'invoice_payload' + from_user = User(0, '') + shipping_address = ShippingAddress('GB', '', 'London', '12 Grimmauld Place', '', 'WC1') + + def test_de_json(self, bot): + json_dict = { + 'id': TestShippingQuery.id, + 'invoice_payload': TestShippingQuery.invoice_payload, + 'from': TestShippingQuery.from_user.to_dict(), + 'shipping_address': TestShippingQuery.shipping_address.to_dict() } + shipping_query = ShippingQuery.de_json(json_dict, bot) - def test_shippingquery_de_json(self): - shippingquery = telegram.ShippingQuery.de_json(self.json_dict, self._bot) + assert shipping_query.id == self.id + assert shipping_query.invoice_payload == self.invoice_payload + assert shipping_query.from_user == self.from_user + assert shipping_query.shipping_address == self.shipping_address - self.assertEqual(shippingquery.id, self._id) - self.assertEqual(shippingquery.invoice_payload, self.invoice_payload) - self.assertEqual(shippingquery.from_user, self.from_user) - self.assertEqual(shippingquery.shipping_address, self.shipping_address) + def test_to_dict(self, shipping_query): + shipping_query_dict = shipping_query.to_dict() - def test_shippingquery_to_json(self): - shippingquery = telegram.ShippingQuery.de_json(self.json_dict, self._bot) + assert isinstance(shipping_query_dict, dict) + assert shipping_query_dict['id'] == shipping_query.id + assert shipping_query_dict['invoice_payload'] == shipping_query.invoice_payload + assert shipping_query_dict['from'] == shipping_query.from_user.to_dict() + assert shipping_query_dict['shipping_address'] == shipping_query.shipping_address.to_dict() - self.assertTrue(self.is_json(shippingquery.to_json())) + def test_answer(self, monkeypatch, shipping_query): + def test(*args, **kwargs): + return args[1] == shipping_query.id - def test_shippingquery_to_dict(self): - shippingquery = telegram.ShippingQuery.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(shippingquery)) - self.assertDictEqual(self.json_dict, shippingquery) + monkeypatch.setattr('telegram.Bot.answer_shipping_query', test) + assert shipping_query.answer() def test_equality(self): - a = telegram.ShippingQuery(self._id, self.from_user, self.invoice_payload, - self.shipping_address) - b = telegram.ShippingQuery(self._id, self.from_user, self.invoice_payload, - self.shipping_address) - c = telegram.ShippingQuery(self._id, None, '', None) - d = telegram.ShippingQuery(0, self.from_user, self.invoice_payload, self.shipping_address) - e = telegram.Update(self._id) + a = ShippingQuery(self.id, self.from_user, self.invoice_payload, self.shipping_address) + b = ShippingQuery(self.id, self.from_user, self.invoice_payload, self.shipping_address) + c = ShippingQuery(self.id, None, '', None) + d = ShippingQuery(0, self.from_user, self.invoice_payload, self.shipping_address) + e = Update(self.id) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_shippingqueryhandler.py b/tests/test_shippingqueryhandler.py new file mode 100644 index 000000000..fbc36910f --- /dev/null +++ b/tests/test_shippingqueryhandler.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import pytest + +from telegram import (Update, Chat, Bot, ChosenInlineResult, User, Message, CallbackQuery, + InlineQuery, ShippingQuery, PreCheckoutQuery, ShippingAddress) +from telegram.ext import ShippingQueryHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +@pytest.fixture(scope='class') +def shiping_query(): + return Update(1, shipping_query=ShippingQuery(42, User(1, 'test user'), 'invoice_payload', + ShippingAddress('EN', 'my_state', 'my_city', + 'steer_1', '', 'post_code'))) + + +class TestShippingQueryHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, Update) + self.test_flag = test_bot and test_update + + def callback_data_1(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) or (chat_data is not None) + + def callback_data_2(self, bot, update, user_data=None, chat_data=None): + self.test_flag = (user_data is not None) and (chat_data is not None) + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def test_basic(self, dp, shiping_query): + handler = ShippingQueryHandler(self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update(shiping_query) + dp.process_update(shiping_query) + assert self.test_flag + + def test_pass_user_or_chat_data(self, dp, shiping_query): + handler = ShippingQueryHandler(self.callback_data_1, pass_user_data=True) + dp.add_handler(handler) + + dp.process_update(shiping_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = ShippingQueryHandler(self.callback_data_1, pass_chat_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(shiping_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = ShippingQueryHandler(self.callback_data_2, pass_chat_data=True, + pass_user_data=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(shiping_query) + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp, shiping_query): + handler = ShippingQueryHandler(self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update(shiping_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = ShippingQueryHandler(self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(shiping_query) + assert self.test_flag + + dp.remove_handler(handler) + handler = ShippingQueryHandler(self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update(shiping_query) + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = ShippingQueryHandler(self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 12ad37cc1..06acd7a39 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -6,322 +6,317 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Sticker""" - import os -import unittest +import pytest from flaky import flaky from future.utils import PY2 -import telegram -from tests.base import BaseTest, timeout +from telegram import Sticker, PhotoSize, TelegramError, StickerSet, Audio, MaskPosition +from telegram.error import BadRequest -class StickerTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Sticker.""" +@pytest.fixture(scope='function') +def sticker_file(): + f = open('tests/data/telegram.webp', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(StickerTest, cls).setUpClass() - cls.emoji = '💪' - # cls.sticker_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.webp" - # Serving sticker from gh since our server sends wrong content_type - cls.sticker_file_url = "https://github.com/python-telegram-bot/python-telegram-bot/blob/master/tests/data/telegram.webp?raw=true" # noqa +@pytest.fixture(scope='class') +def sticker(bot, chat_id): + with open('tests/data/telegram.webp', 'rb') as f: + return bot.send_sticker(chat_id, sticker=f, timeout=10).sticker - sticker_file = open('tests/data/telegram.webp', 'rb') - sticker = cls._bot.send_sticker(cls._chat_id, sticker=sticker_file, timeout=10).sticker - cls.sticker = sticker - cls.thumb = sticker.thumb +class TestSticker(object): + # sticker_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.webp' + # Serving sticker from gh since our server sends wrong content_type + sticker_file_url = ('https://github.com/python-telegram-bot/python-telegram-bot/blob/master' + '/tests/data/telegram.webp?raw=true') + + emoji = '💪' + width = 510 + height = 512 + file_size = 39518 + thumb_width = 90 + thumb_heigth = 90 + thumb_file_size = 3672 + + def test_creation(self, sticker): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.sticker, telegram.Sticker) - assert isinstance(cls.sticker.file_id, str) - assert cls.sticker.file_id is not '' - assert isinstance(cls.thumb, telegram.PhotoSize) - assert isinstance(cls.thumb.file_id, str) - assert cls.thumb.file_id is not '' + assert isinstance(sticker, Sticker) + assert isinstance(sticker.file_id, str) + assert sticker.file_id != '' + assert isinstance(sticker.thumb, PhotoSize) + assert isinstance(sticker.thumb.file_id, str) + assert sticker.thumb.file_id != '' - def setUp(self): - self.sticker_file = open('tests/data/telegram.webp', 'rb') - self.json_dict = { - 'file_id': self.sticker.file_id, - 'width': self.sticker.width, - 'height': self.sticker.height, - 'thumb': self.thumb.to_dict(), - 'emoji': self.emoji, - 'file_size': self.sticker.file_size - } - - def test_expected_values(self): - self.assertEqual(self.sticker.width, 510) - self.assertEqual(self.sticker.height, 512) - self.assertEqual(self.sticker.file_size, 39518) - self.assertEqual(self.thumb.width, 90) - self.assertEqual(self.thumb.height, 90) - self.assertEqual(self.thumb.file_size, 3672) + def test_expected_values(self, sticker): + assert sticker.width == self.width + assert sticker.height == self.height + assert sticker.file_size == self.file_size + assert sticker.thumb.width == self.thumb_width + assert sticker.thumb.height == self.thumb_heigth + assert sticker.thumb.file_size == self.thumb_file_size @flaky(3, 1) - @timeout(10) - def test_send_sticker_all_args(self): - message = self._bot.sendSticker(chat_id=self._chat_id, sticker=self.sticker.file_id, disable_notification=False) - sticker = message.sticker + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, sticker_file, sticker): + message = bot.send_sticker(chat_id, sticker=sticker_file, disable_notification=False) - self.assertEqual(sticker, self.sticker) + assert isinstance(message.sticker, Sticker) + assert isinstance(message.sticker.file_id, str) + assert message.sticker.file_id != '' + assert message.sticker.width == sticker.width + assert message.sticker.height == sticker.height + assert message.sticker.file_size == sticker.file_size + + assert isinstance(message.sticker.thumb, PhotoSize) + assert isinstance(message.sticker.thumb.file_id, str) + assert message.sticker.thumb.file_id != '' + assert message.sticker.thumb.width == sticker.thumb.width + assert message.sticker.thumb.height == sticker.thumb.height + assert message.sticker.thumb.file_size == sticker.thumb.file_size @flaky(3, 1) - @timeout(10) - def test_get_and_download_sticker(self): - new_file = self._bot.getFile(self.sticker.file_id) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, sticker): + new_file = bot.get_file(sticker.file_id) - self.assertEqual(new_file.file_size, self.sticker.file_size) - self.assertEqual(new_file.file_id, self.sticker.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == sticker.file_size + assert new_file.file_id == sticker.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram.webp') - self.assertTrue(os.path.isfile('telegram.webp')) + assert os.path.isfile('telegram.webp') @flaky(3, 1) - @timeout(10) - def test_send_sticker_resend(self): - message = self._bot.sendSticker(chat_id=self._chat_id, sticker=self.sticker.file_id) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, sticker): + message = bot.send_sticker(chat_id=chat_id, sticker=sticker.file_id) - sticker = message.sticker - - self.assertEqual(sticker.file_id, self.sticker.file_id) - self.assertEqual(sticker.width, self.sticker.width) - self.assertEqual(sticker.height, self.sticker.height) - self.assertIsInstance(sticker.thumb, telegram.PhotoSize) - self.assertEqual(sticker.file_size, self.sticker.file_size) + assert message.sticker == sticker @flaky(3, 1) - @timeout(10) - def test_sticker_on_server_emoji(self): - server_file_id = "CAADAQADHAADyIsGAAFZfq1bphjqlgI" - message = self._bot.sendSticker(chat_id=self._chat_id, sticker=server_file_id) + @pytest.mark.timeout(10) + def test_send_on_server_emoji(self, bot, chat_id): + server_file_id = 'CAADAQADHAADyIsGAAFZfq1bphjqlgI' + message = bot.send_sticker(chat_id=chat_id, sticker=server_file_id) sticker = message.sticker if PY2: - self.assertEqual(sticker.emoji, self.emoji.decode('utf-8')) + assert sticker.emoji == self.emoji.decode('utf-8') else: - self.assertEqual(sticker.emoji, self.emoji) + assert sticker.emoji == self.emoji @flaky(3, 1) - @timeout(10) - def test_send_sticker_from_url(self): - message = self._bot.sendSticker(chat_id=self._chat_id, sticker=self.sticker_file_url) + @pytest.mark.timeout(10) + def test_send_from_url(self, bot, chat_id): + message = bot.send_sticker(chat_id=chat_id, sticker=self.sticker_file_url) sticker = message.sticker - self.assertIsInstance(sticker, telegram.Sticker) - self.assertIsInstance(sticker.file_id, str) - self.assertNotEqual(sticker.file_id, '') - self.assertEqual(sticker.file_size, self.sticker.file_size) - self.assertEqual(sticker.height, self.sticker.height) - self.assertEqual(sticker.width, self.sticker.width) - thumb = sticker.thumb - self.assertIsInstance(thumb, telegram.PhotoSize) - self.assertIsInstance(thumb.file_id, str) - self.assertNotEqual(thumb.file_id, '') - self.assertEqual(thumb.file_size, self.thumb.file_size) - self.assertEqual(thumb.width, self.thumb.width) - self.assertEqual(thumb.height, self.thumb.height) + assert isinstance(message.sticker, Sticker) + assert isinstance(message.sticker.file_id, str) + assert message.sticker.file_id != '' + assert message.sticker.width == sticker.width + assert message.sticker.height == sticker.height + assert message.sticker.file_size == sticker.file_size - def test_sticker_de_json(self): - sticker = telegram.Sticker.de_json(self.json_dict, self._bot) + assert isinstance(message.sticker.thumb, PhotoSize) + assert isinstance(message.sticker.thumb.file_id, str) + assert message.sticker.thumb.file_id != '' + assert message.sticker.thumb.width == sticker.thumb.width + assert message.sticker.thumb.height == sticker.thumb.height + assert message.sticker.thumb.file_size == sticker.thumb.file_size - self.assertEqual(sticker.file_id, self.sticker.file_id) - self.assertEqual(sticker.width, self.sticker.width) - self.assertEqual(sticker.height, self.sticker.height) - self.assertIsInstance(sticker.thumb, telegram.PhotoSize) - self.assertEqual(sticker.emoji, self.emoji) - self.assertEqual(sticker.file_size, self.sticker.file_size) + def test_de_json(self, bot, sticker): + json_dict = { + 'file_id': 'not a file id', + 'width': self.width, + 'height': self.height, + 'thumb': sticker.thumb.to_dict(), + 'emoji': self.emoji, + 'file_size': self.file_size + } + json_sticker = Sticker.de_json(json_dict, bot) + + assert json_sticker.file_id == 'not a file id' + assert json_sticker.width == self.width + assert json_sticker.height == self.height + assert json_sticker.emoji == self.emoji + assert json_sticker.file_size == self.file_size + assert json_sticker.thumb == sticker.thumb + + def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): + def test(_, url, data, **kwargs): + return data['sticker'] == sticker.file_id + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_sticker(sticker=sticker, chat_id=chat_id) + assert message + + def test_to_dict(self, sticker): + sticker_dict = sticker.to_dict() + + assert isinstance(sticker_dict, dict) + assert sticker_dict['file_id'] == sticker.file_id + assert sticker_dict['width'] == sticker.width + assert sticker_dict['height'] == sticker.height + assert sticker_dict['file_size'] == sticker.file_size + assert sticker_dict['thumb'] == sticker.thumb.to_dict() @flaky(3, 1) - @timeout(10) - def test_send_sticker_with_sticker(self): - message = self._bot.send_sticker(sticker=self.sticker, chat_id=self._chat_id) - sticker = message.sticker - - self.assertEqual(sticker, self.sticker) - - - def test_sticker_to_json(self): - self.assertTrue(self.is_json(self.sticker.to_json())) - - def test_sticker_to_dict(self): - sticker = self.sticker.to_dict() - - self.is_dict(sticker) - self.assertEqual(sticker['file_id'], self.sticker.file_id) - self.assertEqual(sticker['width'], self.sticker.width) - self.assertEqual(sticker['height'], self.sticker.height) - self.assertIsInstance(sticker['thumb'], dict) - self.assertEqual(sticker['file_size'], self.sticker.file_size) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_sticker(chat_id, open(os.devnull, 'rb')) @flaky(3, 1) - @timeout(10) - def test_error_send_sticker_empty_file(self): - json_dict = self.json_dict + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_sticker(chat_id, '') - del (json_dict['file_id']) - json_dict['sticker'] = open(os.devnull, 'rb') + def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_sticker(chat_id) - with self.assertRaises(telegram.TelegramError): - self._bot.sendSticker(chat_id=self._chat_id, **json_dict) + def test_equality(self, sticker): + a = Sticker(sticker.file_id, self.width, self.height) + b = Sticker(sticker.file_id, self.width, self.height) + c = Sticker(sticker.file_id, 0, 0) + d = Sticker('', self.width, self.height) + e = PhotoSize(sticker.file_id, self.width, self.height) - @flaky(3, 1) - @timeout(10) - def test_error_send_sticker_empty_file_id(self): - json_dict = self.json_dict + assert a == b + assert hash(a) == hash(b) + assert a is not b - del (json_dict['file_id']) - json_dict['sticker'] = '' + assert a == c + assert hash(a) == hash(c) - with self.assertRaises(telegram.TelegramError): - self._bot.sendSticker(chat_id=self._chat_id, **json_dict) + assert a != d + assert hash(a) != hash(d) - @flaky(3, 1) - @timeout(10) - def test_error_sticker_without_required_args(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - - with self.assertRaises(TypeError): - self._bot.sendSticker(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_reply_sticker(self): - """Test for Message.reply_sticker""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_sticker(self.sticker.file_id) - - self.assertNotEqual(message.sticker.file_id, '') - - def test_equality(self): - a = telegram.Sticker(self.sticker.file_id, self.sticker.width, self.sticker.height) - b = telegram.Sticker(self.sticker.file_id, self.sticker.width, self.sticker.height) - c = telegram.Sticker(self.sticker.file_id, 0, 0) - d = telegram.Sticker("", self.sticker.width, self.sticker.height) - e = telegram.PhotoSize(self.sticker.file_id, self.sticker.width, self.sticker.height) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) + assert a != e + assert hash(a) != hash(e) -class TestStickerSet(BaseTest, unittest.TestCase): - # TODO: Implement bot tests for StickerSet - # It's hard to test creation when we can't delete sticker sets - def setUp(self): - self.name = 'test_by_{0}'.format(self._bot.username) - self.title = 'Test stickers' - self.contains_masks = False - self.stickers = [telegram.Sticker('file_id', 512, 512)] +@pytest.fixture(scope='class') +def sticker_set(bot): + return bot.get_sticker_set('test_by_{0}'.format(bot.username)) - self.json_dict = { - 'name': self.name, + +class TestStickerSet(object): + title = 'Test stickers' + contains_masks = False + stickers = [Sticker('file_id', 512, 512)] + name = 'NOTAREALNAME' + + def test_de_json(self, bot): + name = 'test_by_{0}'.format(bot.username) + json_dict = { + 'name': name, 'title': self.title, 'contains_masks': self.contains_masks, 'stickers': [x.to_dict() for x in self.stickers] } + sticker_set = StickerSet.de_json(json_dict, bot) - def test_sticker_set_de_json(self): - sticker_set = telegram.StickerSet.de_json(self.json_dict, self._bot) + assert sticker_set.name == name + assert sticker_set.title == self.title + assert sticker_set.contains_masks == self.contains_masks + assert sticker_set.stickers == self.stickers - self.assertEqual(sticker_set.name, self.name) - self.assertEqual(sticker_set.title, self.title) - self.assertEqual(sticker_set.contains_masks, self.contains_masks) - self.assertEqual(sticker_set.stickers, self.stickers) + def test_sticker_set_to_dict(self, sticker_set): + sticker_set_dict = sticker_set.to_dict() - def test_sticker_set_to_json(self): - sticker_set = telegram.StickerSet.de_json(self.json_dict, self._bot) + assert isinstance(sticker_set_dict, dict) + assert sticker_set_dict['name'] == sticker_set.name + assert sticker_set_dict['title'] == sticker_set.title + assert sticker_set_dict['contains_masks'] == sticker_set.contains_masks + assert sticker_set_dict['stickers'][0] == sticker_set.stickers[0].to_dict() - self.assertTrue(self.is_json(sticker_set.to_json())) + def test_bot_methods_1(self, bot, sticker_set): + with open('tests/data/telegram_sticker.png', 'rb') as f: + file = bot.upload_sticker_file(95205500, f) + assert file + assert bot.add_sticker_to_set(95205500, sticker_set.name, file.file_id, '😄') - def test_sticker_set_to_dict(self): - sticker_set = telegram.StickerSet.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(sticker_set)) - self.assertDictEqual(self.json_dict, sticker_set) + @pytest.mark.xfail(raises=BadRequest, reason='STICKERSET_NOT_MODIFIED errors on deletion') + def test_bot_methods_2(self, bot, sticker_set): + updated_sticker_set = bot.get_sticker_set(sticker_set.name) + assert len(updated_sticker_set.stickers) > 1 # Otherwise test_bot_methods_1 failed + file_id = updated_sticker_set.stickers[-1].file_id + assert bot.set_sticker_position_in_set(file_id, len(updated_sticker_set.stickers) - 1) + assert bot.delete_sticker_from_set(file_id) def test_equality(self): - a = telegram.StickerSet(self.name, self.title, self.contains_masks, self.stickers) - b = telegram.StickerSet(self.name, self.title, self.contains_masks, self.stickers) - c = telegram.StickerSet(self.name, None, None, None) - d = telegram.StickerSet('blah', self.title, self.contains_masks, self.stickers) - e = telegram.Audio(self.name, 0, None, None) + a = StickerSet(self.name, self.title, self.contains_masks, self.stickers) + b = StickerSet(self.name, self.title, self.contains_masks, self.stickers) + c = StickerSet(self.name, None, None, None) + d = StickerSet('blah', self.title, self.contains_masks, self.stickers) + e = Audio(self.name, 0, None, None) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) + assert a != e + assert hash(a) != hash(e) -class TestMaskPosition(BaseTest, unittest.TestCase): - def setUp(self): - self.point = telegram.MaskPosition.EYES - self.x_shift = -1 - self.y_shift = 1 - self.scale = 2 +@pytest.fixture(scope='class') +def mask_position(): + return MaskPosition(TestMaskPosition.point, + TestMaskPosition.x_shift, + TestMaskPosition.y_shift, + TestMaskPosition.scale) - self.json_dict = { + +class TestMaskPosition(object): + point = MaskPosition.EYES + x_shift = -1 + y_shift = 1 + scale = 2 + + def test_mask_position_de_json(self, bot): + json_dict = { 'point': self.point, 'x_shift': self.x_shift, 'y_shift': self.y_shift, 'scale': self.scale } + mask_position = MaskPosition.de_json(json_dict, bot) - def test_mask_position_de_json(self): - mask_position = telegram.MaskPosition.de_json(self.json_dict, self._bot) + assert mask_position.point == self.point + assert mask_position.x_shift == self.x_shift + assert mask_position.y_shift == self.y_shift + assert mask_position.scale == self.scale - self.assertEqual(mask_position.point, self.point) - self.assertEqual(mask_position.x_shift, self.x_shift) - self.assertEqual(mask_position.y_shift, self.y_shift) - self.assertEqual(mask_position.scale, self.scale) + def test_mask_position_to_dict(self, mask_position): + mask_position_dict = mask_position.to_dict() - def test_mask_positiont_to_json(self): - mask_position = telegram.MaskPosition.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(mask_position.to_json())) - - def test_mask_position_to_dict(self): - mask_position = telegram.MaskPosition.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(mask_position)) - self.assertDictEqual(self.json_dict, mask_position) - - -if __name__ == '__main__': - unittest.main() + assert isinstance(mask_position_dict, dict) + assert mask_position_dict['point'] == mask_position.point + assert mask_position_dict['x_shift'] == mask_position.x_shift + assert mask_position_dict['y_shift'] == mask_position.y_shift + assert mask_position_dict['scale'] == mask_position.scale diff --git a/tests/test_stringcommandhandler.py b/tests/test_stringcommandhandler.py new file mode 100644 index 000000000..57c19e77d --- /dev/null +++ b/tests/test_stringcommandhandler.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import pytest + +from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import StringCommandHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +class TestStringCommandHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, str) + self.test_flag = test_bot and test_update + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def sch_callback_args(self, bot, update, args): + if update == '/test': + self.test_flag = len(args) == 0 + else: + self.test_flag = args == ['one', 'two'] + + def test_basic(self, dp): + handler = StringCommandHandler('test', self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update('/test') + dp.process_update('/test') + assert self.test_flag + + assert not handler.check_update('/nottest') + assert not handler.check_update('not /test in front') + assert handler.check_update('/test followed by text') + + def test_pass_args(self, dp): + handler = StringCommandHandler('test', self.sch_callback_args, pass_args=True) + dp.add_handler(handler) + + dp.process_update('/test') + assert self.test_flag + + self.test_flag = False + dp.process_update('/test one two') + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp): + handler = StringCommandHandler('test', self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update('/test') + assert self.test_flag + + dp.remove_handler(handler) + handler = StringCommandHandler('test', self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update('/test') + assert self.test_flag + + dp.remove_handler(handler) + handler = StringCommandHandler('test', self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update('/test') + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = StringCommandHandler('test', self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_stringregexhandler.py b/tests/test_stringregexhandler.py new file mode 100644 index 000000000..a1a99ecf0 --- /dev/null +++ b/tests/test_stringregexhandler.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +import pytest + +from telegram import (Bot, Update, Message, User, Chat, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) +from telegram.ext import StringRegexHandler + +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +ids = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query', 'callback_query_without_message') + + +@pytest.fixture(scope='class', params=params, ids=ids) +def false_update(request): + return Update(update_id=1, **request.param) + + +class TestStringRegexHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, str) + self.test_flag = test_bot and test_update + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def callback_group(self, bot, update, groups=None, groupdict=None): + if groups is not None: + self.test_flag = groups == ('t', ' message') + if groupdict is not None: + self.test_flag = groupdict == {'begin': 't', 'end': ' message'} + + def test_basic(self, dp): + handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update('test message') + dp.process_update('test message') + assert self.test_flag + + assert not handler.check_update('does not match') + + def test_with_passing_group_dict(self, dp): + handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_group, + pass_groups=True) + dp.add_handler(handler) + + dp.process_update('test message') + assert self.test_flag + + dp.remove_handler(handler) + handler = StringRegexHandler('(?P.*)est(?P.*)', self.callback_group, + pass_groupdict=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update('test message') + assert self.test_flag + + def test_pass_job_or_update_queue(self, dp): + handler = StringRegexHandler('test', self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update('test') + assert self.test_flag + + dp.remove_handler(handler) + handler = StringRegexHandler('test', self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update('test') + assert self.test_flag + + dp.remove_handler(handler) + handler = StringRegexHandler('test', self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update('test') + assert self.test_flag + + def test_other_update_types(self, false_update): + handler = StringRegexHandler('test', self.callback_basic) + assert not handler.check_update(false_update) diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index 8df9e7e49..6c89bf1d5 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -5,42 +5,45 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram -SuccessfulPayment""" -import sys -import unittest +import pytest -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import OrderInfo, SuccessfulPayment -class SuccessfulPaymentTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram SuccessfulPayment.""" +@pytest.fixture(scope='class') +def successful_payment(): + return SuccessfulPayment(TestSuccessfulPayment.currency, + TestSuccessfulPayment.total_amount, + TestSuccessfulPayment.invoice_payload, + TestSuccessfulPayment.telegram_payment_charge_id, + TestSuccessfulPayment.provider_payment_charge_id, + shipping_option_id=TestSuccessfulPayment.shipping_option_id, + order_info=TestSuccessfulPayment.order_info) - def setUp(self): - self.invoice_payload = 'invoice_payload' - self.shipping_option_id = 'shipping_option_id' - self.currency = 'EUR' - self.total_amount = 100 - self.order_info = telegram.OrderInfo() - self.telegram_payment_charge_id = 'telegram_payment_charge_id' - self.provider_payment_charge_id = 'provider_payment_charge_id' - self.json_dict = { +class TestSuccessfulPayment(object): + invoice_payload = 'invoice_payload' + shipping_option_id = 'shipping_option_id' + currency = 'EUR' + total_amount = 100 + order_info = OrderInfo() + telegram_payment_charge_id = 'telegram_payment_charge_id' + provider_payment_charge_id = 'provider_payment_charge_id' + + def test_de_json(self, bot): + json_dict = { 'invoice_payload': self.invoice_payload, 'shipping_option_id': self.shipping_option_id, 'currency': self.currency, @@ -49,52 +52,47 @@ class SuccessfulPaymentTest(BaseTest, unittest.TestCase): 'telegram_payment_charge_id': self.telegram_payment_charge_id, 'provider_payment_charge_id': self.provider_payment_charge_id } + successful_payment = SuccessfulPayment.de_json(json_dict, bot) - def test_successfulpayment_de_json(self): - successfulpayment = telegram.SuccessfulPayment.de_json(self.json_dict, self._bot) + assert successful_payment.invoice_payload == self.invoice_payload + assert successful_payment.shipping_option_id == self.shipping_option_id + assert successful_payment.currency == self.currency + assert successful_payment.order_info == self.order_info + assert successful_payment.telegram_payment_charge_id == self.telegram_payment_charge_id + assert successful_payment.provider_payment_charge_id == self.provider_payment_charge_id - self.assertEqual(successfulpayment.invoice_payload, self.invoice_payload) - self.assertEqual(successfulpayment.shipping_option_id, self.shipping_option_id) - self.assertEqual(successfulpayment.currency, self.currency) - self.assertEqual(successfulpayment.order_info, self.order_info) - self.assertEqual(successfulpayment.telegram_payment_charge_id, - self.telegram_payment_charge_id) - self.assertEqual(successfulpayment.provider_payment_charge_id, - self.provider_payment_charge_id) + def test_to_dict(self, successful_payment): + successful_payment_dict = successful_payment.to_dict() - def test_successfulpayment_to_json(self): - successfulpayment = telegram.SuccessfulPayment.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(successfulpayment.to_json())) - - def test_successfulpayment_to_dict(self): - successfulpayment = telegram.SuccessfulPayment.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(successfulpayment)) - self.assertDictEqual(self.json_dict, successfulpayment) + assert isinstance(successful_payment_dict, dict) + assert successful_payment_dict['invoice_payload'] == successful_payment.invoice_payload + assert successful_payment_dict['shipping_option_id'] == \ + successful_payment.shipping_option_id + assert successful_payment_dict['currency'] == successful_payment.currency + assert successful_payment_dict['order_info'] == successful_payment.order_info.to_dict() + assert successful_payment_dict['telegram_payment_charge_id'] == \ + successful_payment.telegram_payment_charge_id + assert successful_payment_dict['provider_payment_charge_id'] == \ + successful_payment.provider_payment_charge_id def test_equality(self): - a = telegram.SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id) - b = telegram.SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id) - c = telegram.SuccessfulPayment('', 0, '', self.telegram_payment_charge_id, - self.provider_payment_charge_id) - d = telegram.SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, - self.telegram_payment_charge_id, '') + a = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id) + b = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id) + c = SuccessfulPayment('', 0, '', self.telegram_payment_charge_id, + self.provider_payment_charge_id) + d = SuccessfulPayment(self.currency, self.total_amount, self.invoice_payload, + self.telegram_payment_charge_id, '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - -if __name__ == '__main__': - unittest.main() + assert a != d + assert hash(a) != hash(d) diff --git a/tests/test_telegramobject.py b/tests/test_telegramobject.py new file mode 100644 index 000000000..ced850dbb --- /dev/null +++ b/tests/test_telegramobject.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. + +import json as json_lib + +import pytest + +try: + import ujson +except ImportError: + ujson = None + +from telegram import TelegramObject + + +class TestTelegramObject(object): + def test_to_json_native(self, monkeypatch): + if ujson: + monkeypatch.setattr('ujson.dumps', json_lib.dumps) + # to_json simply takes whatever comes from to_dict, therefore we only need to test it once + telegram_object = TelegramObject() + + # Test that it works with a dict with str keys as well as dicts as lists as values + d = {'str': 'str', 'str2': ['str', 'str'], 'str3': {'str': 'str'}} + monkeypatch.setattr('telegram.TelegramObject.to_dict', lambda _: d) + json = telegram_object.to_json() + # Order isn't guarantied + assert '"str": "str"' in json + assert '"str2": ["str", "str"]' in json + assert '"str3": {"str": "str"}' in json + + # Now make sure that it doesn't work with not json stuff and that it fails loudly + # Tuples aren't allowed as keys in json + d = {('str', 'str'): 'str'} + + monkeypatch.setattr('telegram.TelegramObject.to_dict', lambda _: d) + with pytest.raises(TypeError): + telegram_object.to_json() + + @pytest.mark.skipif(not ujson, reason='ujson not installed') + def test_to_json_ujson(self, monkeypatch): + # to_json simply takes whatever comes from to_dict, therefore we only need to test it once + telegram_object = TelegramObject() + + # Test that it works with a dict with str keys as well as dicts as lists as values + d = {'str': 'str', 'str2': ['str', 'str'], 'str3': {'str': 'str'}} + monkeypatch.setattr('telegram.TelegramObject.to_dict', lambda _: d) + json = telegram_object.to_json() + # Order isn't guarantied and ujon discards whitespace + assert '"str":"str"' in json + assert '"str2":["str","str"]' in json + assert '"str3":{"str":"str"}' in json + + # Test that ujson allows tuples + # NOTE: This could be seen as a bug (since it's differnt from the normal "json", + # but we test it anyways + d = {('str', 'str'): 'str'} + + monkeypatch.setattr('telegram.TelegramObject.to_dict', lambda _: d) + telegram_object.to_json() diff --git a/tests/test_typehandler.py b/tests/test_typehandler.py new file mode 100644 index 000000000..431191236 --- /dev/null +++ b/tests/test_typehandler.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2017 +# 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/]. +from collections import OrderedDict + +import pytest + +from telegram import Bot +from telegram.ext import TypeHandler + + +class TestTypeHandler(object): + test_flag = False + + @pytest.fixture(autouse=True) + def reset(self): + self.test_flag = False + + def callback_basic(self, bot, update): + test_bot = isinstance(bot, Bot) + test_update = isinstance(update, dict) + self.test_flag = test_bot and test_update + + def callback_queue_1(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) or (update_queue is not None) + + def callback_queue_2(self, bot, update, job_queue=None, update_queue=None): + self.test_flag = (job_queue is not None) and (update_queue is not None) + + def test_basic(self, dp): + handler = TypeHandler(dict, self.callback_basic) + dp.add_handler(handler) + + assert handler.check_update({'a': 1, 'b': 2}) + assert not handler.check_update('not a dict') + dp.process_update({'a': 1, 'b': 2}) + assert self.test_flag + + def test_strict(self): + handler = TypeHandler(dict, self.callback_basic, strict=True) + o = OrderedDict({'a': 1, 'b': 2}) + assert handler.check_update({'a': 1, 'b': 2}) + assert not handler.check_update(o) + + def test_pass_job_or_update_queue(self, dp): + handler = TypeHandler(dict, self.callback_queue_1, pass_job_queue=True) + dp.add_handler(handler) + + dp.process_update({'a': 1, 'b': 2}) + assert self.test_flag + + dp.remove_handler(handler) + handler = TypeHandler(dict, self.callback_queue_1, pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update({'a': 1, 'b': 2}) + assert self.test_flag + + dp.remove_handler(handler) + handler = TypeHandler(dict, self.callback_queue_2, pass_job_queue=True, + pass_update_queue=True) + dp.add_handler(handler) + + self.test_flag = False + dp.process_update({'a': 1, 'b': 2}) + assert self.test_flag diff --git a/tests/test_update.py b/tests/test_update.py index d3de195c2..cf5281789 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -1,116 +1,138 @@ -# !/usr/bin/env python +#!/usr/bin/env python # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Update""" -import sys -import unittest +import pytest -sys.path.append('.') +from telegram import (Message, User, Update, Chat, CallbackQuery, InlineQuery, + ChosenInlineResult, ShippingQuery, PreCheckoutQuery) -import telegram -from tests.base import BaseTest +message = Message(1, User(1, ''), None, Chat(1, ''), text='Text') + +params = [ + {'message': message}, + {'edited_message': message}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat', message=message)}, + {'channel_post': message}, + {'edited_channel_post': message}, + {'inline_query': InlineQuery(1, User(1, ''), '', '')}, + {'chosen_inline_result': ChosenInlineResult('id', User(1, ''), '')}, + {'shipping_query': ShippingQuery('id', User(1, ''), '', None)}, + {'pre_checkout_query': PreCheckoutQuery('id', User(1, ''), '', 0, '')}, + {'callback_query': CallbackQuery(1, User(1, ''), 'chat')} +] + +all_types = ('message', 'edited_message', 'callback_query', 'channel_post', + 'edited_channel_post', 'inline_query', 'chosen_inline_result', + 'shipping_query', 'pre_checkout_query') + +ids = all_types + ('callback_query_without_message',) -class UpdateTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Update.""" +@pytest.fixture(params=params, ids=ids) +def update(request): + return Update(update_id=TestUpdate.update_id, **request.param) - def setUp(self): - self.update_id = 868573637 - self.message = { - 'message_id': 319, - 'from': { - 'id': 12173560, - 'first_name': "Leandro", - 'last_name': "S.", - 'username': "leandrotoledo" - }, - 'chat': { - 'id': 12173560, - 'type': 'private', - 'first_name': "Leandro", - 'last_name': "S.", - 'username': "leandrotoledo" - }, - 'date': 1441644592, - 'text': "Update Test" - } - self.json_dict = {'update_id': self.update_id, 'message': self.message} +class TestUpdate(object): + update_id = 868573637 - def test_update_de_json(self): - update = telegram.Update.de_json(self.json_dict, self._bot) + @pytest.mark.parametrize('paramdict', argvalues=params, ids=ids) + def test_de_json(self, bot, paramdict): + json_dict = {'update_id': TestUpdate.update_id} + # Convert the single update 'item' to a dict of that item and apply it to the json_dict + json_dict.update({k: v.to_dict() for k, v in paramdict.items()}) + update = Update.de_json(json_dict, bot) - self.assertEqual(update.update_id, self.update_id) - self.assertTrue(isinstance(update.message, telegram.Message)) + assert update.update_id == self.update_id - def test_update_de_json_empty(self): - update = telegram.Update.de_json(None, self._bot) + # Make sure only one thing in the update (other than update_id) is not None + i = 0 + for type in all_types: + if getattr(update, type) is not None: + i += 1 + assert getattr(update, type) == paramdict[type] + assert i == 1 - self.assertFalse(update) + def test_update_de_json_empty(self, bot): + update = Update.de_json(None, bot) - def test_update_to_json(self): - update = telegram.Update.de_json(self.json_dict, self._bot) + assert update is None - self.assertTrue(self.is_json(update.to_json())) + def test_to_dict(self, update): + update_dict = update.to_dict() - def test_update_to_dict(self): - update = telegram.Update.de_json(self.json_dict, self._bot) + assert isinstance(update_dict, dict) + assert update_dict['update_id'] == update.update_id + for type in all_types: + if getattr(update, type) is not None: + assert update_dict[type] == getattr(update, type).to_dict() - self.assertTrue(self.is_dict(update.to_dict())) - self.assertEqual(update['update_id'], self.update_id) - self.assertTrue(isinstance(update['message'], telegram.Message)) - - def test_effective_chat(self): - update = telegram.Update.de_json(self.json_dict, self._bot) + def test_effective_chat(self, update): + # Test that it's sometimes None per docstring chat = update.effective_chat - self.assertEqual(update.message.chat, chat) + if not (update.inline_query is not None + or update.chosen_inline_result is not None + or (update.callback_query is not None + and update.callback_query.message is None) + or update.shipping_query is not None + or update.pre_checkout_query is not None): + assert chat.id == 1 + else: + assert chat is None - def test_effective_user(self): - update = telegram.Update.de_json(self.json_dict, self._bot) + def test_effective_user(self, update): + # Test that it's sometimes None per docstring user = update.effective_user - self.assertEqual(update.message.from_user, user) + if not (update.channel_post is not None or update.edited_channel_post is not None): + assert user.id == 1 + else: + assert user is None - def test_effective_message(self): - update = telegram.Update.de_json(self.json_dict, self._bot) - message = update.effective_message - self.assertEqual(update.message.text, message.text) + def test_effective_message(self, update): + # Test that it's sometimes None per docstring + eff_message = update.effective_message + if not (update.inline_query is not None + or update.chosen_inline_result is not None + or (update.callback_query is not None + and update.callback_query.message is None) + or update.shipping_query is not None + or update.pre_checkout_query is not None): + assert eff_message.message_id == message.message_id + else: + assert eff_message is None def test_equality(self): - a = telegram.Update(self.update_id, message=self.message) - b = telegram.Update(self.update_id, message=self.message) - c = telegram.Update(self.update_id) - d = telegram.Update(0, message=self.message) - e = telegram.User(self.update_id, "") + a = Update(self.update_id, message=message) + b = Update(self.update_id, message=message) + c = Update(self.update_id) + d = Update(0, message=message) + e = User(self.update_id, '') - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_updater.py b/tests/test_updater.py index 07849cd27..066ad9dc6 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -1,38 +1,28 @@ #!/usr/bin/env python -# encoding: utf-8 # # A library that provides a Python interface to the Telegram Bot API # Copyright (C) 2015-2017 # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Updater, Dispatcher, -WebhookServer and WebhookHandler -""" -import logging +import os import signal import sys -import os -import re -import unittest -from datetime import datetime -from time import sleep from queue import Queue from random import randrange - -from future.builtins import bytes +from threading import Thread +from time import sleep try: # python2 @@ -42,825 +32,179 @@ except ImportError: from urllib.request import Request, urlopen from urllib.error import HTTPError -sys.path.append('.') +import pytest +from future.builtins import bytes -from telegram import (Update, Message, TelegramError, User, Chat, Bot, - InlineQuery, CallbackQuery) -from telegram.ext import * -from telegram.ext.dispatcher import run_async +from telegram import TelegramError, Message, User, Chat, Update, Bot from telegram.error import Unauthorized, InvalidToken -from tests.base import BaseTest -from threading import Lock, Thread, current_thread +from telegram.ext import Updater -# Enable logging -root = logging.getLogger() -root.setLevel(logging.INFO) - -ch = logging.StreamHandler(sys.stdout) -ch.setLevel(logging.WARN) -formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s ' '- %(message)s') -ch.setFormatter(formatter) -root.addHandler(ch) +signalskip = pytest.mark.skipif(sys.platform == 'win32', + reason='Can\'t send signals without stopping ' + 'whole process on windows') -class UpdaterTest(BaseTest, unittest.TestCase): - """ - This object represents Tests for Updater, Dispatcher, WebhookServer and - WebhookHandler - """ +@pytest.fixture(scope='function') +def updater(bot): + up = Updater(bot=bot, workers=2) + yield up + if up.running: + up.stop() - _updater = None - received_message = None - def setUp(self): - self.updater = None - self.received_message = None - self.message_count = 0 - self.lock = Lock() - - @property - def updater(self): - return self._updater - - @updater.setter - def updater(self, val): - if self._updater: - self._updater.stop() - self._updater.dispatcher._reset_singleton() - del self._updater.dispatcher - - self._updater = val - - def _setup_updater(self, *args, **kwargs): - bot = MockBot(*args, **kwargs) - self.updater = Updater(workers=2, bot=bot) - - def tearDown(self): - self.updater = None +class TestUpdater(object): + message_count = 0 + received = None + attempts = 0 + @pytest.fixture(autouse=True) def reset(self): self.message_count = 0 - self.received_message = None + self.received = None + self.attempts = 0 - def telegramHandlerTest(self, bot, update): - self.received_message = update.message.text - self.message_count += 1 + def error_handler(self, bot, update, error): + self.received = error.message - def telegramHandlerEditedTest(self, bot, update): - self.received_message = update.effective_message.text - self.message_count += 1 + def callback(self, bot, update): + self.received = update.message.text - def telegramInlineHandlerTest(self, bot, update): - self.received_message = (update.inline_query, update.chosen_inline_result) - self.message_count += 1 + # TODO: test clean= argument - def telegramCallbackHandlerTest(self, bot, update): - self.received_message = update.callback_query - self.message_count += 1 + def test_error_on_get_updates(self, monkeypatch, updater): + def test(*args, **kwargs): + raise TelegramError('Test Error 2') - def telegramShippingHandlerTest(self, bot, update): - self.received_message = update.shipping_query - self.message_count += 1 - - def telegramPreCheckoutHandlerTest(self, bot, update): - self.received_message = update.pre_checkout_query - self.message_count += 1 - - @run_async - def asyncHandlerTest(self, bot, update): - sleep(1) - with self.lock: - self.received_message = update.message.text - self.message_count += 1 - - def stringHandlerTest(self, bot, update): - self.received_message = update - self.message_count += 1 - - def regexGroupHandlerTest(self, bot, update, groups, groupdict): - self.received_message = (groups, groupdict) - self.message_count += 1 - - def additionalArgsTest(self, bot, update, update_queue, job_queue, args): - job_queue.put(Job(lambda bot, job: job.schedule_removal(), 0.1)) - - self.received_message = update - self.message_count += 1 - - if args[0] == 'resend': - update_queue.put('/test5 noresend') - elif args[0] == 'noresend': - pass - - def userAndChatDataTest(self, bot, update, user_data, chat_data): - user_data['text'] = update.message.text - chat_data['text'] = update.message.text - self.received_message = update.message.text - self.message_count += 1 - - @run_async - def asyncAdditionalHandlerTest(self, bot, update, update_queue=None): - sleep(1) - with self.lock: - if update_queue is not None: - self.received_message = update.message.text - self.message_count += 1 - - def errorRaisingHandlerTest(self, bot, update): - raise TelegramError(update) - - def errorHandlerTest(self, bot, update, error): - self.received_message = error.message - self.message_count += 1 - - def test_addRemoveTelegramMessageHandler(self): - self._setup_updater('Test') - d = self.updater.dispatcher - from telegram.ext import Filters - handler = MessageHandler([Filters.text], self.telegramHandlerTest) - d.add_handler(handler) - self.updater.start_polling(0.01) + monkeypatch.setattr('telegram.Bot.get_updates', test) + monkeypatch.setattr('telegram.Bot.set_webhook', lambda *args, **kwargs: True) + updater.dispatcher.add_error_handler(self.error_handler) + updater.start_polling(0.01) sleep(.1) - self.assertEqual(self.received_message, 'Test') + assert self.received == 'Test Error 2' - # Remove handler - d.remove_handler(handler) - self.reset() - - self.updater.bot.send_messages = 1 - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_editedMessageHandler(self): - self._setup_updater('Test', edited=True) - d = self.updater.dispatcher - from telegram.ext import Filters - handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, edited_updates=True) - d.add_handler(handler) - self.updater.start_polling(0.01) - sleep(.1) - self.assertEqual(self.received_message, 'Test') - - self.reset() - d.remove_handler(handler) - handler = MessageHandler( - Filters.text, - self.telegramHandlerEditedTest, - edited_updates=False, - message_updates=False) - d.add_handler(handler) - self.updater.bot.send_messages = 1 - sleep(.1) - self.assertTrue(None is self.received_message) - - handler = MessageHandler(Filters.text, self.telegramHandlerEditedTest, allow_edited=True) - d.add_handler(handler) - self.reset() - self.updater.bot.send_messages = 1 - sleep(.1) - self.assertEqual(self.received_message, 'Test') - - def test_addTelegramMessageHandlerMultipleMessages(self): - self._setup_updater('Multiple', 100) - self.updater.dispatcher.add_handler(MessageHandler(Filters.all, self.telegramHandlerTest)) - self.updater.start_polling(0.0) - sleep(2) - self.assertEqual(self.received_message, 'Multiple') - self.assertEqual(self.message_count, 100) - - def test_addRemoveTelegramRegexHandler(self): - self._setup_updater('Test2') - d = self.updater.dispatcher - regobj = re.compile('Te.*') - handler = RegexHandler(regobj, self.telegramHandlerTest) - self.updater.dispatcher.add_handler(handler) - self.updater.start_polling(0.01) - sleep(.1) - self.assertEqual(self.received_message, 'Test2') - - # Remove handler - d.remove_handler(handler) - self.reset() - - self.updater.bot.send_messages = 1 - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_regex_handler_without_message(self): - self._setup_updater('Test3') - d = self.updater.dispatcher - handler = RegexHandler(r'Te.*', self.telegramHandlerTest) - d.add_handler(handler) - - # message, no text - m = Message(1, User(1, "testuser"), None, Chat(2, "private"), video="My_vid", - caption="test ") - d.process_update(Update(1, message=m)) - self.assertEqual(self.message_count, 0) - - # no message - c = InlineQuery(2, User(1, "testuser"), "my_query", offset=15) - d.process_update(Update(2, inline_query=c)) - self.assertEqual(self.message_count, 0) - - def test_addRemoveTelegramCommandHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = CommandHandler('test', self.telegramHandlerTest) - self.updater.dispatcher.add_handler(handler) - user = User(first_name="singelton", id=404) - bot = self.updater.bot - queue = self.updater.start_polling(0.01) - - # regular use - message = Message(0, user, None, None, text="/test", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/test') - - # assigned use - message = Message(0, user, None, None, text="/test@MockBot", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/test@MockBot') - message.text = "/test@mockbot" - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/test@mockbot') - - # directed at other bot - self.reset() - message = Message(0, user, None, None, text="/test@OtherBot", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(None is self.received_message) - - # case insensitivity - self.reset() - message = Message(0, user, None, None, text="/Test", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.received_message, '/Test') - handler = CommandHandler('Test', self.telegramHandlerTest) - self.updater.dispatcher.add_handler(handler) - message = Message(0, user, None, None, text="/test", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(self.received_message, '/test') - - # Remove handler - d.remove_handler(handler) - handler = CommandHandler('test', self.telegramHandlerEditedTest, allow_edited=False) - d.add_handler(handler) - self.reset() - - self.updater.bot.send_messages = 1 - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_filterPassTelegramCommandHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = CommandHandler('test', self.telegramHandlerTest, lambda msg: True) - self.updater.dispatcher.add_handler(handler) - user = User(first_name="singelton", id=404) - bot = self.updater.bot - queue = self.updater.start_polling(0.01) - - message = Message(0, user, None, None, text="/test", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/test') - - def test_filterNotPassTelegramCommandHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = CommandHandler('test', self.telegramHandlerTest, lambda msg: False) - self.updater.dispatcher.add_handler(handler) - user = User(first_name="singelton", id=404) - bot = self.updater.bot - queue = self.updater.start_polling(0.01) - - message = Message(0, user, None, None, text="/test", bot=bot) - queue.put(Update(update_id=0, message=message)) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_CommandHandler_commandList(self): - self._setup_updater('', messages=0) - handler = CommandHandler(['foo', 'bar', 'spameggs'], self.telegramHandlerTest) - self.updater.dispatcher.add_handler(handler) - bot = self.updater.bot - user = User(0, 'TestUser') - queue = self.updater.start_polling(0.01) - - message = Message(0, user, 0, None, text='/foo', bot=bot) - queue.put(Update(0, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/foo') - - message.text = '/bar' - queue.put(Update(1, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/bar') - - message.text = '/spameggs' - queue.put(Update(2, message=message)) - sleep(.1) - self.assertEqual(self.received_message, '/spameggs') - - self.reset() - message.text = '/not_in_list' - queue.put(Update(3, message=message)) - sleep(.1) - self.assertTrue(self.received_message is None) - - def test_addRemoveStringRegexHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = StringRegexHandler('Te.*', self.stringHandlerTest) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - queue.put('Test3') - sleep(.1) - self.assertEqual(self.received_message, 'Test3') - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put('Test3') - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemoveStringCommandHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = StringCommandHandler('test3', self.stringHandlerTest) - d.add_handler(handler) - - queue = self.updater.start_polling(0.01) - queue.put('/test3') - sleep(.1) - self.assertEqual(self.received_message, '/test3') - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put('/test3') - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemoveErrorHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - d.add_error_handler(self.errorHandlerTest) - queue = self.updater.start_polling(0.01) - error = TelegramError("Unauthorized.") - queue.put(error) - sleep(.1) - self.assertEqual(self.received_message, "Unauthorized.") - - # Remove handler - d.remove_error_handler(self.errorHandlerTest) - self.reset() - - queue.put(error) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_errorInHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = StringRegexHandler('.*', self.errorRaisingHandlerTest) - d.add_handler(handler) - self.updater.dispatcher.add_error_handler(self.errorHandlerTest) - queue = self.updater.start_polling(0.01) - - queue.put('Test Error 1') - sleep(.1) - self.assertEqual(self.received_message, 'Test Error 1') - - def test_cleanBeforeStart(self): - self._setup_updater('') - d = self.updater.dispatcher - handler = MessageHandler([], self.telegramHandlerTest) - d.add_handler(handler) - self.updater.start_polling(0.01, clean=True) - sleep(.1) - self.assertEqual(self.message_count, 0) - self.assertIsNone(self.received_message) - - def test_errorOnGetUpdates(self): - self._setup_updater('', raise_error=True) - d = self.updater.dispatcher - d.add_error_handler(self.errorHandlerTest) - self.updater.start_polling(0.01) - sleep(.1) - self.assertEqual(self.received_message, "Test Error 2") - - def test_addRemoveTypeHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = TypeHandler(dict, self.stringHandlerTest) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - payload = {"Test": 42} - queue.put(payload) - sleep(.1) - self.assertEqual(self.received_message, payload) - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put(payload) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemoveInlineQueryHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = InlineQueryHandler(self.telegramInlineHandlerTest) - handler2 = ChosenInlineResultHandler(self.telegramInlineHandlerTest) - d.add_handler(handler) - d.add_handler(handler2) - 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.remove_handler(handler) - d.remove_handler(handler2) - self.reset() - - queue.put(update) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemoveCallbackQueryHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = CallbackQueryHandler(self.telegramCallbackHandlerTest) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - update = Update(update_id=0, callback_query="testcallback") - queue.put(update) - sleep(.1) - self.assertEqual(self.received_message, "testcallback") - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put(update) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemoveShippingQueryHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = ShippingQueryHandler(self.telegramShippingHandlerTest) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - update = Update(update_id=0, shipping_query="testshipping") - queue.put(update) - sleep(.1) - self.assertEqual(self.received_message, "testshipping") - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put(update) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_addRemovePreCheckoutQueryHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = PreCheckoutQueryHandler(self.telegramPreCheckoutHandlerTest) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - update = Update(update_id=0, pre_checkout_query="testprecheckout") - queue.put(update) - sleep(.1) - self.assertEqual(self.received_message, "testprecheckout") - - # Remove handler - d.remove_handler(handler) - self.reset() - - queue.put(update) - sleep(.1) - self.assertTrue(None is self.received_message) - - def test_runAsync(self): - self._setup_updater('Test5', messages=2) - d = self.updater.dispatcher - handler = MessageHandler([], self.asyncHandlerTest) - d.add_handler(handler) - self.updater.start_polling(0.01) - sleep(1.2) - self.assertEqual(self.received_message, 'Test5') - self.assertEqual(self.message_count, 2) - - def test_multiple_dispatchers(self): - - def get_dispatcher_name(q): - q.put(current_thread().name) - sleep(1.2) - - d1 = Dispatcher(MockBot('disp1'), Queue()) - d2 = Dispatcher(MockBot('disp2'), Queue()) - q1 = Queue() - q2 = Queue() - d1._init_async_threads('test_1', workers=1) - d2._init_async_threads('test_2', workers=1) - - try: - d1.run_async(get_dispatcher_name, q1) - d2.run_async(get_dispatcher_name, q2) - - name1 = q1.get() - name2 = q2.get() - - self.assertNotEqual(name1, name2) - finally: - d1.stop() - d2.stop() - # following three lines are for pypy unitests - d1._reset_singleton() - del d1 - del d2 - - def test_multiple_dispatcers_no_decorator(self): - - @run_async - def must_raise_runtime_error(): - pass - - d1 = Dispatcher(MockBot('disp1'), Queue(), workers=1) - d2 = Dispatcher(MockBot('disp2'), Queue(), workers=1) - - self.assertRaises(RuntimeError, must_raise_runtime_error) - - d1.stop() - d2.stop() - # following three lines are for pypy unitests - d1._reset_singleton() - del d1 - del d2 - - def test_additionalArgs(self): - self._setup_updater('', messages=0) - handler = StringCommandHandler( - 'test5', - self.additionalArgsTest, - pass_update_queue=True, - pass_job_queue=True, - pass_args=True) - self.updater.dispatcher.add_handler(handler) - - queue = self.updater.start_polling(0.01) - queue.put('/test5 resend') - sleep(.1) - self.assertEqual(self.received_message, '/test5 noresend') - self.assertEqual(self.message_count, 2) - - def test_user_and_chat_data(self): - self._setup_updater('/test_data', messages=1) - handler = CommandHandler( - 'test_data', self.userAndChatDataTest, pass_user_data=True, pass_chat_data=True) - self.updater.dispatcher.add_handler(handler) - - self.updater.start_polling(0.01) - sleep(.1) - self.assertEqual(self.received_message, '/test_data') - self.assertEqual(self.message_count, 1) - self.assertDictEqual(dict(self.updater.dispatcher.user_data), {0: {'text': '/test_data'}}) - self.assertDictEqual(dict(self.updater.dispatcher.chat_data), {0: {'text': '/test_data'}}) - - def test_regexGroupHandler(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = StringRegexHandler( - '^(This).*?(?Pregex group).*', - self.regexGroupHandlerTest, - pass_groupdict=True, - pass_groups=True) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - queue.put('This is a test message for regex group matching.') - sleep(.1) - self.assertEqual(self.received_message, (('This', 'regex group'), { - 'testgroup': 'regex group' - })) - - def test_regexGroupHandlerInlineQuery(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = InlineQueryHandler( - self.regexGroupHandlerTest, - pattern='^(This).*?(?Pregex group).*', - pass_groupdict=True, - pass_groups=True) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - queue.put( - Update( - update_id=0, - inline_query=InlineQuery( - 0, None, 'This is a test message for regex group matching.', None))) - - sleep(.1) - self.assertEqual(self.received_message, (('This', 'regex group'), { - 'testgroup': 'regex group' - })) - - def test_regexGroupHandlerCallbackQuery(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = CallbackQueryHandler( - self.regexGroupHandlerTest, - pattern='^(This).*?(?Pregex group).*', - pass_groupdict=True, - pass_groups=True) - d.add_handler(handler) - queue = self.updater.start_polling(0.01) - queue.put( - Update( - update_id=0, - callback_query=CallbackQuery( - 0, None, None, data='This is a test message for regex group matching.'))) - - sleep(.1) - self.assertEqual(self.received_message, (('This', 'regex group'), { - 'testgroup': 'regex group' - })) - - def test_runAsyncWithAdditionalArgs(self): - self._setup_updater('Test6', messages=2) - d = self.updater.dispatcher - handler = MessageHandler([], self.asyncAdditionalHandlerTest, pass_update_queue=True) - d.add_handler(handler) - self.updater.start_polling(0.01) - sleep(1.2) - self.assertEqual(self.received_message, 'Test6') - self.assertEqual(self.message_count, 2) - - def test_webhook(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = MessageHandler([], self.telegramHandlerTest) - d.add_handler(handler) + def test_webhook(self, monkeypatch, updater): + q = Queue() + monkeypatch.setattr('telegram.Bot.set_webhook', lambda *args, **kwargs: True) + monkeypatch.setattr('telegram.Bot.delete_webhook', lambda *args, **kwargs: True) + monkeypatch.setattr('telegram.ext.Dispatcher.process_update', lambda _, u: q.put(u)) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis - self.updater.start_webhook( + updater.start_webhook( ip, port, url_path='TOKEN', cert='./tests/test_updater.py', - key='./tests/test_updater.py', - webhook_url=None) - sleep(0.5) + key='./tests/test_updater.py', ) + sleep(.2) # SSL-Wrapping will fail, so we start the server without SSL - Thread(target=self.updater.httpd.serve_forever).start() + thr = Thread(target=updater.httpd.serve_forever) + thr.start() - # Now, we send an update to the server via urlopen - message = Message( - 1, User(1, "Tester"), datetime.now(), Chat( - 1, "group", title="Test Group")) + try: + # Now, we send an update to the server via urlopen + update = Update(1, message=Message(1, User(1, ''), None, Chat(1, ''), text='Webhook')) + self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN') + sleep(.2) + assert q.get(False) == update - message.text = "Webhook Test" - update = Update(1) - update.message = message + response = self._send_webhook_msg(ip, port, None, 'webookhandler.py') + assert b'' == response.read() + assert 200 == response.code - self._send_webhook_msg(ip, port, update.to_json(), 'TOKEN') + response = self._send_webhook_msg(ip, port, None, 'webookhandler.py', + get_method=lambda: 'HEAD') - sleep(1) - self.assertEqual(self.received_message, 'Webhook Test') + assert b'' == response.read() + assert 200 == response.code - print("Test other webhook server functionalities...") - response = self._send_webhook_msg(ip, port, None, 'webookhandler.py') - self.assertEqual(b'', response.read()) - self.assertEqual(200, response.code) + # Test multiple shutdown() calls + updater.httpd.shutdown() + finally: + updater.httpd.shutdown() + thr.join() - response = self._send_webhook_msg( - ip, port, None, 'webookhandler.py', get_method=lambda: 'HEAD') - - self.assertEqual(b'', response.read()) - self.assertEqual(200, response.code) - - # Test multiple shutdown() calls - self.updater.httpd.shutdown() - self.updater.httpd.shutdown() - self.assertTrue(True) - - def test_webhook_no_ssl(self): - self._setup_updater('', messages=0) - d = self.updater.dispatcher - handler = MessageHandler([], self.telegramHandlerTest) - d.add_handler(handler) + def test_webhook_no_ssl(self, monkeypatch, updater): + q = Queue() + monkeypatch.setattr('telegram.Bot.set_webhook', lambda *args, **kwargs: True) + monkeypatch.setattr('telegram.Bot.delete_webhook', lambda *args, **kwargs: True) + monkeypatch.setattr('telegram.ext.Dispatcher.process_update', lambda _, u: q.put(u)) ip = '127.0.0.1' port = randrange(1024, 49152) # Select random port for travis - self.updater.start_webhook(ip, port, webhook_url=None) - sleep(0.5) + updater.start_webhook(ip, port, webhook_url=None) + sleep(.2) # Now, we send an update to the server via urlopen - message = Message( - 1, User(1, "Tester 2"), datetime.now(), Chat( - 1, 'group', title="Test Group 2")) - - message.text = "Webhook Test 2" - update = Update(1) - update.message = message - + update = Update(1, message=Message(1, User(1, ''), None, Chat(1, ''), text='Webhook 2')) self._send_webhook_msg(ip, port, update.to_json()) - sleep(1) - self.assertEqual(self.received_message, 'Webhook Test 2') + sleep(.2) + assert q.get(False) == update - def test_start_dispatcher_twice(self): - self._setup_updater('', messages=0) - self.updater.start_polling(0.1) - sleep(0.5) - self.updater.dispatcher.start() + def test_bootstrap_retries_success(self, monkeypatch, updater): + retries = 2 - def test_bootstrap_retries_success(self): - retries = 3 - self._setup_updater('', messages=0, bootstrap_retries=retries) + def attempt(_, *args, **kwargs): + if self.attempts < retries: + self.attempts += 1 + raise TelegramError('') - self.updater._bootstrap(retries, False, 'path', None) - self.assertEqual(self.updater.bot.bootstrap_attempts, retries) + monkeypatch.setattr('telegram.Bot.set_webhook', attempt) - def test_bootstrap_retries_unauth(self): - retries = 3 - self._setup_updater( - '', messages=0, bootstrap_retries=retries, bootstrap_err=Unauthorized("Unauthorized")) + updater._bootstrap(retries, False, 'path', None) + assert self.attempts == retries - self.assertRaises(Unauthorized, self.updater._bootstrap, retries, False, 'path', None) - self.assertEqual(self.updater.bot.bootstrap_attempts, 1) - - def test_bootstrap_retries_invalid_token(self): - retries = 3 - self._setup_updater( - '', messages=0, bootstrap_retries=retries, bootstrap_err=InvalidToken()) - - self.assertRaises(InvalidToken, self.updater._bootstrap, retries, False, 'path', None) - self.assertEqual(self.updater.bot.bootstrap_attempts, 1) - - def test_bootstrap_retries_fail(self): + @pytest.mark.parametrize(('error', 'attempts'), + argvalues=[ + (TelegramError(''), 2), + (Unauthorized(''), 1), + (InvalidToken(), 1) + ], + ids=('TelegramError', 'Unauthorized', 'InvalidToken')) + def test_bootstrap_retries_error(self, monkeypatch, updater, error, attempts): retries = 1 - self._setup_updater('', messages=0, bootstrap_retries=retries) - self.assertRaisesRegexp(TelegramError, 'test', self.updater._bootstrap, retries - 1, False, - 'path', None) - self.assertEqual(self.updater.bot.bootstrap_attempts, 1) + def attempt(_, *args, **kwargs): + self.attempts += 1 + raise error - def test_webhook_invalid_posts(self): - self._setup_updater('', messages=0) + monkeypatch.setattr('telegram.Bot.set_webhook', attempt) + with pytest.raises(type(error)): + updater._bootstrap(retries, False, 'path', None) + assert self.attempts == attempts + + def test_webhook_invalid_posts(self, updater): ip = '127.0.0.1' port = randrange(1024, 49152) # select random port for travis thr = Thread( - target=self.updater._start_webhook, + target=updater._start_webhook, args=(ip, port, '', None, None, 0, False, None, None)) thr.start() - sleep(0.5) + sleep(.2) try: - with self.assertRaises(HTTPError) as ctx: - self._send_webhook_msg( - ip, port, 'data', content_type='application/xml') - self.assertEqual(ctx.exception.code, 403) + with pytest.raises(HTTPError) as excinfo: + self._send_webhook_msg(ip, port, 'data', + content_type='application/xml') + assert excinfo.value.code == 403 - with self.assertRaises(HTTPError) as ctx: + with pytest.raises(HTTPError) as excinfo: self._send_webhook_msg(ip, port, 'dummy-payload', content_len=-2) - self.assertEqual(ctx.exception.code, 403) + assert excinfo.value.code == 403 # TODO: prevent urllib or the underlying from adding content-length - # with self.assertRaises(HTTPError) as ctx: - # self._send_webhook_msg(ip, port, 'dummy-payload', - # content_len=None) - # self.assertEqual(ctx.exception.code, 411) + # with pytest.raises(HTTPError) as excinfo: + # self._send_webhook_msg(ip, port, 'dummy-payload', content_len=None) + # assert excinfo.value.code == 411 - with self.assertRaises(HTTPError) as ctx: + with pytest.raises(HTTPError) as ctx: self._send_webhook_msg(ip, port, 'dummy-payload', content_len='not-a-number') - self.assertEqual(ctx.exception.code, 403) + assert excinfo.value.code == 403 finally: - self.updater._stop_httpd() + updater.httpd.shutdown() thr.join() def _send_webhook_msg(self, @@ -871,7 +215,7 @@ class UpdaterTest(BaseTest, unittest.TestCase): content_len=-1, content_type='application/json', get_method=None): - headers = {'content-type': content_type,} + headers = {'content-type': content_type, } if not payload_str: content_len = None @@ -894,195 +238,44 @@ class UpdaterTest(BaseTest, unittest.TestCase): return urlopen(req) - def signalsender(self): - sleep(0.5) + def signal_sender(self): + sleep(0.2) os.kill(os.getpid(), signal.SIGTERM) - def test_idle(self): - if sys.platform == "win32": - return - self._setup_updater('Test6', messages=0) - self.updater.start_polling(poll_interval=0.01) - Thread(target=self.signalsender).start() - self.updater.idle() + @signalskip + def test_idle(self, updater): + updater.start_polling(0.01) + Thread(target=self.signal_sender).start() + updater.idle() # If we get this far, idle() ran through - sleep(1) - self.assertFalse(self.updater.running) + sleep(.5) + assert updater.running is False - def test_userSignal(self): - if sys.platform == "win32": - return - self._setup_updater('Test7', messages=0) + @signalskip + def test_user_signal(self, updater): + temp_var = {'a': 0} - tempVar = {'a': 0} + def user_signal_inc(signum, frame): + temp_var['a'] = 1 - def userSignalInc(signum, frame): - tempVar['a'] = 1 - - self.updater.user_sig_handler = userSignalInc - self.updater.start_polling(poll_interval=0.01) - Thread(target=self.signalsender).start() - self.updater.idle() + updater.user_sig_handler = user_signal_inc + updater.start_polling(0.01) + Thread(target=self.signal_sender).start() + updater.idle() # If we get this far, idle() ran through - sleep(1) - self.assertFalse(self.updater.running) - self.assertTrue(tempVar['a'] != 0) + sleep(.5) + assert updater.running is False + assert temp_var['a'] != 0 - def test_createBot(self): - self.updater = Updater('123:abcd') - self.assertIsNotNone(self.updater.bot) + def test_create_bot(self): + updater = Updater('123:abcd') + assert updater.bot is not None - def test_mutualExclusiveTokenBot(self): + def test_mutual_exclude_token_bot(self): bot = Bot('123:zyxw') - self.assertRaises(ValueError, Updater, token='123:abcd', bot=bot) + with pytest.raises(ValueError): + Updater(token='123:abcd', bot=bot) - def test_noTokenOrBot(self): - self.assertRaises(ValueError, Updater) - - def test_dispatcher_handler_flow_continue(self): - passed = [] - - def start1(b, u): - passed.append('start1') - raise DispatcherHandlerContinue - - def start2(b, u): - passed.append('start2') - - def start3(b, u): - passed.append('start3') - - def error(b, u, e): - passed.append('error') - passed.append(e) - - # noinspection PyTypeChecker - update = Update(1, message=Message(1, None, None, None, text='/start', bot=self._bot)) - - # Without raising Continue everything should work as before - passed = [] - dp = Dispatcher(self._bot, Queue()) - dp.add_handler(CommandHandler('start', start3)) - dp.add_handler(CommandHandler('start', start2)) - dp.add_error_handler(error) - dp.process_update(update) - self.assertEqual(passed, ['start3']) - - # If Continue raised next handler should be proceed. - passed = [] - dp = Dispatcher(self._bot, Queue()) - dp.add_handler(CommandHandler('start', start1)) - dp.add_handler(CommandHandler('start', start2)) - dp.process_update(update) - self.assertEqual(passed, ['start1', 'start2']) - - def test_dispatcher_handler_flow_stop(self): - passed = [] - - def start1(b, u): - passed.append('start1') - raise DispatcherHandlerStop - - def start2(b, u): - passed.append('start2') - - def start3(b, u): - passed.append('start3') - - def error(b, u, e): - passed.append('error') - passed.append(e) - - # noinspection PyTypeChecker - update = Update(1, message=Message(1, None, None, None, text='/start', bot=self._bot)) - - # Without raising Stop everything should work as before - passed = [] - dp = Dispatcher(self._bot, Queue()) - dp.add_handler(CommandHandler('start', start3), 1) - dp.add_handler(CommandHandler('start', start2), 2) - dp.add_error_handler(error) - dp.process_update(update) - self.assertEqual(passed, ['start3', 'start2']) - - # If Stop raised handlers in other groups should not be called. - passed = [] - dp = Dispatcher(self._bot, Queue()) - dp.add_handler(CommandHandler('start', start1), 1) - dp.add_handler(CommandHandler('start', start3), 1) - dp.add_handler(CommandHandler('start', start2), 2) - dp.process_update(update) - self.assertEqual(passed, ['start1']) - - -class MockBot(object): - def __init__(self, - text, - messages=1, - raise_error=False, - bootstrap_retries=None, - bootstrap_err=TelegramError('test'), - edited=False): - self.text = text - self.send_messages = messages - self.raise_error = raise_error - self.token = "TOKEN" - self.bootstrap_retries = bootstrap_retries - self.bootstrap_attempts = 0 - self.bootstrap_err = bootstrap_err - self.edited = edited - self.username = "MockBot" - - def mock_update(self, text): - message = Message(0, User(0, 'Testuser'), None, Chat(0, Chat.GROUP), bot=self) - message.text = text - update = Update(0) - - if self.edited: - update.edited_message = message - else: - update.message = message - - return update - - def set_webhook(self, url=None, certificate=None, allowed_updates=None): - if self.bootstrap_retries is None: - return - - if self.bootstrap_attempts < self.bootstrap_retries: - self.bootstrap_attempts += 1 - raise self.bootstrap_err - - def delete_webhook(self): - if self.bootstrap_retries is None: - return - - if self.bootstrap_attempts < self.bootstrap_retries: - self.bootstrap_attempts += 1 - raise self.bootstrap_err - - def get_updates(self, - offset=None, - limit=100, - timeout=0, - network_delay=None, - read_latency=2., - allowed_updates=None): - - if self.raise_error: - raise TelegramError('Test Error 2') - elif self.send_messages >= 2: - self.send_messages -= 2 - return self.mock_update(self.text), self.mock_update(self.text) - elif self.send_messages == 1: - self.send_messages -= 1 - return self.mock_update(self.text), - else: - return [] - - def create_references(self, d): - pass - - -if __name__ == '__main__': - unittest.main() + def test_no_token_or_bot(self): + with pytest.raises(ValueError): + Updater() diff --git a/tests/test_user.py b/tests/test_user.py index 0dff8477e..8bdcbb246 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -5,131 +5,110 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram User""" +import pytest -import unittest -import sys - -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import User, Update -class UserTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram User.""" +@pytest.fixture(scope='function') +def json_dict(): + return { + 'id': TestUser.id, + 'first_name': TestUser.first_name, + 'last_name': TestUser.last_name, + 'username': TestUser.username, + 'language_code': TestUser.language_code + } - def setUp(self): - self._id = 12173560 - self.first_name = "Leandro" - self.last_name = "S." - self.username = "leandrotoledo" - self.language_code = "pt-BR" - self.json_dict = { - 'id': self._id, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'username': self.username, - 'language_code': self.language_code - } +@pytest.fixture(scope='function') +def user(bot): + return User(TestUser.id, TestUser.first_name, last_name=TestUser.last_name, + username=TestUser.username, language_code=TestUser.language_code, bot=bot) - def test_user_de_json(self): - user = telegram.User.de_json(self.json_dict, self._bot) - self.assertEqual(user.id, self._id) - self.assertEqual(user.first_name, self.first_name) - self.assertEqual(user.last_name, self.last_name) - self.assertEqual(user.username, self.username) - self.assertEqual(user.language_code, self.language_code) +class TestUser(object): + id = 1 + first_name = 'first_name' + last_name = 'last_name' + username = 'username' + language_code = 'en_us' - self.assertEqual(user.name, '@leandrotoledo') + def test_de_json(self, json_dict, bot): + user = User.de_json(json_dict, bot) - def test_user_de_json_without_username(self): - json_dict = self.json_dict + assert user.id == self.id + assert user.first_name == self.first_name + assert user.last_name == self.last_name + assert user.username == self.username + assert user.language_code == self.language_code - del (json_dict['username']) + def test_de_json_without_username(self, json_dict, bot): + del json_dict['username'] - user = telegram.User.de_json(self.json_dict, self._bot) + user = User.de_json(json_dict, bot) - self.assertEqual(user.id, self._id) - self.assertEqual(user.first_name, self.first_name) - self.assertEqual(user.last_name, self.last_name) + assert user.id == self.id + assert user.first_name == self.first_name + assert user.last_name == self.last_name + assert user.username is None + assert user.language_code == self.language_code - self.assertEqual(user.name, '%s %s' % (self.first_name, self.last_name)) + def test_de_json_without_username_and_last_name(self, json_dict, bot): + del json_dict['username'] + del json_dict['last_name'] - def test_user_de_json_without_username_and_lastname(self): - json_dict = self.json_dict + user = User.de_json(json_dict, bot) - del (json_dict['username']) - del (json_dict['last_name']) + assert user.id == self.id + assert user.first_name == self.first_name + assert user.last_name is None + assert user.username is None + assert user.language_code == self.language_code - user = telegram.User.de_json(self.json_dict, self._bot) + def test_name(self, user): + assert user.name == '@username' + user.username = None + assert user.name == 'first_name last_name' + user.last_name = None + assert user.name == 'first_name' + user.username = self.username + assert user.name == '@username' - self.assertEqual(user.id, self._id) - self.assertEqual(user.first_name, self.first_name) + def test_get_profile_photos(self, monkeypatch, user): + def test(_, *args, **kwargs): + return args[0] == user.id - self.assertEqual(user.name, self.first_name) - - def test_user_to_json(self): - user = telegram.User.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_json(user.to_json())) - - def test_user_to_dict(self): - user = telegram.User.de_json(self.json_dict, self._bot) - - self.assertTrue(self.is_dict(user.to_dict())) - self.assertEqual(user['id'], self._id) - self.assertEqual(user['first_name'], self.first_name) - self.assertEqual(user['last_name'], self.last_name) - self.assertEqual(user['username'], self.username) - self.assertEqual(user['language_code'], self.language_code) - - @flaky(3, 1) - def test_get_profile_photos(self): - """Test for User.get_profile_photos""" - self.json_dict['id'] = self._chat_id - user = telegram.User.de_json(self.json_dict, self._bot) - user.bot = self._bot - - result = user.get_profile_photos() - - self.assertNotEquals(result, None) + monkeypatch.setattr('telegram.Bot.get_user_profile_photos', test) + assert user.get_profile_photos() def test_equality(self): - a = telegram.User(self._id, self.first_name, self.last_name) - b = telegram.User(self._id, self.first_name, self.last_name) - c = telegram.User(self._id, self.first_name) - d = telegram.User(0, self.first_name, self.last_name) - e = telegram.Update(self._id) + a = User(self.id, self.first_name, self.last_name) + b = User(self.id, self.first_name, self.last_name) + c = User(self.id, self.first_name) + d = User(0, self.first_name, self.last_name) + e = Update(self.id) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_venue.py b/tests/test_venue.py index 359720660..1d90856bb 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -5,102 +5,92 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Venue""" -import sys -import unittest +import pytest -from flaky import flaky - -sys.path.append('.') - -import telegram -from tests.base import BaseTest +from telegram import Location, Venue -class VenueTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Venue.""" +@pytest.fixture(scope='class') +def venue(): + return Venue(TestVenue.location, + TestVenue.title, + TestVenue.address, + foursquare_id=TestVenue.foursquare_id) - def setUp(self): - self.location = telegram.Location(longitude=-46.788279, latitude=-23.691288) - self.title = 'title' - self._address = '_address' - self.foursquare_id = 'foursquare id' - self.json_dict = { - 'location': self.location.to_dict(), - 'title': self.title, - 'address': self._address, - 'foursquare_id': self.foursquare_id +class TestVenue(object): + location = Location(longitude=-46.788279, latitude=-23.691288) + title = 'title' + address = 'address' + foursquare_id = 'foursquare id' + + def test_de_json(self, bot): + json_dict = { + 'location': TestVenue.location.to_dict(), + 'title': TestVenue.title, + 'address': TestVenue.address, + 'foursquare_id': TestVenue.foursquare_id } + venue = Venue.de_json(json_dict, bot) - def test_venue_de_json(self): - sticker = telegram.Venue.de_json(self.json_dict, self._bot) + assert venue.location == self.location + assert venue.title == self.title + assert venue.address == self.address + assert venue.foursquare_id == self.foursquare_id - self.assertTrue(isinstance(sticker.location, telegram.Location)) - self.assertEqual(sticker.title, self.title) - self.assertEqual(sticker.address, self._address) - self.assertEqual(sticker.foursquare_id, self.foursquare_id) + def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): + def test(_, url, data, **kwargs): + return (data['longitude'] == self.location.longitude + and data['latitude'] == self.location.latitude + and data['title'] == self.title + and data['address'] == self.address + and data['foursquare_id'] == self.foursquare_id) - def test_send_venue_with_venue(self): - ven = telegram.Venue.de_json(self.json_dict, self._bot) - message = self._bot.send_venue(chat_id=self._chat_id, venue=ven) - venue = message.venue + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_venue(chat_id, venue=venue) + assert message - self.assertEqual(venue, ven) + def test_send_venue_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match='Either venue or latitude, longitude, address and'): + bot.send_venue(chat_id=chat_id) - def test_venue_to_json(self): - sticker = telegram.Venue.de_json(self.json_dict, self._bot) + def test_to_dict(self, venue): + venue_dict = venue.to_dict() - self.assertTrue(self.is_json(sticker.to_json())) - - def test_sticker_to_dict(self): - sticker = telegram.Venue.de_json(self.json_dict, self._bot).to_dict() - - self.assertTrue(self.is_dict(sticker)) - self.assertDictEqual(self.json_dict, sticker) - - @flaky(3, 1) - def test_reply_venue(self): - """Test for Message.reply_venue""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_venue(self.location.latitude, self.location.longitude, self.title, - self._address) - - self.assertAlmostEqual(message.venue.location.latitude, self.location.latitude, 2) - self.assertAlmostEqual(message.venue.location.longitude, self.location.longitude, 2) + assert isinstance(venue_dict, dict) + assert venue_dict['location'] == venue.location.to_dict() + assert venue_dict['title'] == venue.title + assert venue_dict['address'] == venue.address + assert venue_dict['foursquare_id'] == venue.foursquare_id def test_equality(self): - a = telegram.Venue(telegram.Location(0, 0), "Title", "Address") - b = telegram.Venue(telegram.Location(0, 0), "Title", "Address") - c = telegram.Venue(telegram.Location(0, 0), "Title", "Not Address") - d = telegram.Venue(telegram.Location(0, 1), "Title", "Address") - d2 = telegram.Venue(telegram.Location(0, 0), "Not Title", "Address") + a = Venue(Location(0, 0), self.title, self.address) + b = Venue(Location(0, 0), self.title, self.address) + c = Venue(Location(0, 0), self.title, '') + d = Venue(Location(0, 1), self.title, self.address) + d2 = Venue(Location(0, 0), '', self.address) - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) + assert a == c + assert hash(a) == hash(c) - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) + assert a != d + assert hash(a) != hash(d) - self.assertNotEqual(a, d2) - self.assertNotEqual(hash(a), hash(d2)) - - -if __name__ == '__main__': - unittest.main() + assert a != d2 + assert hash(a) != hash(d2) diff --git a/tests/test_video.py b/tests/test_video.py index 936e58362..9eec87cb1 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -5,227 +5,200 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Video""" - import os -import unittest +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import Video, TelegramError, Voice, PhotoSize -class VideoTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Video.""" +@pytest.fixture(scope='function') +def video_file(): + f = open('tests/data/telegram.mp4', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(VideoTest, cls).setUpClass() - cls.caption = u'VideoTest - Caption' - cls.video_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.mp4' +@pytest.fixture(scope='class') +def video(bot, chat_id): + with open('tests/data/telegram.mp4', 'rb') as f: + return bot.send_video(chat_id, video=f, timeout=10).video - video_file = open('tests/data/telegram.mp4', 'rb') - video = cls._bot.send_video(cls._chat_id, video=video_file, timeout=10).video - cls.video = video +class TestVideo(object): + width = 360 + height = 640 + duration = 5 + file_size = 326534 + mime_type = 'video/mp4' + + caption = u'VideoTest - Caption' + video_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.mp4' + + def test_creation(self, video): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.video, telegram.Video) - assert isinstance(cls.video.file_id, str) - assert cls.video.file_id is not '' + assert isinstance(video, Video) + assert isinstance(video.file_id, str) + assert video.file_id is not '' - def setUp(self): - self.video_file = open('tests/data/telegram.mp4', 'rb') - self.json_dict = { - 'file_id': self.video.file_id, - 'width': self.video.width, - 'height': self.video.height, - 'duration': self.video.duration, - 'thumb': self.video.thumb.to_dict(), - 'mime_type': self.video.mime_type, - 'file_size': self.video.file_size - } + assert isinstance(video.thumb, PhotoSize) + assert isinstance(video.thumb.file_id, str) + assert video.thumb.file_id is not '' - def test_expected_values(self): - self.assertEqual(self.video.width, 360) - self.assertEqual(self.video.height, 640) - self.assertEqual(self.video.duration, 5) - self.assertEqual(self.video.file_size, 326534) - self.assertEqual(self.video.mime_type, 'video/mp4') + def test_expected_values(self, video): + assert video.width == self.width + assert video.height == self.height + assert video.duration == self.duration + assert video.file_size == self.file_size + assert video.mime_type == self.mime_type @flaky(3, 1) - @timeout(10) - def test_send_video_all_args(self): - message = self._bot.sendVideo( - self._chat_id, - self.video_file, - timeout=10, - duration=self.video.duration, - caption=self.caption, - disable_notification=False) + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, video_file, video): + message = bot.send_video(chat_id, video_file, duration=self.duration, + caption=self.caption, disable_notification=False, + width=video.width, height=video.height) - video = message.video + assert isinstance(message.video, Video) + assert isinstance(message.video.file_id, str) + assert message.video.file_id != '' + assert message.video.width == video.width + assert message.video.height == video.height + assert message.video.duration == video.duration + assert message.video.file_size == video.file_size - self.assertTrue(isinstance(video.file_id, str)) - self.assertNotEqual(video.file_id, None) - self.assertEqual(video.width, self.video.width) - self.assertEqual(video.height, self.video.height) - self.assertEqual(video.duration, self.video.duration) - self.assertEqual(video.thumb, self.video.thumb) - self.assertEqual(video.mime_type, self.video.mime_type) - self.assertEqual(video.file_size, self.video.file_size) + assert isinstance(message.video.thumb, PhotoSize) + assert isinstance(message.video.thumb.file_id, str) + assert message.video.thumb.file_id != '' + assert message.video.thumb.width == video.thumb.width + assert message.video.thumb.height == video.thumb.height + assert message.video.thumb.file_size == video.thumb.file_size - self.assertEqual(message.caption, self.caption) + assert message.caption == self.caption @flaky(3, 1) - @timeout(10) - def test_get_and_download_video(self): - new_file = self._bot.getFile(self.video.file_id) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, video): + new_file = bot.get_file(video.file_id) - self.assertEqual(new_file.file_size, self.video.file_size) - self.assertEqual(new_file.file_id, self.video.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == self.file_size + assert new_file.file_id == video.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram.mp4') - self.assertTrue(os.path.isfile('telegram.mp4')) + assert os.path.isfile('telegram.mp4') @flaky(3, 1) - @timeout(10) - def test_send_video_mp4_file_url(self): - message = self._bot.sendVideo( - chat_id=self._chat_id, - video=self.video_file_url, - timeout=10, - caption=self.caption) + @pytest.mark.timeout(10) + def test_send_mp4_file_url(self, bot, chat_id, video): + message = bot.send_video(chat_id, self.video_file_url, caption=self.caption) - video = message.video + assert isinstance(message.video, Video) + assert isinstance(message.video.file_id, str) + assert message.video.file_id != '' + assert message.video.width == video.width + assert message.video.height == video.height + assert message.video.duration == video.duration + assert message.video.file_size == video.file_size - self.assertIsInstance(video.file_id, str) - self.assertNotEqual(video.file_id, None) - self.assertEqual(video.height, self.video.height) - self.assertEqual(video.duration, self.video.duration) - self.assertEqual(video.mime_type, self.video.mime_type) - self.assertEqual(video.file_size, self.video.file_size) - self.assertEqual(message.caption, self.caption) - thumb = video.thumb - self.assertEqual(thumb.height, self.video.thumb.height) - self.assertEqual(thumb.width, self.video.thumb.width) - self.assertEqual(thumb.file_size, self.video.thumb.file_size) + assert isinstance(message.video.thumb, PhotoSize) + assert isinstance(message.video.thumb.file_id, str) + assert message.video.thumb.file_id != '' + assert message.video.thumb.width == video.thumb.width + assert message.video.thumb.height == video.thumb.height + assert message.video.thumb.file_size == video.thumb.file_size + + assert message.caption == self.caption @flaky(3, 1) - @timeout(10) - def test_send_video_resend(self): - message = self._bot.sendVideo( - chat_id=self._chat_id, - video=self.video.file_id, - timeout=10) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, video): + message = bot.send_video(chat_id, video.file_id) - video = message.video + assert message.video == video - self.assertEqual(video.file_id, self.video.file_id) - self.assertEqual(video.duration, self.video.duration) - self.assertEqual(video.thumb, self.video.thumb) - self.assertEqual(video.mime_type, self.video.mime_type) + def test_send_with_video(self, monkeypatch, bot, chat_id, video): + def test(_, url, data, **kwargs): + return data['video'] == video.file_id + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_video(chat_id, video=video) + assert message + + def test_de_json(self, bot): + json_dict = { + 'file_id': 'not a file id', + 'width': self.width, + 'height': self.height, + 'duration': self.duration, + 'mime_type': self.mime_type, + 'file_size': self.file_size + } + json_video = Video.de_json(json_dict, bot) + + assert json_video.file_id == 'not a file id' + assert json_video.width == self.width + assert json_video.height == self.height + assert json_video.duration == self.duration + assert json_video.mime_type == self.mime_type + assert json_video.file_size == self.file_size + + def test_to_dict(self, video): + video_dict = video.to_dict() + + assert isinstance(video_dict, dict) + assert video_dict['file_id'] == video.file_id + assert video_dict['width'] == video.width + assert video_dict['height'] == video.height + assert video_dict['duration'] == video.duration + assert video_dict['mime_type'] == video.mime_type + assert video_dict['file_size'] == video.file_size @flaky(3, 1) - @timeout(10) - def test_send_video_with_video(self): - message = self._bot.send_video(video=self.video, chat_id=self._chat_id) - video = message.video - - self.assertEqual(video, self.video) - - - def test_video_de_json(self): - video = telegram.Video.de_json(self.json_dict, self._bot) - - self.assertEqual(video, self.video) - - def test_video_to_json(self): - self.assertTrue(self.is_json(self.video.to_json())) - - def test_video_to_dict(self): - video = self.video.to_dict() - - self.assertTrue(self.is_dict(video)) - self.assertEqual(video['file_id'], self.video.file_id) - self.assertEqual(video['width'], self.video.width) - self.assertEqual(video['height'], self.video.height) - self.assertEqual(video['duration'], self.video.duration) - self.assertEqual(video['mime_type'], self.video.mime_type) - self.assertEqual(video['file_size'], self.video.file_size) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_video(chat_id, open(os.devnull, 'rb')) @flaky(3, 1) - @timeout(10) - def test_error_send_video_empty_file(self): - json_dict = self.json_dict + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_video(chat_id, '') - del (json_dict['file_id']) - json_dict['video'] = open(os.devnull, 'rb') + def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_video(chat_id=chat_id) - with self.assertRaises(telegram.TelegramError): - self._bot.sendVideo(chat_id=self._chat_id, timeout=10, **json_dict) + def test_equality(self, video): + a = Video(video.file_id, self.width, self.height, self.duration) + b = Video(video.file_id, self.width, self.height, self.duration) + c = Video(video.file_id, 0, 0, 0) + d = Video('', self.width, self.height, self.duration) + e = Voice(video.file_id, self.duration) - @flaky(3, 1) - @timeout(10) - def test_error_send_video_empty_file_id(self): - json_dict = self.json_dict + assert a == b + assert hash(a) == hash(b) + assert a is not b - del (json_dict['file_id']) - json_dict['video'] = '' + assert a == c + assert hash(a) == hash(c) - with self.assertRaises(telegram.TelegramError): - self._bot.sendVideo(chat_id=self._chat_id, timeout=10, **json_dict) + assert a != d + assert hash(a) != hash(d) - @flaky(3, 1) - @timeout(10) - def test_error_video_without_required_args(self): - # Obsolete: only required args are chat_id and video. Both tested above - self.assertEqual(True, True) - - @flaky(3, 1) - @timeout(10) - def test_reply_video(self): - """Test for Message.reply_video""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_video(self.video_file) - - self.assertNotEqual(message.video.file_id, None) - - def test_equality(self): - a = telegram.Video(self.video.file_id, self.video.width, self.video.height, self.video.duration) - b = telegram.Video(self.video.file_id, self.video.width, self.video.height, self.video.duration) - c = telegram.Video(self.video.file_id, 0, 0, 0) - d = telegram.Video("", self.video.width, self.video.height, self.video.duration) - e = telegram.Voice(self.video.file_id, self.video.duration) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_videonote.py b/tests/test_videonote.py index bd9a89609..3e386642f 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -5,188 +5,163 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram VideoNote""" import os -import unittest +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import VideoNote, TelegramError, Voice, PhotoSize -class VideoNoteTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram VideoNote.""" +@pytest.fixture(scope='function') +def video_note_file(): + f = open('tests/data/telegram2.mp4', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(VideoNoteTest, cls).setUpClass() - videonote_file = open('tests/data/telegram2.mp4', 'rb') - video_note = cls._bot.send_video_note(cls._chat_id, video_note=videonote_file, timeout=10).video_note +@pytest.fixture(scope='class') +def video_note(bot, chat_id): + with open('tests/data/telegram2.mp4', 'rb') as f: + return bot.send_video_note(chat_id, video_note=f, timeout=10).video_note - cls.videonote = video_note +class TestVideoNote(object): + length = 240 + duration = 3 + file_size = 132084 + + caption = u'VideoNoteTest - Caption' + + def test_creation(self, video_note): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.videonote, telegram.VideoNote) - assert isinstance(cls.videonote.file_id, str) - assert cls.videonote.file_id is not '' + assert isinstance(video_note, VideoNote) + assert isinstance(video_note.file_id, str) + assert video_note.file_id is not '' - def setUp(self): - self.videonote_file = open('tests/data/telegram2.mp4', 'rb') - self.json_dict = { - 'file_id': self.videonote.file_id, - 'duration': self.videonote.duration, - 'length': self.videonote.length, - 'thumb': self.videonote.thumb.to_dict(), - 'file_size': self.videonote.file_size - } + assert isinstance(video_note.thumb, PhotoSize) + assert isinstance(video_note.thumb.file_id, str) + assert video_note.thumb.file_id is not '' + + def test_expected_values(self, video_note): + assert video_note.length == self.length + assert video_note.duration == self.duration + assert video_note.file_size == self.file_size @flaky(3, 1) - @timeout(10) - def test_expected_values(self): - self.assertEqual(self.videonote.duration, 3) - self.assertEqual(self.videonote.length, 240) - self.assertEqual(self.videonote.file_size, 132084) + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, video_note_file, video_note): + message = bot.send_video_note(chat_id, video_note_file, duration=self.duration, + length=self.length, disable_notification=False) + + assert isinstance(message.video_note, VideoNote) + assert isinstance(message.video_note.file_id, str) + assert message.video_note.file_id != '' + assert message.video_note.length == video_note.length + assert message.video_note.duration == video_note.duration + assert message.video_note.file_size == video_note.file_size + + assert isinstance(message.video_note.thumb, PhotoSize) + assert isinstance(message.video_note.thumb.file_id, str) + assert message.video_note.thumb.file_id != '' + assert message.video_note.thumb.width == video_note.thumb.width + assert message.video_note.thumb.height == video_note.thumb.height + assert message.video_note.thumb.file_size == video_note.thumb.file_size @flaky(3, 1) - @timeout(10) - def test_send_videonote_all_args(self): - message = self._bot.sendVideoNote( - self._chat_id, - self.videonote_file, - timeout=10, - duration=self.videonote.duration, - length=self.videonote.length, - disable_notification=False) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, video_note): + new_file = bot.get_file(video_note.file_id) - videonote = message.video_note - - self.assertIsInstance(videonote.file_id, str) - self.assertNotEqual(videonote.file_id, None) - self.assertEqual(videonote.length, self.videonote.length) - self.assertEqual(videonote.duration, self.videonote.duration) - self.assertEqual(videonote.thumb, self.videonote.thumb) - self.assertEqual(videonote.file_size, self.videonote.file_size) - - @flaky(3, 1) - @timeout(10) - def test_get_and_download_videonote(self): - new_file = self._bot.getFile(self.videonote.file_id) - - self.assertEqual(new_file.file_size, self.videonote.file_size) - self.assertEqual(new_file.file_id, self.videonote.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == self.file_size + assert new_file.file_id == video_note.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram2.mp4') - self.assertTrue(os.path.isfile('telegram2.mp4')) + assert os.path.isfile('telegram2.mp4') @flaky(3, 1) - @timeout(10) - def test_send_videonote_resend(self): - message = self._bot.sendVideoNote( - chat_id=self._chat_id, - video_note=self.videonote.file_id, - timeout=10 - ) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, video_note): + message = bot.send_video_note(chat_id, video_note.file_id) - videonote = message.video_note + assert message.video_note == video_note - self.assertEqual(videonote.file_id, self.videonote.file_id) - self.assertEqual(videonote.length, self.videonote.length) - self.assertEqual(videonote.duration, self.videonote.duration) - self.assertEqual(videonote.thumb, self.videonote.thumb) - self.assertEqual(videonote.file_size, self.videonote.file_size) + def test_send_with_video_note(self, monkeypatch, bot, chat_id, video_note): + def test(_, url, data, **kwargs): + return data['video_note'] == video_note.file_id + + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_video_note(chat_id, video_note=video_note) + assert message + + def test_de_json(self, bot): + json_dict = { + 'file_id': 'not a file id', + 'length': self.length, + 'duration': self.duration, + 'file_size': self.file_size + } + json_video_note = VideoNote.de_json(json_dict, bot) + + assert json_video_note.file_id == 'not a file id' + assert json_video_note.length == self.length + assert json_video_note.duration == self.duration + assert json_video_note.file_size == self.file_size + + def test_to_dict(self, video_note): + video_note_dict = video_note.to_dict() + + assert isinstance(video_note_dict, dict) + assert video_note_dict['file_id'] == video_note.file_id + assert video_note_dict['length'] == video_note.length + assert video_note_dict['duration'] == video_note.duration + assert video_note_dict['file_size'] == video_note.file_size @flaky(3, 1) - @timeout(10) - def test_send_video_note_with_video_note(self): - message = self._bot.send_video_note(video_note=self.videonote, chat_id=self._chat_id) - video_note = message.video_note - - self.assertEqual(video_note, self.videonote) - - def test_videonote_de_json(self): - videonote = telegram.VideoNote.de_json(self.json_dict, self._bot) - - self.assertEqual(videonote, self.videonote) - - def test_videonote_to_json(self): - self.assertTrue(self.is_json(self.videonote.to_json())) - - def test_videonote_to_dict(self): - videonote = self.videonote.to_dict() - - self.assertTrue(self.is_dict(videonote)) - self.assertEqual(videonote['file_id'], self.videonote.file_id) - self.assertEqual(videonote['duration'], self.videonote.duration) - self.assertEqual(videonote['length'], self.videonote.length) - self.assertEqual(videonote['file_size'], self.videonote.file_size) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_video_note(chat_id, open(os.devnull, 'rb')) @flaky(3, 1) - @timeout(10) - def test_error_send_videonote_empty_file(self): - json_dict = self.json_dict + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.send_video_note(chat_id, '') - del (json_dict['file_id']) - json_dict['video_note'] = open(os.devnull, 'rb') + def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.send_video_note(chat_id=chat_id) - with self.assertRaises(telegram.TelegramError): - self._bot.sendVideoNote(chat_id=self._chat_id, timeout=10, **json_dict) + def test_equality(self, video_note): + a = VideoNote(video_note.file_id, self.length, self.duration) + b = VideoNote(video_note.file_id, self.length, self.duration) + c = VideoNote(video_note.file_id, 0, 0) + d = VideoNote('', self.length, self.duration) + e = Voice(video_note.file_id, self.duration) - @flaky(3, 1) - @timeout(10) - def test_error_send_videonote_empty_file_id(self): - json_dict = self.json_dict + assert a == b + assert hash(a) == hash(b) + assert a is not b - del (json_dict['file_id']) - json_dict['video_note'] = '' + assert a == c + assert hash(a) == hash(c) - with self.assertRaises(telegram.TelegramError): - self._bot.sendVideoNote(chat_id=self._chat_id, timeout=10, **json_dict) + assert a != d + assert hash(a) != hash(d) - @flaky(3, 1) - @timeout(10) - def test_reply_videonote(self): - """Test for Message.reply_videonote""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_video_note(self.videonote_file) - - self.assertNotEqual(message.video_note.file_id, None) - - def test_equality(self): - a = telegram.VideoNote(self.videonote.file_id, self.videonote.length, self.videonote.duration) - b = telegram.VideoNote(self.videonote.file_id, self.videonote.length, self.videonote.duration) - c = telegram.VideoNote(self.videonote.file_id, 0, 0, 0) - d = telegram.VideoNote("", self.videonote.length, self.videonote.duration) - e = telegram.Voice(self.videonote.file_id, self.videonote.duration) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/test_voice.py b/tests/test_voice.py index 6308cb712..e12106eb5 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -5,235 +5,167 @@ # 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 +# 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 General Public License for more details. +# GNU Lesser Public License for more details. # -# You should have received a copy of the GNU General Public License +# 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 an object that represents Tests for Telegram Voice""" - import os -import unittest +import pytest from flaky import flaky -import telegram -from tests.base import BaseTest, timeout +from telegram import Audio, Voice, TelegramError -class VoiceTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram Voice.""" +@pytest.fixture(scope='function') +def voice_file(): + f = open('tests/data/telegram.ogg', 'rb') + yield f + f.close() - @classmethod - def setUpClass(cls): - super(VoiceTest, cls).setUpClass() - cls.voice_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.ogg' - cls.caption = u"Test voice" +@pytest.fixture(scope='class') +def voice(bot, chat_id): + with open('tests/data/telegram.ogg', 'rb') as f: + return bot.send_voice(chat_id, voice=f, timeout=10).voice - voice_file = open('tests/data/telegram.ogg', 'rb') - voice = cls._bot.send_voice(cls._chat_id, voice=voice_file).voice - cls.voice = voice +class TestVoice(object): + duration = 3 + mime_type = 'audio/ogg' + file_size = 9199 + caption = u'Test voice' + voice_file_url = 'https://python-telegram-bot.org/static/testfiles/telegram.ogg' + + def test_creation(self, voice): # Make sure file has been uploaded. - # Simple assertions PY2 Only - assert isinstance(cls.voice, telegram.Voice) - assert isinstance(cls.voice.file_id, str) - assert cls.voice.file_id is not '' + assert isinstance(voice, Voice) + assert isinstance(voice.file_id, str) + assert voice.file_id != '' - def setUp(self): - self.voice_file = open('tests/data/telegram.ogg', 'rb') - - self.json_dict = { - 'file_id': self.voice.file_id, - 'duration': self.voice.duration, - 'caption': self.caption, - 'mime_type': self.voice.mime_type, - 'file_size': self.voice.file_size - } + def test_expected_values(self, voice): + assert voice.duration == self.duration + assert voice.mime_type == self.mime_type + assert voice.file_size == self.file_size @flaky(3, 1) - @timeout(10) - def test_expected_values(self): - self.assertEqual(self.voice.duration, 3) - self.assertEqual(self.voice.mime_type, 'audio/ogg') - self.assertEqual(self.voice.file_size, 9199) + @pytest.mark.timeout(10) + def test_send_all_args(self, bot, chat_id, voice_file, voice): + message = bot.send_voice(chat_id, voice_file, duration=self.duration, + caption=self.caption, disable_notification=False) + + assert isinstance(message.voice, Voice) + assert isinstance(message.voice.file_id, str) + assert message.voice.file_id != '' + assert message.voice.duration == voice.duration + assert message.voice.mime_type == voice.mime_type + assert message.voice.file_size == voice.file_size + assert message.caption == self.caption @flaky(3, 1) - @timeout(10) - def test_send_voice_all_args(self): - message = self._bot.sendVoice( - self._chat_id, - self.voice_file, - duration=self.voice.duration, - caption=self.caption, - mime_type=self.voice.mime_type, - file_size=self.voice.file_size, - disable_notification=False) + @pytest.mark.timeout(10) + def test_get_and_download(self, bot, voice): + new_file = bot.get_file(voice.file_id) - self.assertEqual(message.caption, self.caption) - - voice = message.voice - - self.assertIsInstance(voice.file_id, str) - self.assertNotEqual(voice.file_id, '') - self.assertEqual(voice.duration, self.voice.duration) - self.assertEqual(voice.mime_type, self.voice.mime_type) - self.assertEqual(voice.file_size, self.voice.file_size) - - @flaky(3, 1) - @timeout(10) - def test_get_and_download_voice(self): - new_file = self._bot.getFile(self.voice.file_id) - - self.assertEqual(new_file.file_size, self.voice.file_size) - self.assertEqual(new_file.file_id, self.voice.file_id) - self.assertTrue(new_file.file_path.startswith('https://')) + assert new_file.file_size == voice.file_size + assert new_file.file_id == voice.file_id + assert new_file.file_path.startswith('https://') new_file.download('telegram.ogg') - self.assertTrue(os.path.isfile('telegram.ogg')) + assert os.path.isfile('telegram.ogg') @flaky(3, 1) - @timeout(10) - def test_send_voice_ogg_url_file(self): - message = self._bot.sendVoice( - chat_id=self._chat_id, voice=self.voice_file_url, duration=self.voice.duration) + @pytest.mark.timeout(10) + def test_send_ogg_url_file(self, bot, chat_id, voice): + message = bot.sendVoice(chat_id, self.voice_file_url, duration=self.duration) - voice = message.voice - - self.assertIsInstance(voice.file_id, str) - self.assertNotEqual(voice.file_id, '') - self.assertEqual(voice.duration, self.voice.duration) - self.assertEqual(voice.mime_type, self.voice.mime_type) - self.assertEqual(voice.file_size, self.voice.file_size) + assert isinstance(message.voice, Voice) + assert isinstance(message.voice.file_id, str) + assert message.voice.file_id != '' + assert message.voice.duration == voice.duration + assert message.voice.mime_type == voice.mime_type + assert message.voice.file_size == voice.file_size @flaky(3, 1) - @timeout(10) - def test_send_voice_ogg_url_file_with_caption(self): - message = self._bot.sendVoice( - chat_id=self._chat_id, - voice=self.voice_file_url, - duration=self.voice.duration, - caption=self.caption) + @pytest.mark.timeout(10) + def test_resend(self, bot, chat_id, voice): + message = bot.sendVoice(chat_id, voice.file_id) - self.assertEqual(message.caption, self.caption) + assert message.voice == voice - voice = message.voice + def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): + def test(_, url, data, **kwargs): + return data['voice'] == voice.file_id - self.assertIsInstance(voice.file_id, str) - self.assertNotEqual(voice.file_id, '') - self.assertEqual(voice.duration, self.voice.duration) - self.assertEqual(voice.mime_type, self.voice.mime_type) - self.assertEqual(voice.file_size, self.voice.file_size) + monkeypatch.setattr('telegram.utils.request.Request.post', test) + message = bot.send_voice(chat_id, voice=voice) + assert message + + def test_de_json(self, bot): + json_dict = { + 'file_id': 'not a file id', + 'duration': self.duration, + 'caption': self.caption, + 'mime_type': self.mime_type, + 'file_size': self.file_size + } + json_voice = Voice.de_json(json_dict, bot) + + assert json_voice.file_id == 'not a file id' + assert json_voice.duration == self.duration + assert json_voice.mime_type == self.mime_type + assert json_voice.file_size == self.file_size + + def test_to_dict(self, voice): + voice_dict = voice.to_dict() + + assert isinstance(voice_dict, dict) + assert voice_dict['file_id'] == voice.file_id + assert voice_dict['duration'] == voice.duration + assert voice_dict['mime_type'] == voice.mime_type + assert voice_dict['file_size'] == voice.file_size @flaky(3, 1) - @timeout(10) - def test_send_voice_resend(self): - message = self._bot.sendVoice( - chat_id=self._chat_id, - voice=self.voice.file_id) - - voice = message.voice - - self.assertEqual(voice.file_id, self.voice.file_id) - self.assertEqual(voice.duration, self.voice.duration) - self.assertEqual(voice.mime_type, self.voice.mime_type) + @pytest.mark.timeout(10) + def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.sendVoice(chat_id, open(os.devnull, 'rb')) @flaky(3, 1) - @timeout(10) - def test_send_voice_with_voice(self): - message = self._bot.send_voice(voice=self.voice, chat_id=self._chat_id) - voice = message.voice + @pytest.mark.timeout(10) + def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + bot.sendVoice(chat_id, '') - self.assertEqual(voice, self.voice) + def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + bot.sendVoice(chat_id) + def test_equality(self, voice): + a = Voice(voice.file_id, self.duration) + b = Voice(voice.file_id, self.duration) + c = Voice(voice.file_id, 0) + d = Voice('', self.duration) + e = Audio(voice.file_id, self.duration) - def test_voice_de_json(self): - voice = telegram.Voice.de_json(self.json_dict, self._bot) + assert a == b + assert hash(a) == hash(b) + assert a is not b - self.assertEqual(voice, self.voice) + assert a == c + assert hash(a) == hash(c) - def test_voice_to_json(self): - self.assertTrue(self.is_json(self.voice.to_json())) + assert a != d + assert hash(a) != hash(d) - def test_voice_to_dict(self): - voice = self.voice.to_dict() - - self.assertTrue(self.is_dict(voice)) - self.assertEqual(voice['file_id'], self.voice.file_id) - self.assertEqual(voice['duration'], self.voice.duration) - self.assertEqual(voice['mime_type'], self.voice.mime_type) - self.assertEqual(voice['file_size'], self.voice.file_size) - - @flaky(3, 1) - @timeout(10) - def test_error_send_voice_empty_file(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['voice'] = open(os.devnull, 'rb') - - with self.assertRaises(telegram.TelegramError): - self._bot.sendVoice(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_send_voice_empty_file_id(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - json_dict['voice'] = '' - - with self.assertRaises(telegram.TelegramError): - self._bot.sendVoice(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_error_voice_without_required_args(self): - json_dict = self.json_dict - - del (json_dict['file_id']) - - with self.assertRaises(TypeError): - self._bot.sendVoice(chat_id=self._chat_id, **json_dict) - - @flaky(3, 1) - @timeout(10) - def test_reply_voice(self): - """Test for Message.reply_voice""" - message = self._bot.sendMessage(self._chat_id, '.') - message = message.reply_voice(self.voice_file) - - self.assertNotEqual(message.voice.file_id, '') - - def test_equality(self): - a = telegram.Voice(self.voice.file_id, self.voice.duration) - b = telegram.Voice(self.voice.file_id, self.voice.duration) - c = telegram.Voice(self.voice.file_id, 0) - d = telegram.Voice("", self.voice.duration) - e = telegram.Audio(self.voice.file_id, self.voice.duration) - - self.assertEqual(a, b) - self.assertEqual(hash(a), hash(b)) - self.assertIsNot(a, b) - - self.assertEqual(a, c) - self.assertEqual(hash(a), hash(c)) - - self.assertNotEqual(a, d) - self.assertNotEqual(hash(a), hash(d)) - - self.assertNotEqual(a, e) - self.assertNotEqual(hash(a), hash(e)) - - -if __name__ == '__main__': - unittest.main() + assert a != e + assert hash(a) != hash(e) diff --git a/tests/travis_fold.py b/tests/travis_fold.py new file mode 100644 index 000000000..54fb1f6df --- /dev/null +++ b/tests/travis_fold.py @@ -0,0 +1,78 @@ +import time +from collections import defaultdict + +import _pytest.config +import pytest + +fold_plugins = {'_cov': 'Coverage report', 'flaky': 'Flaky report'} + + +def terminal_summary_wrapper(original, plugin_name): + text = fold_plugins[plugin_name] + + def pytest_terminal_summary(terminalreporter): + terminalreporter.write('travis_fold:start:plugin.{}\n{}\n'.format(plugin_name, text)) + original(terminalreporter) + terminalreporter.write('travis_fold:end:plugin.{}\n'.format(plugin_name)) + + return pytest_terminal_summary + + +@pytest.mark.trylast +def pytest_configure(config): + for hookimpl in config.pluginmanager.hook.pytest_terminal_summary._nonwrappers: + if hookimpl.plugin_name in fold_plugins.keys(): + hookimpl.function = terminal_summary_wrapper(hookimpl.function, + hookimpl.plugin_name) + + +terminal = None +previous_name = None +failed = set() +durations = defaultdict(int) + + +def _get_name(location): + return '{}::{}'.format(location[0], location[2].split('.')[0].split('[')[0]) + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_makereport(item, call): + outcome = yield + rep = outcome.get_result() + name = _get_name(item.location) + durations[name] += rep.duration + if rep.failed: + global failed + failed.add(name) + + +@pytest.hookimpl(hookwrapper=True, tryfirst=True) +def pytest_runtest_protocol(item, nextitem): + # This is naughty but pytests' own plugins does something similar too, so who cares + global terminal + if terminal is None: + terminal = _pytest.config.create_terminal_writer(item.config) + + global previous_name + + name = _get_name(item.location) + + if previous_name is None or previous_name != name: + previous_name = name + terminal.write('\ntravis_fold:start:{}\r'.format(name.split('::')[1])) + terminal.write('travis_time:start:{}time\r'.format(name.split('::')[1])) + terminal.write(name) + + yield + + if nextitem is None or _get_name(nextitem.location) != name: + global failed + if name in failed: + terminal.write('') + else: + terminal.write('\n\ntravis_fold:end:{}'.format(name.split('::')[1])) + terminal.write('\rtravis_time:end:{}time:' + 'duration={}'.format(name.split('::')[1], + int(durations[name] * 1E9))) + time.sleep(0.001) # Tiny sleep so travis hopefully doesn't mangle the log diff --git a/travis.py b/travis.py deleted file mode 100644 index 509bb41f5..000000000 --- a/travis.py +++ /dev/null @@ -1,93 +0,0 @@ -from __future__ import print_function - -import subprocess -import sys -from platform import python_implementation -import inspect - -import nose -from nose.config import Config -from nose.plugins import Plugin, DefaultPluginManager -from nose.plugins.cover import Coverage - -import tests - - -class CustomCoverage(Coverage): - enabled = True - name = 'coverage' - score = 201 # One higher than original package - - def report(self, stream): - fold('coverage', 'Coverage report', stream=stream) - super(CustomCoverage, self).report(stream) - fold('coverage', stream=stream) - - -class FoldPlugin(Plugin): - enabled = True - name = 'travis-fold' - score = 100 - - def setOutputStream(self, stream): - self.stream = stream - - def startContext(self, context): - if inspect.ismodule(context) and context != tests: - fold(context.__name__, context.__name__, stream=self.stream) - - def stopContext(self, context): - if inspect.ismodule(context) and context != tests: - fold(context.__name__, stream=self.stream) - -folds = set() - - -def fold(foldname, comment=None, stream=sys.stdout): - if foldname in folds: - folds.remove(foldname) - print('\ntravis_fold:end:{}'.format(foldname), file=stream, end='') - else: - folds.add(foldname) - print('travis_fold:start:{}'.format(foldname), file=stream, end='') - - if comment: - print('\n{}'.format(comment), file=stream) - else: - print('', file=stream) - - -def main(): - print('Starting...') - fold('tests', 'Running tests...') - config = Config(verbosity=2, plugins=DefaultPluginManager(), env={'NOSE_REDNOSE': '1'}) - tests = nose.run(argv=['--with-flaky', '--no-flaky-report', - '--with-coverage', '--cover-package=telegram/', - '--with-travis-fold', - 'tests'], - addplugins=[FoldPlugin(), CustomCoverage()], - config=config) - print('\n' * 2) - if tests: - fold('tests') - - # Only run pre-commit hooks once - pre_commit = True - if sys.version_info[:2] == (3, 6) and python_implementation() == 'CPython': - fold('pre-commit', 'Running pre-commits') - # TODO: Only run pre-commit hooks on changed files - # Using something like git diff-tree and $TRAVIS_COMMIT_RANGE - pre_commit = subprocess.call(['pre-commit', 'run', '--all-files']) == 0 - if pre_commit: - fold('pre-commit') - - fold('bdist_dumb', 'Testing build...') - # run_setup('setup.py', ['bdist_dumb']) # Makes us unable to fetch exit code - bdist_dumb = subprocess.call(['python', 'setup.py', 'bdist_dumb']) == 0 - if bdist_dumb: - fold('bdist_dumb') - - sys.exit(0 if all((tests, pre_commit, bdist_dumb)) else 1) - -if __name__ == '__main__': - main()