From fc5aea4307b6d48ea922cc834dc4c7621b2f0730 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 8 Dec 2022 18:54:08 +0530 Subject: [PATCH 01/77] Split tests based on whether they make a request This commit additionally changes: - The scope of the fixtures to module - Class variables are moved into a namespace class called as Space - Auto addition of flaky and no_req marker (in conftest.py) - Caching of default and tz bots (in conftest.py) Apart from this, no tests were added/deleted/modified in any way. --- setup.cfg | 5 +- tests/conftest.py | 58 +- tests/test_animation.py | 261 +- tests/test_audio.py | 284 +- tests/test_bot.py | 2767 ++++++++--------- tests/test_botcommand.py | 4 +- tests/test_botcommandscope.py | 10 +- tests/test_callbackquery.py | 54 +- tests/test_chat.py | 128 +- tests/test_chatadministratorrights.py | 4 +- tests/test_chatinvitelink.py | 87 +- tests/test_chatjoinrequest.py | 42 +- tests/test_chatlocation.py | 22 +- tests/test_chatmember.py | 2 +- tests/test_chatmemberupdated.py | 22 +- tests/test_chatpermissions.py | 42 +- tests/test_chatphoto.py | 142 +- tests/test_choseninlineresult.py | 32 +- tests/test_constants.py | 42 +- tests/test_contact.py | 124 +- tests/test_dice.py | 10 +- tests/test_document.py | 325 +- tests/test_encryptedcredentials.py | 28 +- tests/test_encryptedpassportelement.py | 46 +- tests/test_file.py | 197 +- tests/test_forcereply.py | 29 +- tests/test_forum.py | 19 +- tests/test_game.py | 54 +- tests/test_gamehighscore.py | 22 +- tests/test_inlinekeyboardbutton.py | 74 +- tests/test_inlinekeyboardmarkup.py | 33 +- tests/test_inlinequery.py | 44 +- tests/test_inlinequeryresultarticle.py | 58 +- tests/test_inlinequeryresultaudio.py | 60 +- tests/test_inlinequeryresultcachedaudio.py | 48 +- tests/test_inlinequeryresultcacheddocument.py | 58 +- tests/test_inlinequeryresultcachedgif.py | 54 +- tests/test_inlinequeryresultcachedmpeg4gif.py | 52 +- tests/test_inlinequeryresultcachedphoto.py | 56 +- tests/test_inlinequeryresultcachedsticker.py | 34 +- tests/test_inlinequeryresultcachedvideo.py | 56 +- tests/test_inlinequeryresultcachedvoice.py | 52 +- tests/test_inlinequeryresultcontact.py | 54 +- tests/test_inlinequeryresultdocument.py | 74 +- tests/test_inlinequeryresultgame.py | 30 +- tests/test_inlinequeryresultgif.py | 72 +- tests/test_inlinequeryresultlocation.py | 70 +- tests/test_inlinequeryresultmpeg4gif.py | 72 +- tests/test_inlinequeryresultphoto.py | 68 +- tests/test_inlinequeryresultvenue.py | 74 +- tests/test_inlinequeryresultvideo.py | 78 +- tests/test_inlinequeryresultvoice.py | 60 +- tests/test_inputcontactmessagecontent.py | 18 +- tests/test_inputfile.py | 6 +- tests/test_inputinvoicemessagecontent.py | 264 +- tests/test_inputlocationmessagecontent.py | 32 +- tests/test_inputmedia.py | 427 +-- tests/test_inputtextmessagecontent.py | 24 +- tests/test_inputvenuemessagecontent.py | 38 +- tests/test_invoice.py | 399 +-- tests/test_keyboardbutton.py | 46 +- tests/test_keyboardbuttonpolltype.py | 10 +- tests/test_labeledprice.py | 12 +- tests/test_location.py | 219 +- tests/test_loginurl.py | 32 +- tests/test_menubutton.py | 30 +- tests/test_message.py | 148 +- tests/test_messageautodeletetimerchanged.py | 2 +- tests/test_messageentity.py | 14 +- tests/test_messageid.py | 6 +- tests/test_no_passport.py | 2 +- tests/test_orderinfo.py | 30 +- tests/test_passport.py | 68 +- tests/test_passportelementerrordatafield.py | 38 +- tests/test_passportelementerrorfile.py | 32 +- tests/test_passportelementerrorfiles.py | 32 +- tests/test_passportelementerrorfrontside.py | 32 +- tests/test_passportelementerrorreverseside.py | 32 +- tests/test_passportelementerrorselfie.py | 32 +- ...est_passportelementerrortranslationfile.py | 32 +- ...st_passportelementerrortranslationfiles.py | 32 +- tests/test_passportelementerrorunspecified.py | 32 +- tests/test_passportfile.py | 28 +- tests/test_photo.py | 267 +- tests/test_poll.py | 130 +- tests/test_precheckoutquery.py | 56 +- tests/test_proximityalerttriggered.py | 28 +- tests/test_replykeyboardmarkup.py | 52 +- tests/test_replykeyboardremove.py | 28 +- tests/test_request.py | 7 +- tests/test_requestdata.py | 8 +- tests/test_requestparameter.py | 2 +- tests/test_sentwebappmessage.py | 20 +- tests/test_shippingaddress.py | 88 +- tests/test_shippingoption.py | 26 +- tests/test_shippingquery.py | 43 +- tests/test_sticker.py | 701 ++--- tests/test_successfulpayment.py | 76 +- tests/test_update.py | 20 +- tests/test_user.py | 122 +- tests/test_userprofilephotos.py | 20 +- tests/test_venue.py | 158 +- tests/test_video.py | 281 +- tests/test_videochat.py | 12 +- tests/test_videonote.py | 205 +- tests/test_voice.py | 237 +- tests/test_webappdata.py | 25 +- tests/test_webappinfo.py | 18 +- tests/test_webhookinfo.py | 90 +- 109 files changed, 5549 insertions(+), 5513 deletions(-) diff --git a/setup.cfg b/setup.cfg index a0e0eb8561b..60c2cf57478 100644 --- a/setup.cfg +++ b/setup.cfg @@ -36,7 +36,10 @@ filterwarnings = ; Unfortunately due to https://github.com/pytest-dev/pytest/issues/8343 we can't have this here ; and instead do a trick directly in tests/conftest.py ; ignore::telegram.utils.deprecate.TelegramDeprecationWarning -markers = dev: If you want to test a specific test, use this +markers = + dev: If you want to test a specific test, use this + no_req + req asyncio_mode = auto [coverage:run] diff --git a/tests/conftest.py b/tests/conftest.py index 06e12e98c4e..168c0d529b9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,7 +22,7 @@ import re import sys from pathlib import Path -from typing import Callable, Optional +from typing import Callable, List, Optional import pytest from httpx import AsyncClient, Response @@ -52,12 +52,28 @@ # This is here instead of in setup.cfg due to https://github.com/pytest-dev/pytest/issues/8343 -def pytest_runtestloop(session): +def pytest_runtestloop(session: pytest.Session): session.add_marker( pytest.mark.filterwarnings("ignore::telegram.warnings.PTBDeprecationWarning") ) +def pytest_collection_modifyitems(items: List[pytest.Item]): + """Here we add a flaky marker to all request making tests and the no_req marker to the rest.""" + for item in items: + parent = item.parent + if parent is None: + return + if ( + "NoReq" not in parent.name + and parent.name.endswith("Req") + and not parent.get_closest_marker(name="flaky") + ): + parent.add_marker(pytest.mark.flaky(3, 1)) + elif parent.name.endswith("NoReq") and not parent.get_closest_marker(name="no_req"): + parent.add_marker(pytest.mark.no_req) + + GITHUB_ACTION = os.getenv("GITHUB_ACTION", False) if GITHUB_ACTION: @@ -148,6 +164,7 @@ class DictApplication(Application): async def bot(bot_info): """Makes an ExtBot instance with the given bot_info""" async with make_bot(bot_info) as _bot: + print("making new bot") yield _bot @@ -170,20 +187,35 @@ async def raw_bot(bot_info): yield _bot -@pytest.fixture(scope="function") +default_bots = {} + + +@pytest.fixture(scope="session") async def default_bot(request, bot_info): param = request.param if hasattr(request, "param") else {} + defaults = Defaults(**param) - default_bot = make_bot(bot_info, defaults=Defaults(**param)) - async with default_bot: - yield default_bot + # If the bot is already created, return it. Else make a new one. + default_bot = default_bots.get(defaults, None) + if default_bot is None: + default_bot = make_bot(bot_info, defaults=defaults) + await default_bot.initialize() + default_bots[defaults] = default_bot # Defaults object is hashable + return default_bot -@pytest.fixture(scope="function") +tz_bots = {} + + +@pytest.fixture(scope="session") async def tz_bot(timezone, bot_info): - default_bot = make_bot(bot_info, defaults=Defaults(tzinfo=timezone)) - async with default_bot: - yield default_bot + try: # If the bot is already created, return it. Saves time since get_me is not called again. + return tz_bots[timezone] + except KeyError: + default_bot = make_bot(bot_info, defaults=Defaults(tzinfo=timezone)) + await default_bot.initialize() + tz_bots[timezone] = default_bot + return default_bot @pytest.fixture(scope="session") @@ -248,7 +280,7 @@ def thumb_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def class_thumb_file(): f = data_file("thumb.jpg").open("rb") yield f @@ -401,7 +433,7 @@ def dst(self, dt): return datetime.timedelta(0) -@pytest.fixture(params=["Europe/Berlin", "Asia/Singapore", "UTC"]) +@pytest.fixture(scope="session", params=["Europe/Berlin", "Asia/Singapore", "UTC"]) def tzinfo(request): if TEST_WITH_OPT_DEPS: return pytz.timezone(request.param) @@ -410,7 +442,7 @@ def tzinfo(request): return BasicTimezone(offset=datetime.timedelta(hours=hours_offset), name=request.param) -@pytest.fixture() +@pytest.fixture(scope="session") def timezone(tzinfo): return tzinfo diff --git a/tests/test_animation.py b/tests/test_animation.py index 98c2184eaba..5017f2753c7 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -40,7 +40,7 @@ def animation_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def animation(bot, chat_id): with data_file("game.gif").open("rb") as f: thumb = data_file("thumb.jpg") @@ -49,7 +49,7 @@ async def animation(bot, chat_id): ).animation -class TestAnimation: +class Space: animation_file_id = "CgADAQADngIAAuyVeEez0xRovKi9VAI" animation_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" width = 320 @@ -63,6 +63,8 @@ class TestAnimation: file_size = 5859 caption = "Test *animation*" + +class TestAnimationNoReq: def test_slot_behaviour(self, animation, mro_slots): for attr in animation.__slots__: assert getattr(animation, attr, "err") != "err", f"got extra slot '{attr}'" @@ -76,19 +78,131 @@ def test_creation(self, animation): assert animation.file_unique_id != "" def test_expected_values(self, animation): - assert animation.mime_type == self.mime_type - assert animation.file_name.startswith("game.gif") == self.file_name.startswith("game.gif") + assert animation.mime_type == Space.mime_type + assert animation.file_name.startswith("game.gif") == Space.file_name.startswith("game.gif") assert isinstance(animation.thumb, PhotoSize) - @pytest.mark.flaky(3, 1) + async def test_send_animation_custom_filename(self, bot, chat_id, animation_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") + monkeypatch.delattr(bot.request, "post") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_animation_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("animation") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("animation"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_animation(chat_id, file, thumb=file) + assert test_flag + monkeypatch.delattr(bot, "_post") + finally: + bot._local_mode = False + + async def test_send_with_animation(self, monkeypatch, bot, chat_id, animation): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["animation"] == animation.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_animation(animation=animation, chat_id=chat_id) + assert message + + def test_de_json(self, bot, animation): + json_dict = { + "file_id": Space.animation_file_id, + "file_unique_id": Space.animation_file_unique_id, + "width": Space.width, + "height": Space.height, + "duration": Space.duration, + "thumb": animation.thumb.to_dict(), + "file_name": Space.file_name, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + } + animation = Animation.de_json(json_dict, bot) + assert animation.api_kwargs == {} + assert animation.file_id == Space.animation_file_id + assert animation.file_unique_id == Space.animation_file_unique_id + assert animation.file_name == Space.file_name + assert animation.mime_type == Space.mime_type + assert animation.file_size == Space.file_size + + def test_to_dict(self, animation): + animation_dict = animation.to_dict() + + assert isinstance(animation_dict, dict) + assert animation_dict["file_id"] == animation.file_id + assert animation_dict["file_unique_id"] == animation.file_unique_id + assert animation_dict["width"] == animation.width + assert animation_dict["height"] == animation.height + assert animation_dict["duration"] == animation.duration + assert animation_dict["thumb"] == animation.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 + + async def test_get_file_instance_method(self, monkeypatch, animation): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == animation.file_id + + assert check_shortcut_signature(Animation.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(animation.get_file, animation.get_bot(), "get_file") + assert await check_defaults_handling(animation.get_file, animation.get_bot()) + + monkeypatch.setattr(animation.get_bot(), "get_file", make_assertion) + assert await animation.get_file() + + def test_equality(self): + a = Animation( + Space.animation_file_id, + Space.animation_file_unique_id, + Space.height, + Space.width, + Space.duration, + ) + b = Animation( + "", Space.animation_file_unique_id, Space.height, Space.width, Space.duration + ) + d = Animation("", "", 0, 0, 0) + e = Voice(Space.animation_file_id, Space.animation_file_unique_id, 0) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + +class TestAnimationReq: async def test_send_all_args(self, bot, chat_id, animation_file, animation, thumb_file): message = await bot.send_animation( chat_id, animation_file, - duration=self.duration, - width=self.width, - height=self.height, - caption=self.caption, + duration=Space.duration, + width=Space.width, + height=Space.height, + caption=Space.caption, parse_mode="Markdown", disable_notification=False, protect_content=True, @@ -103,21 +217,10 @@ async def test_send_all_args(self, bot, chat_id, animation_file, animation, thum assert message.animation.file_name == animation.file_name assert message.animation.mime_type == animation.mime_type assert message.animation.file_size == animation.file_size - assert message.animation.thumb.width == self.width - assert message.animation.thumb.height == self.height + assert message.animation.thumb.width == Space.width + assert message.animation.thumb.height == Space.height assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_send_animation_custom_filename(self, bot, chat_id, animation_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") - monkeypatch.delattr(bot.request, "post") - - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, animation): path = Path("game.gif") if path.is_file(): @@ -132,13 +235,12 @@ async def test_get_and_download(self, bot, animation): assert new_filepath.is_file() - @pytest.mark.flaky(3, 1) async def test_send_animation_url_file(self, bot, chat_id, animation): message = await bot.send_animation( - chat_id=chat_id, animation=self.animation_file_url, caption=self.caption + chat_id=chat_id, animation=Space.animation_file_url, caption=Space.caption ) - assert message.caption == self.caption + assert message.caption == Space.caption assert isinstance(message.animation, Animation) assert isinstance(message.animation.file_id, str) @@ -152,7 +254,6 @@ async def test_send_animation_url_file(self, bot, chat_id, animation): ) == animation.file_name.startswith("game.gif") assert message.animation.mime_type == animation.mime_type - @pytest.mark.flaky(3, 1) async def test_send_animation_caption_entities(self, bot, chat_id, animation): test_string = "Italic Bold Code" entities = [ @@ -167,7 +268,6 @@ async def test_send_animation_caption_entities(self, bot, chat_id, animation): assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_animation_default_parse_mode_1(self, default_bot, chat_id, animation_file): test_string = "Italic Bold Code" @@ -179,7 +279,6 @@ async def test_send_animation_default_parse_mode_1(self, default_bot, chat_id, a assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_animation_default_parse_mode_2(self, default_bot, chat_id, animation_file): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -190,7 +289,6 @@ async def test_send_animation_default_parse_mode_2(self, default_bot, chat_id, a assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_animation_default_parse_mode_3(self, default_bot, chat_id, animation_file): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -201,32 +299,6 @@ async def test_send_animation_default_parse_mode_3(self, default_bot, chat_id, a assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_animation_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("animation") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("animation"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_animation(chat_id, file, thumb=file) - assert test_flag - monkeypatch.delattr(bot, "_post") - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -260,7 +332,6 @@ async def test_send_animation_default_allow_sending_without_reply( chat_id, animation, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_animation_default_protect_content(self, default_bot, chat_id, animation): animation_protected = await default_bot.send_animation(chat_id, animation) @@ -270,62 +341,17 @@ async def test_send_animation_default_protect_content(self, default_bot, chat_id ) assert not ani_unprotected.has_protected_content - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, animation): message = await bot.send_animation(chat_id, animation.file_id) assert message.animation == animation - async def test_send_with_animation(self, monkeypatch, bot, chat_id, animation): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["animation"] == animation.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_animation(animation=animation, chat_id=chat_id) - assert message - - def test_de_json(self, bot, animation): - json_dict = { - "file_id": self.animation_file_id, - "file_unique_id": self.animation_file_unique_id, - "width": self.width, - "height": self.height, - "duration": self.duration, - "thumb": animation.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.api_kwargs == {} - assert animation.file_id == self.animation_file_id - assert animation.file_unique_id == self.animation_file_unique_id - assert animation.file_name == self.file_name - assert animation.mime_type == self.mime_type - assert animation.file_size == self.file_size - - def test_to_dict(self, animation): - animation_dict = animation.to_dict() - - assert isinstance(animation_dict, dict) - assert animation_dict["file_id"] == animation.file_id - assert animation_dict["file_unique_id"] == animation.file_unique_id - assert animation_dict["width"] == animation.width - assert animation_dict["height"] == animation.height - assert animation_dict["duration"] == animation.duration - assert animation_dict["thumb"] == animation.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 - - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): animation_file = open(os.devnull, "rb") with pytest.raises(TelegramError): await bot.send_animation(chat_id=chat_id, animation=animation_file) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_animation(chat_id=chat_id, animation="") @@ -333,36 +359,3 @@ async def test_error_send_empty_file_id(self, bot, chat_id): async def test_error_send_without_required_args(self, bot, chat_id): with pytest.raises(TypeError): await bot.send_animation(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, animation): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == animation.file_id - - assert check_shortcut_signature(Animation.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(animation.get_file, animation.get_bot(), "get_file") - assert await check_defaults_handling(animation.get_file, animation.get_bot()) - - monkeypatch.setattr(animation.get_bot(), "get_file", make_assertion) - assert await animation.get_file() - - def test_equality(self): - a = Animation( - self.animation_file_id, - self.animation_file_unique_id, - self.height, - self.width, - self.duration, - ) - b = Animation("", self.animation_file_unique_id, self.height, self.width, self.duration) - d = Animation("", "", 0, 0, 0) - e = Voice(self.animation_file_id, self.animation_file_unique_id, 0) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) diff --git a/tests/test_audio.py b/tests/test_audio.py index 9619e7ef5a1..f4c1f49b15f 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -33,13 +33,13 @@ from tests.conftest import data_file -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def audio_file(): with open(data_file("telegram.mp3"), "rb") as f: yield f -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def audio(bot, chat_id): with data_file("telegram.mp3").open("rb") as f: thumb = data_file("thumb.jpg") @@ -48,7 +48,7 @@ async def audio(bot, chat_id): ).audio -class TestAudio: +class Space: caption = "Test *audio*" performer = "Leandro Toledo" title = "Teste" @@ -65,6 +65,8 @@ class TestAudio: audio_file_id = "5a3128a4d2a04750b5b58397f3b5e812" audio_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" + +class TestAudioNoReq: def test_slot_behaviour(self, audio, mro_slots): for attr in audio.__slots__: assert getattr(audio, attr, "err") != "err", f"got extra slot '{attr}'" @@ -79,58 +81,157 @@ def test_creation(self, audio): assert audio.file_unique_id != "" def test_expected_values(self, audio): - assert audio.duration == self.duration + assert audio.duration == Space.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 - assert audio.thumb.file_size == self.thumb_file_size - assert audio.thumb.width == self.thumb_width - assert audio.thumb.height == self.thumb_height + assert audio.mime_type == Space.mime_type + assert audio.file_size == Space.file_size + assert audio.thumb.file_size == Space.thumb_file_size + assert audio.thumb.width == Space.thumb_width + assert audio.thumb.height == Space.thumb_height + + async def test_send_audio_custom_filename(self, bot, chat_id, audio_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_audio(chat_id, audio_file, filename="custom_filename") + + async def test_send_with_audio(self, monkeypatch, bot, chat_id, audio): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["audio"] == audio.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_audio(audio=audio, chat_id=chat_id) + assert message + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_audio_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("audio") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("audio"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_audio(chat_id, file, thumb=file) + assert test_flag + monkeypatch.delattr(bot, "_post") + finally: + bot._local_mode = False + + def test_de_json(self, bot, audio): + json_dict = { + "file_id": Space.audio_file_id, + "file_unique_id": Space.audio_file_unique_id, + "duration": Space.duration, + "performer": Space.performer, + "title": Space.title, + "file_name": Space.file_name, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + "thumb": audio.thumb.to_dict(), + } + json_audio = Audio.de_json(json_dict, bot) + assert json_audio.api_kwargs == {} + + assert json_audio.file_id == Space.audio_file_id + assert json_audio.file_unique_id == Space.audio_file_unique_id + assert json_audio.duration == Space.duration + assert json_audio.performer == Space.performer + assert json_audio.title == Space.title + assert json_audio.file_name == Space.file_name + assert json_audio.mime_type == Space.mime_type + assert json_audio.file_size == Space.file_size + assert json_audio.thumb == audio.thumb + + 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["file_unique_id"] == audio.file_unique_id + assert audio_dict["duration"] == audio.duration + assert audio_dict["mime_type"] == audio.mime_type + assert audio_dict["file_size"] == audio.file_size + assert audio_dict["file_name"] == audio.file_name + + async def test_get_file_instance_method(self, monkeypatch, audio): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == audio.file_id + + assert check_shortcut_signature(Audio.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(audio.get_file, audio.get_bot(), "get_file") + assert await check_defaults_handling(audio.get_file, audio.get_bot()) + + monkeypatch.setattr(audio._bot, "get_file", make_assertion) + assert await audio.get_file() + + def test_equality(self, audio): + a = Audio(audio.file_id, audio.file_unique_id, audio.duration) + b = Audio("", audio.file_unique_id, audio.duration) + c = Audio(audio.file_id, audio.file_unique_id, 0) + d = Audio("", "", audio.duration) + e = Voice(audio.file_id, audio.file_unique_id, audio.duration) + + 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) - @pytest.mark.flaky(3, 1) + +class TestAudioReq: async def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): message = await bot.send_audio( chat_id, audio=audio_file, - caption=self.caption, - duration=self.duration, - performer=self.performer, - title=self.title, + caption=Space.caption, + duration=Space.duration, + performer=Space.performer, + title=Space.title, disable_notification=False, protect_content=True, parse_mode="Markdown", thumb=thumb_file, ) - assert message.caption == self.caption.replace("*", "") + assert message.caption == Space.caption.replace("*", "") assert isinstance(message.audio, Audio) assert isinstance(message.audio.file_id, str) assert isinstance(message.audio.file_unique_id, str) assert message.audio.file_unique_id is not None 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.file_name == self.file_name - assert message.audio.mime_type == self.mime_type - assert message.audio.file_size == self.file_size - assert message.audio.thumb.file_size == self.thumb_file_size - assert message.audio.thumb.width == self.thumb_width - assert message.audio.thumb.height == self.thumb_height + assert message.audio.duration == Space.duration + assert message.audio.performer == Space.performer + assert message.audio.title == Space.title + assert message.audio.file_name == Space.file_name + assert message.audio.mime_type == Space.mime_type + assert message.audio.file_size == Space.file_size + assert message.audio.thumb.file_size == Space.thumb_file_size + assert message.audio.thumb.width == Space.thumb_width + assert message.audio.thumb.height == Space.thumb_height assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_send_audio_custom_filename(self, bot, chat_id, audio_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_audio(chat_id, audio_file, filename="custom_filename") - - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, audio): path = Path("telegram.mp3") if path.is_file(): @@ -138,7 +239,7 @@ async def test_get_and_download(self, bot, audio): new_file = await bot.get_file(audio.file_id) - assert new_file.file_size == self.file_size + assert new_file.file_size == Space.file_size assert new_file.file_id == audio.file_id assert new_file.file_unique_id == audio.file_unique_id assert str(new_file.file_path).startswith("https://") @@ -147,13 +248,12 @@ async def test_get_and_download(self, bot, audio): assert path.is_file() - @pytest.mark.flaky(3, 1) async def test_send_mp3_url_file(self, bot, chat_id, audio): message = await bot.send_audio( - chat_id=chat_id, audio=self.audio_file_url, caption=self.caption + chat_id=chat_id, audio=Space.audio_file_url, caption=Space.caption ) - assert message.caption == self.caption + assert message.caption == Space.caption assert isinstance(message.audio, Audio) assert isinstance(message.audio.file_id, str) @@ -164,21 +264,11 @@ async def test_send_mp3_url_file(self, bot, chat_id, audio): assert message.audio.mime_type == audio.mime_type assert message.audio.file_size == audio.file_size - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, audio): message = await bot.send_audio(chat_id=chat_id, audio=audio.file_id) assert message.audio == audio - async def test_send_with_audio(self, monkeypatch, bot, chat_id, audio): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["audio"] == audio.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_audio(audio=audio, chat_id=chat_id) - assert message - - @pytest.mark.flaky(3, 1) async def test_send_audio_caption_entities(self, bot, chat_id, audio): test_string = "Italic Bold Code" entities = [ @@ -193,7 +283,6 @@ async def test_send_audio_caption_entities(self, bot, chat_id, audio): assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_audio_default_parse_mode_1(self, default_bot, chat_id, audio_file): test_string = "Italic Bold Code" @@ -203,7 +292,6 @@ async def test_send_audio_default_parse_mode_1(self, default_bot, chat_id, audio assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_audio_default_parse_mode_2(self, default_bot, chat_id, audio_file): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -214,7 +302,6 @@ async def test_send_audio_default_parse_mode_2(self, default_bot, chat_id, audio assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_audio_default_parse_mode_3(self, default_bot, chat_id, audio_file): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -225,7 +312,6 @@ async def test_send_audio_default_parse_mode_3(self, default_bot, chat_id, audio assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_audio_default_protect_content(self, default_bot, chat_id, audio): protected_audio = await default_bot.send_audio(chat_id, audio) @@ -233,75 +319,12 @@ async def test_send_audio_default_protect_content(self, default_bot, chat_id, au unprotected = await default_bot.send_audio(chat_id, audio, protect_content=False) assert not unprotected.has_protected_content - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_audio_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("audio") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("audio"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_audio(chat_id, file, thumb=file) - assert test_flag - monkeypatch.delattr(bot, "_post") - finally: - bot._local_mode = False - - def test_de_json(self, bot, audio): - json_dict = { - "file_id": self.audio_file_id, - "file_unique_id": self.audio_file_unique_id, - "duration": self.duration, - "performer": self.performer, - "title": self.title, - "file_name": self.file_name, - "mime_type": self.mime_type, - "file_size": self.file_size, - "thumb": audio.thumb.to_dict(), - } - json_audio = Audio.de_json(json_dict, bot) - assert json_audio.api_kwargs == {} - - assert json_audio.file_id == self.audio_file_id - assert json_audio.file_unique_id == self.audio_file_unique_id - assert json_audio.duration == self.duration - assert json_audio.performer == self.performer - assert json_audio.title == self.title - assert json_audio.file_name == self.file_name - assert json_audio.mime_type == self.mime_type - assert json_audio.file_size == self.file_size - assert json_audio.thumb == audio.thumb - - 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["file_unique_id"] == audio.file_unique_id - assert audio_dict["duration"] == audio.duration - assert audio_dict["mime_type"] == audio.mime_type - assert audio_dict["file_size"] == audio.file_size - assert audio_dict["file_name"] == audio.file_name - - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): audio_file = open(os.devnull, "rb") with pytest.raises(TelegramError): await bot.send_audio(chat_id=chat_id, audio=audio_file) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_audio(chat_id=chat_id, audio="") @@ -309,34 +332,3 @@ async def test_error_send_empty_file_id(self, bot, chat_id): async def test_error_send_without_required_args(self, bot, chat_id): with pytest.raises(TypeError): await bot.send_audio(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, audio): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == audio.file_id - - assert check_shortcut_signature(Audio.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(audio.get_file, audio.get_bot(), "get_file") - assert await check_defaults_handling(audio.get_file, audio.get_bot()) - - monkeypatch.setattr(audio._bot, "get_file", make_assertion) - assert await audio.get_file() - - def test_equality(self, audio): - a = Audio(audio.file_id, audio.file_unique_id, audio.duration) - b = Audio("", audio.file_unique_id, audio.duration) - c = Audio(audio.file_id, audio.file_unique_id, 0) - d = Audio("", "", audio.duration) - e = Voice(audio.file_id, audio.file_unique_id, audio.duration) - - 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_bot.py b/tests/test_bot.py index f8489bbd03c..d4b7d6f275d 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -76,7 +76,15 @@ from telegram.request import BaseRequest, HTTPXRequest, RequestData from tests.auxil.bot_method_checks import check_defaults_handling from tests.bots import FALLBACKS -from tests.conftest import GITHUB_ACTION, data_file, expect_bad_request, make_bot +from tests.conftest import ( + GITHUB_ACTION, + TEST_WITH_OPT_DEPS, + DictBot, + DictExtBot, + data_file, + expect_bad_request, + make_bot, +) def to_camel_case(snake_str): @@ -87,7 +95,7 @@ def to_camel_case(snake_str): return components[0] + "".join(x.title() for x in components[1:]) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def message(bot, chat_id): to_reply_to = await bot.send_message( chat_id, "Text", disable_web_page_preview=True, disable_notification=True @@ -103,13 +111,13 @@ async def message(bot, chat_id): return out -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def media_message(bot, chat_id): with data_file("telegram.ogg").open("rb") as f: return await bot.send_voice(chat_id, voice=f, caption="my caption", read_timeout=10) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_permissions(): return ChatPermissions(can_send_messages=False, can_change_info=False, can_invite_users=False) @@ -125,7 +133,7 @@ def inline_results_callback(page=None): return None -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_results(): return inline_results_callback() @@ -188,24 +196,7 @@ def __init__( self.disable_web_page_preview = disable_web_page_preview -class TestBot: - """ - Most are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot - - Behavior for init of ExtBot with missing optional dependency cachetools (for CallbackDataCache) - is tested in `test_callbackdatacache` - """ - - @staticmethod - def localize(dt, tzinfo): - try: - return tzinfo.localize(dt) - except AttributeError: - # We get here if tzinfo is not a pytz timezone but a datetime.timezone class - # This test class should never be run in if pytz is not installed, we intentionally - # fail if this branch is ever reached. - sys.exit(1) - +class TestBotNoReq: test_flag = None @pytest.fixture(scope="function", autouse=True) @@ -335,11 +326,6 @@ async def test_no_token_passed(self): with pytest.raises(InvalidToken, match="You must pass the token"): Bot("") - async def test_invalid_token_server_response(self): - with pytest.raises(InvalidToken, match="The token `12` was rejected by the server."): - async with make_bot(token="12"): - pass - async def test_unknown_kwargs(self, bot, monkeypatch): async def post(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters @@ -352,20 +338,10 @@ async def post(url, request_data: RequestData, *args, **kwargs): 123, "text", api_kwargs={"unknown_kwarg_1": 7, "unknown_kwarg_2": 5} ) - @pytest.mark.flaky(3, 1) - async def test_get_me_and_properties(self, bot: Bot): - get_me_bot = await bot.get_me() - - 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 - assert get_me_bot.can_join_groups == bot.can_join_groups - assert get_me_bot.can_read_all_group_messages == bot.can_read_all_group_messages - assert get_me_bot.supports_inline_queries == bot.supports_inline_queries - assert f"https://t.me/{get_me_bot.username}" == bot.link + async def test_invalid_token_server_response(self): + with pytest.raises(InvalidToken, match="The token `12` was rejected by the server."): + async with make_bot(token="12"): + pass @pytest.mark.parametrize( "attribute", @@ -389,6 +365,20 @@ async def test_get_me_and_properties_not_initialized(self, bot: Bot, attribute): finally: await bot.shutdown() + async def test_get_me_and_properties(self, bot: Bot): + get_me_bot = await bot.get_me() + + 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 + assert get_me_bot.can_join_groups == bot.can_join_groups + assert get_me_bot.can_read_all_group_messages == bot.can_read_all_group_messages + assert get_me_bot.supports_inline_queries == bot.supports_inline_queries + assert f"https://t.me/{get_me_bot.username}" == bot.link + async def test_equality(self): async with make_bot(token=FALLBACKS[0]["token"]) as a, make_bot( token=FALLBACKS[0]["token"] @@ -408,7 +398,6 @@ async def test_equality(self): assert a != e assert hash(a) != hash(e) - @pytest.mark.flaky(3, 1) async def test_to_dict(self, bot): to_dict_bot = bot.to_dict() @@ -495,1101 +484,1458 @@ def test_ext_bot_signature(self): param.kind == ext_signature.parameters[param_name].kind ), f"Wrong parameter kind for parameter {param_name} of method {name}" - @pytest.mark.flaky(3, 1) - async def test_forward_message(self, bot, chat_id, message): - forward_message = await bot.forward_message( - chat_id, from_chat_id=chat_id, message_id=message.message_id - ) - - assert forward_message.text == message.text - assert forward_message.forward_from.username == message.from_user.username - assert isinstance(forward_message.forward_date, dtm.datetime) + async def test_answer_web_app_query(self, bot, raw_bot, monkeypatch): + params = False - async def test_forward_protected_message(self, bot, message, chat_id): - to_forward_protected = await bot.send_message( - chat_id, "cant forward me", protect_content=True - ) - assert to_forward_protected.has_protected_content + # For now just test that our internals pass the correct data - with pytest.raises(BadRequest, match="can't be forwarded"): - await to_forward_protected.forward(chat_id) + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + nonlocal params + params = request_data.parameters == { + "web_app_query_id": "12345", + "result": { + "title": "title", + "input_message_content": { + "message_text": "text", + }, + "type": InlineQueryResultType.ARTICLE, + "id": "1", + }, + } + web_app_msg = SentWebAppMessage("321").to_dict() + return web_app_msg - to_forward_unprotected = await bot.send_message( - chat_id, "forward me", protect_content=False - ) - assert not to_forward_unprotected.has_protected_content - forwarded_but_now_protected = await to_forward_unprotected.forward( - chat_id, protect_content=True - ) - assert forwarded_but_now_protected.has_protected_content - with pytest.raises(BadRequest, match="can't be forwarded"): - await forwarded_but_now_protected.forward(chat_id) + # We test different result types more thoroughly for answer_inline_query, so we just + # use the one type here + result = InlineQueryResultArticle("1", "title", InputTextMessageContent("text")) + copied_result = copy.copy(result) - @pytest.mark.flaky(3, 1) - async def test_delete_message(self, bot, chat_id): - message = await bot.send_message(chat_id, text="will be deleted") - await asyncio.sleep(2) + ext_bot = bot + for bot in (ext_bot, raw_bot): + # We need to test 1) below both the bot and raw_bot and setting this up with + # pytest.parametrize appears to be difficult ... + monkeypatch.setattr(bot.request, "post", make_assertion) + web_app_msg = await bot.answer_web_app_query("12345", result) + assert params, "something went wrong with passing arguments to the request" + assert isinstance(web_app_msg, SentWebAppMessage) + assert web_app_msg.inline_message_id == "321" - assert await bot.delete_message(chat_id=chat_id, message_id=message.message_id) is True + # 1) + # make sure that the results were not edited in-place + assert result == copied_result + assert ( + result.input_message_content.parse_mode + == copied_result.input_message_content.parse_mode + ) - @pytest.mark.flaky(3, 1) - async def test_delete_message_old_message(self, bot, chat_id): - with pytest.raises(BadRequest): - # Considering that the first message is old enough - await bot.delete_message(chat_id=chat_id, message_id=1) + @pytest.mark.parametrize( + "default_bot", + [{"parse_mode": "Markdown", "disable_web_page_preview": True}], + indirect=True, + ) + @pytest.mark.parametrize( + "ilq_result,expected_params", + [ + ( + InlineQueryResultArticle("1", "title", InputTextMessageContent("text")), + { + "web_app_query_id": "12345", + "result": { + "title": "title", + "input_message_content": { + "message_text": "text", + "parse_mode": "Markdown", + "disable_web_page_preview": True, + }, + "type": InlineQueryResultType.ARTICLE, + "id": "1", + }, + }, + ), + ( + InlineQueryResultArticle( + "1", + "title", + InputTextMessageContent( + "text", parse_mode="HTML", disable_web_page_preview=False + ), + ), + { + "web_app_query_id": "12345", + "result": { + "title": "title", + "input_message_content": { + "message_text": "text", + "parse_mode": "HTML", + "disable_web_page_preview": False, + }, + "type": InlineQueryResultType.ARTICLE, + "id": "1", + }, + }, + ), + ( + InlineQueryResultArticle( + "1", + "title", + InputTextMessageContent( + "text", parse_mode=None, disable_web_page_preview="False" + ), + ), + { + "web_app_query_id": "12345", + "result": { + "title": "title", + "input_message_content": { + "message_text": "text", + "disable_web_page_preview": "False", + }, + "type": InlineQueryResultType.ARTICLE, + "id": "1", + }, + }, + ), + ], + ) + async def test_answer_web_app_query_defaults( + self, default_bot, ilq_result, expected_params, monkeypatch + ): + bot = default_bot + params = False - # send_photo, send_audio, send_document, send_sticker, send_video, send_voice, send_video_note, - # send_media_group and send_animation are tested in their respective test modules. No need to - # duplicate here. + # For now just test that our internals pass the correct data - @pytest.mark.flaky(3, 1) - async def test_send_venue(self, bot, chat_id): - longitude = -46.788279 - latitude = -23.691288 - title = "title" - address = "address" - foursquare_id = "foursquare id" - foursquare_type = "foursquare type" - google_place_id = "google_place id" - google_place_type = "google_place type" + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + nonlocal params + params = request_data.parameters == expected_params + web_app_msg = SentWebAppMessage("321").to_dict() + return web_app_msg - message = await bot.send_venue( - chat_id=chat_id, - title=title, - address=address, - latitude=latitude, - longitude=longitude, - foursquare_id=foursquare_id, - foursquare_type=foursquare_type, - protect_content=True, - ) + monkeypatch.setattr(bot.request, "post", make_assertion) - 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 - assert message.venue.foursquare_id == foursquare_id - assert message.venue.foursquare_type == foursquare_type - assert message.venue.google_place_id is None - assert message.venue.google_place_type is None - assert message.has_protected_content + # We test different result types more thoroughly for answer_inline_query, so we just + # use the one type here + copied_result = copy.copy(ilq_result) - message = await bot.send_venue( - chat_id=chat_id, - title=title, - address=address, - latitude=latitude, - longitude=longitude, - google_place_id=google_place_id, - google_place_type=google_place_type, - protect_content=True, - ) + web_app_msg = await bot.answer_web_app_query("12345", ilq_result) + assert params, "something went wrong with passing arguments to the request" + assert isinstance(web_app_msg, SentWebAppMessage) + assert web_app_msg.inline_message_id == "321" - 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 - assert message.venue.google_place_id == google_place_id - assert message.venue.google_place_type == google_place_type - assert message.venue.foursquare_id is None - assert message.venue.foursquare_type is None - assert message.has_protected_content - - @pytest.mark.flaky(3, 1) - async def test_send_contact(self, bot, chat_id): - phone_number = "+11234567890" - first_name = "Leandro" - last_name = "Toledo" - message = await bot.send_contact( - chat_id=chat_id, - phone_number=phone_number, - first_name=first_name, - last_name=last_name, - protect_content=True, + # make sure that the results were not edited in-place + assert ilq_result == copied_result + assert ( + ilq_result.input_message_content.parse_mode + == copied_result.input_message_content.parse_mode ) - assert message.contact - assert message.contact.phone_number == phone_number - assert message.contact.first_name == first_name - assert message.contact.last_name == last_name - assert message.has_protected_content - - # TODO: Add bot to group to test polls too + # TODO: Needs improvement. We need incoming inline query to test answer. + async def test_answer_inline_query(self, monkeypatch, bot, raw_bot): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "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"}, + }, + { + "title": "test_result", + "id": "123", + "type": "document", + "document_url": "https://raw.githubusercontent.com/python-telegram-bot" + "/logos/master/logo/png/ptb-logo_240.png", + "mime_type": "image/png", + "caption": "ptb_logo", + "input_message_content": {"message_text": "imc"}, + }, + ], + "next_offset": "42", + "switch_pm_parameter": "start_pm", + "inline_query_id": 1234, + "is_personal": True, + "switch_pm_text": "switch pm", + } - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize( - "reply_markup", - [ - None, - InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="data") + results = [ + InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), + InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), + InlineQueryResultDocument( + id="123", + document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" + "logo/png/ptb-logo_240.png", + title="test_result", + mime_type="image/png", + caption="ptb_logo", + input_message_content=InputMessageContentDWPP("imc"), ), - InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="data") - ).to_dict(), - ], - ) - async def test_send_and_stop_poll(self, bot, super_group_id, reply_markup): - question = "Is this a test?" - answers = ["Yes", "No", "Maybe"] - message = await bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - is_anonymous=False, - allows_multiple_answers=True, - read_timeout=60, - protect_content=True, - ) + ] - assert message.poll - assert message.poll.question == question - assert message.poll.options[0].text == answers[0] - assert message.poll.options[1].text == answers[1] - assert message.poll.options[2].text == answers[2] - assert not message.poll.is_anonymous - assert message.poll.allows_multiple_answers - assert not message.poll.is_closed - assert message.poll.type == Poll.REGULAR - assert message.has_protected_content + copied_results = copy.copy(results) + ext_bot = bot + for bot in (ext_bot, raw_bot): + # We need to test 1) below both the bot and raw_bot and setting this up with + # pytest.parametrize appears to be difficult ... + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await 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", + ) - # Since only the poll and not the complete message is returned, we can't check that the - # reply_markup is correct. So we just test that sending doesn't give an error. - poll = await bot.stop_poll( - chat_id=super_group_id, - message_id=message.message_id, - reply_markup=reply_markup, - read_timeout=60, - ) - assert isinstance(poll, Poll) - assert poll.is_closed - assert poll.options[0].text == answers[0] - assert poll.options[0].voter_count == 0 - assert poll.options[1].text == answers[1] - assert poll.options[1].voter_count == 0 - assert poll.options[2].text == answers[2] - assert poll.options[2].voter_count == 0 - assert poll.question == question - assert poll.total_voter_count == 0 + # 1) + # make sure that the results were not edited in-place + assert results == copied_results + for idx, result in enumerate(results): + if hasattr(result, "parse_mode"): + assert result.parse_mode == copied_results[idx].parse_mode + if hasattr(result, "input_message_content"): + assert getattr(result.input_message_content, "parse_mode", None) == getattr( + copied_results[idx].input_message_content, "parse_mode", None + ) + assert getattr( + result.input_message_content, "disable_web_page_preview", None + ) == getattr( + copied_results[idx].input_message_content, "disable_web_page_preview", None + ) - explanation = "[Here is a link](https://google.com)" - explanation_entities = [ - MessageEntity(MessageEntity.TEXT_LINK, 0, 14, url="https://google.com") + monkeypatch.delattr(bot.request, "post") + + async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "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"}, + }, + { + "title": "test_result", + "id": "123", + "type": "document", + "document_url": "https://raw.githubusercontent.com/" + "python-telegram-bot/logos/master/logo/png/" + "ptb-logo_240.png", + "mime_type": "image/png", + "caption": "ptb_logo", + "input_message_content": {"message_text": "imc"}, + }, + ], + "next_offset": "42", + "switch_pm_parameter": "start_pm", + "inline_query_id": 1234, + "is_personal": True, + "switch_pm_text": "switch pm", + } + + monkeypatch.setattr(bot.request, "post", make_assertion) + results = [ + InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), + InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), + InlineQueryResultDocument( + id="123", + document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" + "logo/png/ptb-logo_240.png", + title="test_result", + mime_type="image/png", + caption="ptb_logo", + input_message_content=InputMessageContentDWPP("imc"), + ), ] - message_quiz = await bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation, - explanation_parse_mode=ParseMode.MARKDOWN_V2, + + copied_results = copy.copy(results) + assert await 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", ) - assert message_quiz.poll.correct_option_id == 2 - assert message_quiz.poll.type == Poll.QUIZ - assert message_quiz.poll.is_closed - assert message_quiz.poll.explanation == "Here is a link" - assert message_quiz.poll.explanation_entities == tuple(explanation_entities) + # make sure that the results were not edited in-place + assert results == copied_results + for idx, result in enumerate(results): + if hasattr(result, "parse_mode"): + assert result.parse_mode == copied_results[idx].parse_mode + if hasattr(result, "input_message_content"): + assert getattr(result.input_message_content, "parse_mode", None) == getattr( + copied_results[idx].input_message_content, "parse_mode", None + ) + assert getattr( + result.input_message_content, "disable_web_page_preview", None + ) == getattr( + copied_results[idx].input_message_content, "disable_web_page_preview", None + ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( - ["open_period", "close_date"], [(5, None), (None, True)], ids=["open_period", "close_date"] - ) - async def test_send_open_period(self, bot, super_group_id, open_period, close_date): - question = "Is this a test?" - answers = ["Yes", "No", "Maybe"] - reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="data") - ) + "default_bot", + [{"parse_mode": "Markdown", "disable_web_page_preview": True}], + indirect=True, + ) + async def test_answer_inline_query_default_parse_mode(self, monkeypatch, default_bot): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "cache_time": 300, + "results": [ + { + "title": "first", + "id": "11", + "type": "article", + "input_message_content": { + "message_text": "first", + "parse_mode": "Markdown", + "disable_web_page_preview": True, + }, + }, + { + "title": "second", + "id": "12", + "type": "article", + "input_message_content": { + "message_text": "second", + "disable_web_page_preview": True, + }, + }, + { + "title": "test_result", + "id": "123", + "type": "document", + "document_url": "https://raw.githubusercontent.com/" + "python-telegram-bot/logos/master/logo/png/" + "ptb-logo_240.png", + "mime_type": "image/png", + "caption": "ptb_logo", + "parse_mode": "Markdown", + "input_message_content": { + "message_text": "imc", + "disable_web_page_preview": True, + "parse_mode": "Markdown", + }, + }, + ], + "next_offset": "42", + "switch_pm_parameter": "start_pm", + "inline_query_id": 1234, + "is_personal": True, + "switch_pm_text": "switch pm", + } - if close_date: - close_date = dtm.datetime.utcnow() + dtm.timedelta(seconds=5.05) + monkeypatch.setattr(default_bot.request, "post", make_assertion) + results = [ + InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), + InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), + InlineQueryResultDocument( + id="123", + document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" + "logo/png/ptb-logo_240.png", + title="test_result", + mime_type="image/png", + caption="ptb_logo", + input_message_content=InputTextMessageContent("imc"), + ), + ] - message = await bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - is_anonymous=False, - allows_multiple_answers=True, - read_timeout=60, - open_period=open_period, - close_date=close_date, - ) - await asyncio.sleep(5.1) - new_message = await bot.edit_message_reply_markup( - chat_id=super_group_id, - message_id=message.message_id, - reply_markup=reply_markup, - read_timeout=60, + copied_results = copy.copy(results) + assert await default_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", ) - assert new_message.poll.id == message.poll.id - assert new_message.poll.is_closed + # make sure that the results were not edited in-place + assert results == copied_results + for idx, result in enumerate(results): + if hasattr(result, "parse_mode"): + assert result.parse_mode == copied_results[idx].parse_mode + if hasattr(result, "input_message_content"): + assert getattr(result.input_message_content, "parse_mode", None) == getattr( + copied_results[idx].input_message_content, "parse_mode", None + ) + assert getattr( + result.input_message_content, "disable_web_page_preview", None + ) == getattr( + copied_results[idx].input_message_content, "disable_web_page_preview", None + ) - @pytest.mark.flaky(3, 1) - async def test_send_close_date_default_tz(self, tz_bot, super_group_id): - question = "Is this a test?" - answers = ["Yes", "No", "Maybe"] - reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="data") - ) + @pytest.mark.parametrize( + "current_offset,num_results,id_offset,expected_next_offset", + [ + ("", InlineQueryLimit.RESULTS, 1, 1), + (1, InlineQueryLimit.RESULTS, 51, 2), + (5, 3, 251, ""), + ], + ) + async def test_answer_inline_query_current_offset_1( + self, + monkeypatch, + bot, + inline_results, + current_offset, + num_results, + id_offset, + expected_next_offset, + ): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + results = data["results"] + length_matches = len(results) == num_results + ids_match = all(int(res["id"]) == id_offset + i for i, res in enumerate(results)) + next_offset_matches = data["next_offset"] == str(expected_next_offset) + return length_matches and ids_match and next_offset_matches - aware_close_date = dtm.datetime.now(tz=tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=5) - close_date = aware_close_date.replace(tzinfo=None) + monkeypatch.setattr(bot.request, "post", make_assertion) - msg = await tz_bot.send_poll( # The timezone returned from this is always converted to UTC - chat_id=super_group_id, - question=question, - options=answers, - close_date=close_date, - read_timeout=60, + assert await bot.answer_inline_query( + 1234, results=inline_results, current_offset=current_offset ) - msg.poll._unfreeze() - # Sometimes there can be a few seconds delay, so don't let the test fail due to that- - msg.poll.close_date = msg.poll.close_date.astimezone(aware_close_date.tzinfo) - assert abs(msg.poll.close_date - aware_close_date) <= dtm.timedelta(seconds=5) - await asyncio.sleep(5.1) + async def test_answer_inline_query_current_offset_2(self, monkeypatch, bot, inline_results): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + results = data["results"] + length_matches = len(results) == InlineQueryLimit.RESULTS + ids_match = all(int(res["id"]) == 1 + i for i, res in enumerate(results)) + next_offset_matches = data["next_offset"] == "1" + return length_matches and ids_match and next_offset_matches - new_message = await tz_bot.edit_message_reply_markup( - chat_id=super_group_id, - message_id=msg.message_id, - reply_markup=reply_markup, - read_timeout=60, - ) - assert new_message.poll.id == msg.poll.id - assert new_message.poll.is_closed + monkeypatch.setattr(bot.request, "post", make_assertion) - @pytest.mark.flaky(3, 1) - async def test_send_poll_explanation_entities(self, bot, chat_id): - test_string = "Italic Bold Code" - entities = [ - MessageEntity(MessageEntity.ITALIC, 0, 6), - MessageEntity(MessageEntity.ITALIC, 7, 4), - MessageEntity(MessageEntity.ITALIC, 12, 4), - ] - message = await bot.send_poll( - chat_id, - "question", - options=["a", "b"], - correct_option_id=0, - type=Poll.QUIZ, - explanation=test_string, - explanation_entities=entities, - ) + assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) - assert message.poll.explanation == test_string - assert message.poll.explanation_entities == tuple(entities) + inline_results = inline_results[:30] - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) - async def test_send_poll_default_parse_mode(self, default_bot, super_group_id): - explanation = "Italic Bold Code" - explanation_markdown = "_Italic_ *Bold* `Code`" - question = "Is this a test?" - answers = ["Yes", "No", "Maybe"] + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + results = data["results"] + length_matches = len(results) == 30 + ids_match = all(int(res["id"]) == 1 + i for i, res in enumerate(results)) + next_offset_matches = data["next_offset"] == "" + return length_matches and ids_match and next_offset_matches - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, - ) - assert message.poll.explanation == explanation - assert message.poll.explanation_entities == ( - MessageEntity(MessageEntity.ITALIC, 0, 6), - MessageEntity(MessageEntity.BOLD, 7, 4), - MessageEntity(MessageEntity.CODE, 12, 4), - ) + monkeypatch.setattr(bot.request, "post", make_assertion) - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode=None, + assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) + + async def test_answer_inline_query_current_offset_callback(self, monkeypatch, bot, caplog): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + results = data["results"] + length = len(results) == 5 + ids = all(int(res["id"]) == 6 + i for i, res in enumerate(results)) + next_offset = data["next_offset"] == "2" + return length and ids and next_offset + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.answer_inline_query( + 1234, results=inline_results_callback, current_offset=1 ) - assert message.poll.explanation == explanation_markdown - assert message.poll.explanation_entities == () - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode="HTML", - ) - assert message.poll.explanation == explanation_markdown - assert message.poll.explanation_entities == () + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + results = data["results"] + length = results == [] + next_offset = data["next_offset"] == "" + return length and next_offset - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize( - "default_bot,custom", - [ - ({"allow_sending_without_reply": True}, None), - ({"allow_sending_without_reply": False}, None), - ({"allow_sending_without_reply": False}, True), - ], - indirect=["default_bot"], - ) - async def test_send_poll_default_allow_sending_without_reply( - self, default_bot, chat_id, custom - ): - question = "Is this a test?" - answers = ["Yes", "No", "Maybe"] - reply_to_message = await default_bot.send_message(chat_id, "test") - await reply_to_message.delete() - if custom is not None: - message = await default_bot.send_poll( - chat_id, - question=question, - options=answers, - allow_sending_without_reply=custom, - reply_to_message_id=reply_to_message.message_id, - ) - assert message.reply_to_message is None - elif default_bot.defaults.allow_sending_without_reply: - message = await default_bot.send_poll( - chat_id, - question=question, - options=answers, - reply_to_message_id=reply_to_message.message_id, - ) - assert message.reply_to_message is None - else: - with pytest.raises(BadRequest, match="message not found"): - await default_bot.send_poll( - chat_id, - question=question, - options=answers, - reply_to_message_id=reply_to_message.message_id, - ) + monkeypatch.setattr(bot.request, "post", make_assertion) - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) - async def test_send_poll_default_protect_content(self, chat_id, default_bot): - protected_poll = await default_bot.send_poll(chat_id, "Test", ["1", "2"]) - assert protected_poll.has_protected_content - unprotect_poll = await default_bot.send_poll( - chat_id, "test", ["1", "2"], protect_content=False + assert await bot.answer_inline_query( + 1234, results=inline_results_callback, current_offset=6 ) - assert not unprotect_poll.has_protected_content - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI + [None]) - async def test_send_dice(self, bot, chat_id, emoji): - message = await bot.send_dice(chat_id, emoji=emoji, protect_content=True) + # get_file is tested multiple times in the test_*media* modules. + # Here we only test the behaviour for bot apis in local mode + async def test_get_file_local_mode(self, bot, monkeypatch): + path = str(data_file("game.gif")) - assert message.dice - assert message.has_protected_content - if emoji is None: - assert message.dice.emoji == Dice.DICE - else: - assert message.dice.emoji == emoji + async def _post(*args, **kwargs): + return { + "file_id": None, + "file_unique_id": None, + "file_size": None, + "file_path": path, + } - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize( - "default_bot,custom", - [ - ({"allow_sending_without_reply": True}, None), - ({"allow_sending_without_reply": False}, None), - ({"allow_sending_without_reply": False}, True), - ], - indirect=["default_bot"], - ) - async def test_send_dice_default_allow_sending_without_reply( - self, default_bot, chat_id, custom - ): - reply_to_message = await default_bot.send_message(chat_id, "test") - await reply_to_message.delete() - if custom is not None: - message = await default_bot.send_dice( - chat_id, - allow_sending_without_reply=custom, - reply_to_message_id=reply_to_message.message_id, - ) - assert message.reply_to_message is None - elif default_bot.defaults.allow_sending_without_reply: - message = await default_bot.send_dice( - chat_id, - reply_to_message_id=reply_to_message.message_id, - ) - assert message.reply_to_message is None - else: - with pytest.raises(BadRequest, match="message not found"): - await default_bot.send_dice( - chat_id, reply_to_message_id=reply_to_message.message_id - ) + monkeypatch.setattr(bot, "_post", _post) - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) - async def test_send_dice_default_protect_content(self, chat_id, default_bot): - protected_dice = await default_bot.send_dice(chat_id) - assert protected_dice.has_protected_content - unprotected_dice = await default_bot.send_dice(chat_id, protect_content=False) - assert not unprotected_dice.has_protected_content + resulting_path = (await bot.get_file("file_id")).file_path + assert bot.token not in resulting_path + assert resulting_path == path + monkeypatch.delattr(bot, "_post") - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("chat_action", list(ChatAction)) - async def test_send_chat_action(self, bot, chat_id, chat_action): - assert await bot.send_chat_action(chat_id, chat_action) + # TODO: Needs improvement. No feasible way to test until bots can add members. + async def test_ban_chat_member(self, monkeypatch, bot): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.json_parameters + chat_id = data["chat_id"] == "2" + user_id = data["user_id"] == "32" + until_date = data.get("until_date", "1577887200") == "1577887200" + revoke_msgs = data.get("revoke_messages", "true") == "true" + return chat_id and user_id and until_date and revoke_msgs - async def test_wrong_chat_action(self, bot, chat_id): - with pytest.raises(BadRequest, match="Wrong parameter action"): - await bot.send_chat_action(chat_id, "unknown action") + monkeypatch.setattr(bot.request, "post", make_assertion) + until = from_timestamp(1577887200) - @pytest.mark.asyncio - async def test_answer_web_app_query(self, bot, raw_bot, monkeypatch): - params = False + assert await bot.ban_chat_member(2, 32) + assert await bot.ban_chat_member(2, 32, until_date=until) + assert await bot.ban_chat_member(2, 32, until_date=1577887200) + assert await bot.ban_chat_member(2, 32, revoke_messages=True) + monkeypatch.delattr(bot.request, "post") - # For now just test that our internals pass the correct data + async def test_ban_chat_member_default_tz(self, monkeypatch, tz_bot): + until = dtm.datetime(2020, 1, 11, 16, 13) + until_timestamp = to_timestamp(until, tzinfo=tz_bot.defaults.tzinfo) async def make_assertion(url, request_data: RequestData, *args, **kwargs): - nonlocal params - params = request_data.parameters == { - "web_app_query_id": "12345", - "result": { - "title": "title", - "input_message_content": { - "message_text": "text", - }, - "type": InlineQueryResultType.ARTICLE, - "id": "1", - }, - } - web_app_msg = SentWebAppMessage("321").to_dict() - return web_app_msg + data = request_data.parameters + chat_id = data["chat_id"] == 2 + user_id = data["user_id"] == 32 + until_date = data.get("until_date", until_timestamp) == until_timestamp + return chat_id and user_id and until_date - # We test different result types more thoroughly for answer_inline_query, so we just - # use the one type here - result = InlineQueryResultArticle("1", "title", InputTextMessageContent("text")) - copied_result = copy.copy(result) + monkeypatch.setattr(tz_bot.request, "post", make_assertion) - ext_bot = bot - for bot in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with - # pytest.parametrize appears to be difficult ... - monkeypatch.setattr(bot.request, "post", make_assertion) - web_app_msg = await bot.answer_web_app_query("12345", result) - assert params, "something went wrong with passing arguments to the request" - assert isinstance(web_app_msg, SentWebAppMessage) - assert web_app_msg.inline_message_id == "321" + assert await tz_bot.ban_chat_member(2, 32) + assert await tz_bot.ban_chat_member(2, 32, until_date=until) + assert await tz_bot.ban_chat_member(2, 32, until_date=until_timestamp) - # 1) - # make sure that the results were not edited in-place - assert result == copied_result - assert ( - result.input_message_content.parse_mode - == copied_result.input_message_content.parse_mode - ) + async def test_ban_chat_sender_chat(self, monkeypatch, bot): + # For now, we just test that we pass the correct data to TG + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + chat_id = data["chat_id"] == 2 + sender_chat_id = data["sender_chat_id"] == 32 + return chat_id and sender_chat_id - @pytest.mark.asyncio - @pytest.mark.parametrize( - "default_bot", - [{"parse_mode": "Markdown", "disable_web_page_preview": True}], - indirect=True, - ) - @pytest.mark.parametrize( - "ilq_result,expected_params", - [ - ( - InlineQueryResultArticle("1", "title", InputTextMessageContent("text")), - { - "web_app_query_id": "12345", - "result": { - "title": "title", - "input_message_content": { - "message_text": "text", - "parse_mode": "Markdown", - "disable_web_page_preview": True, - }, - "type": InlineQueryResultType.ARTICLE, - "id": "1", - }, - }, - ), - ( - InlineQueryResultArticle( - "1", - "title", - InputTextMessageContent( - "text", parse_mode="HTML", disable_web_page_preview=False - ), - ), - { - "web_app_query_id": "12345", - "result": { - "title": "title", - "input_message_content": { - "message_text": "text", - "parse_mode": "HTML", - "disable_web_page_preview": False, - }, - "type": InlineQueryResultType.ARTICLE, - "id": "1", - }, - }, - ), - ( - InlineQueryResultArticle( - "1", - "title", - InputTextMessageContent( - "text", parse_mode=None, disable_web_page_preview="False" - ), - ), - { - "web_app_query_id": "12345", - "result": { - "title": "title", - "input_message_content": { - "message_text": "text", - "disable_web_page_preview": "False", - }, - "type": InlineQueryResultType.ARTICLE, - "id": "1", - }, - }, - ), - ], - ) - async def test_answer_web_app_query_defaults( - self, default_bot, ilq_result, expected_params, monkeypatch - ): - bot = default_bot - params = False - - # For now just test that our internals pass the correct data + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.ban_chat_sender_chat(2, 32) + monkeypatch.delattr(bot.request, "post") + # TODO: Needs improvement. + @pytest.mark.parametrize("only_if_banned", [True, False, None]) + async def test_unban_chat_member(self, monkeypatch, bot, only_if_banned): async def make_assertion(url, request_data: RequestData, *args, **kwargs): - nonlocal params - params = request_data.parameters == expected_params - web_app_msg = SentWebAppMessage("321").to_dict() - return web_app_msg + data = request_data.parameters + chat_id = data["chat_id"] == 2 + user_id = data["user_id"] == 32 + o_i_b = data.get("only_if_banned", None) == only_if_banned + return chat_id and user_id and o_i_b monkeypatch.setattr(bot.request, "post", make_assertion) - # We test different result types more thoroughly for answer_inline_query, so we just - # use the one type here - copied_result = copy.copy(ilq_result) + assert await bot.unban_chat_member(2, 32, only_if_banned=only_if_banned) - web_app_msg = await bot.answer_web_app_query("12345", ilq_result) - assert params, "something went wrong with passing arguments to the request" - assert isinstance(web_app_msg, SentWebAppMessage) - assert web_app_msg.inline_message_id == "321" + async def test_unban_chat_sender_chat(self, monkeypatch, bot): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.json_parameters + chat_id = data["chat_id"] == "2" + sender_chat_id = data["sender_chat_id"] == "32" + return chat_id and sender_chat_id - # make sure that the results were not edited in-place - assert ilq_result == copied_result - assert ( - ilq_result.input_message_content.parse_mode - == copied_result.input_message_content.parse_mode - ) + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.unban_chat_sender_chat(2, 32) - # TODO: Needs improvement. We need incoming inline query to test answer. - async def test_answer_inline_query(self, monkeypatch, bot, raw_bot): - # For now just test that our internals pass the correct data + async def test_set_chat_permissions(self, monkeypatch, bot, chat_permissions): async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "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"}, - }, - { - "title": "test_result", - "id": "123", - "type": "document", - "document_url": "https://raw.githubusercontent.com/python-telegram-bot" - "/logos/master/logo/png/ptb-logo_240.png", - "mime_type": "image/png", - "caption": "ptb_logo", - "input_message_content": {"message_text": "imc"}, - }, - ], - "next_offset": "42", - "switch_pm_parameter": "start_pm", - "inline_query_id": 1234, - "is_personal": True, - "switch_pm_text": "switch pm", - } + data = request_data.json_parameters + chat_id = data["chat_id"] == "2" + permissions = data["permissions"] == chat_permissions.to_json() + return chat_id and permissions - results = [ - InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), - InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), - InlineQueryResultDocument( - id="123", - document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" - "logo/png/ptb-logo_240.png", - title="test_result", - mime_type="image/png", - caption="ptb_logo", - input_message_content=InputMessageContentDWPP("imc"), - ), - ] + monkeypatch.setattr(bot.request, "post", make_assertion) - copied_results = copy.copy(results) - ext_bot = bot - for bot in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with - # pytest.parametrize appears to be difficult ... - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await 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", - ) + assert await bot.set_chat_permissions(2, chat_permissions) - # 1) - # make sure that the results were not edited in-place - assert results == copied_results - for idx, result in enumerate(results): - if hasattr(result, "parse_mode"): - assert result.parse_mode == copied_results[idx].parse_mode - if hasattr(result, "input_message_content"): - assert getattr(result.input_message_content, "parse_mode", None) == getattr( - copied_results[idx].input_message_content, "parse_mode", None - ) - assert getattr( - result.input_message_content, "disable_web_page_preview", None - ) == getattr( - copied_results[idx].input_message_content, "disable_web_page_preview", None - ) + async def test_set_chat_administrator_custom_title(self, monkeypatch, bot): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + chat_id = data["chat_id"] == 2 + user_id = data["user_id"] == 32 + custom_title = data["custom_title"] == "custom_title" + return chat_id and user_id and custom_title - monkeypatch.delattr(bot.request, "post") + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.set_chat_administrator_custom_title(2, 32, "custom_title") - async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot): + # TODO: Needs improvement. Need an incoming callbackquery to test + async def test_answer_callback_query(self, monkeypatch, bot): + # For now just test that our internals pass the correct data async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.parameters == { - "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"}, - }, - { - "title": "test_result", - "id": "123", - "type": "document", - "document_url": "https://raw.githubusercontent.com/" - "python-telegram-bot/logos/master/logo/png/" - "ptb-logo_240.png", - "mime_type": "image/png", - "caption": "ptb_logo", - "input_message_content": {"message_text": "imc"}, - }, - ], - "next_offset": "42", - "switch_pm_parameter": "start_pm", - "inline_query_id": 1234, - "is_personal": True, - "switch_pm_text": "switch pm", + "callback_query_id": 23, + "show_alert": True, + "url": "no_url", + "cache_time": 1, + "text": "answer", } monkeypatch.setattr(bot.request, "post", make_assertion) - results = [ - InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), - InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), - InlineQueryResultDocument( - id="123", - document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" - "logo/png/ptb-logo_240.png", - title="test_result", - mime_type="image/png", - caption="ptb_logo", - input_message_content=InputMessageContentDWPP("imc"), - ), - ] - copied_results = copy.copy(results) - assert await 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", + assert await bot.answer_callback_query( + 23, text="answer", show_alert=True, url="no_url", cache_time=1 ) - # make sure that the results were not edited in-place - assert results == copied_results - for idx, result in enumerate(results): - if hasattr(result, "parse_mode"): - assert result.parse_mode == copied_results[idx].parse_mode - if hasattr(result, "input_message_content"): - assert getattr(result.input_message_content, "parse_mode", None) == getattr( - copied_results[idx].input_message_content, "parse_mode", None - ) - assert getattr( - result.input_message_content, "disable_web_page_preview", None - ) == getattr( - copied_results[idx].input_message_content, "disable_web_page_preview", None - ) - @pytest.mark.parametrize( - "default_bot", - [{"parse_mode": "Markdown", "disable_web_page_preview": True}], - indirect=True, - ) - async def test_answer_inline_query_default_parse_mode(self, monkeypatch, default_bot): + @pytest.mark.parametrize("drop_pending_updates", [True, False]) + async def test_set_webhook_delete_webhook_drop_pending_updates( + self, bot, drop_pending_updates, monkeypatch + ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "cache_time": 300, - "results": [ - { - "title": "first", - "id": "11", - "type": "article", - "input_message_content": { - "message_text": "first", - "parse_mode": "Markdown", - "disable_web_page_preview": True, - }, - }, - { - "title": "second", - "id": "12", - "type": "article", - "input_message_content": { - "message_text": "second", - "disable_web_page_preview": True, - }, - }, - { - "title": "test_result", - "id": "123", - "type": "document", - "document_url": "https://raw.githubusercontent.com/" - "python-telegram-bot/logos/master/logo/png/" - "ptb-logo_240.png", - "mime_type": "image/png", - "caption": "ptb_logo", - "parse_mode": "Markdown", - "input_message_content": { - "message_text": "imc", - "disable_web_page_preview": True, - "parse_mode": "Markdown", - }, - }, + data = request_data.parameters + return data.get("drop_pending_updates") == drop_pending_updates + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.set_webhook("", drop_pending_updates=drop_pending_updates) + assert await bot.delete_webhook(drop_pending_updates=drop_pending_updates) + + @pytest.mark.parametrize("local_file", ["str", "Path", False]) + async def test_set_webhook_params(self, bot, monkeypatch, local_file): + # actually making calls to TG is done in + # test_set_webhook_get_webhook_info_and_delete_webhook. Sadly secret_token can't be tested + # there so we have this function \o/ + async def make_assertion(*args, **_): + kwargs = args[1] + + if local_file is False: + cert_assertion = ( + kwargs["certificate"].input_file_content + == data_file("sslcert.pem").read_bytes() + ) + else: + cert_assertion = data_file("sslcert.pem").as_uri() + + return ( + kwargs["url"] == "example.com" + and cert_assertion + and kwargs["max_connections"] == 7 + and kwargs["allowed_updates"] == ["messages"] + and kwargs["ip_address"] == "127.0.0.1" + and kwargs["drop_pending_updates"] + and kwargs["secret_token"] == "SoSecretToken" + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + + cert_path = data_file("sslcert.pem") + if local_file == "str": + certificate = str(cert_path) + elif local_file == "Path": + certificate = cert_path + else: + certificate = cert_path.read_bytes() + + assert await bot.set_webhook( + "example.com", + certificate, + 7, + ["messages"], + "127.0.0.1", + True, + "SoSecretToken", + ) + + # TODO: Needs improvement. Need incoming shipping queries to test + async def test_answer_shipping_query_ok(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "shipping_query_id": 1, + "ok": True, + "shipping_options": [ + {"title": "option1", "prices": [{"label": "price", "amount": 100}], "id": 1} ], - "next_offset": "42", - "switch_pm_parameter": "start_pm", - "inline_query_id": 1234, - "is_personal": True, - "switch_pm_text": "switch pm", } - monkeypatch.setattr(default_bot.request, "post", make_assertion) - results = [ - InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), - InlineQueryResultArticle("12", "second", InputMessageContentDWPP("second")), - InlineQueryResultDocument( - id="123", - document_url="https://raw.githubusercontent.com/python-telegram-bot/logos/master/" - "logo/png/ptb-logo_240.png", - title="test_result", - mime_type="image/png", - caption="ptb_logo", - input_message_content=InputTextMessageContent("imc"), - ), - ] + monkeypatch.setattr(bot.request, "post", make_assertion) + shipping_options = ShippingOption(1, "option1", [LabeledPrice("price", 100)]) + assert await bot.answer_shipping_query(1, True, shipping_options=[shipping_options]) + + async def test_answer_shipping_query_error_message(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "shipping_query_id": 1, + "error_message": "Not enough fish", + "ok": False, + } + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.answer_shipping_query(1, False, error_message="Not enough fish") + + # TODO: Needs improvement. Need incoming pre checkout queries to test + async def test_answer_pre_checkout_query_ok(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == {"pre_checkout_query_id": 1, "ok": True} + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.answer_pre_checkout_query(1, True) + + async def test_answer_pre_checkout_query_error_message(self, monkeypatch, bot): + # For now just test that our internals pass the correct data + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters == { + "pre_checkout_query_id": 1, + "error_message": "Not enough fish", + "ok": False, + } + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.answer_pre_checkout_query(1, False, error_message="Not enough fish") + + async def test_restrict_chat_member_default_tz( + self, monkeypatch, tz_bot, channel_id, chat_permissions + ): + until = dtm.datetime(2020, 1, 11, 16, 13) + until_timestamp = to_timestamp(until, tzinfo=tz_bot.defaults.tzinfo) + + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters.get("until_date", until_timestamp) == until_timestamp + + monkeypatch.setattr(tz_bot.request, "post", make_assertion) + + assert await tz_bot.restrict_chat_member(channel_id, 95205500, chat_permissions) + assert await tz_bot.restrict_chat_member( + channel_id, 95205500, chat_permissions, until_date=until + ) + assert await tz_bot.restrict_chat_member( + channel_id, 95205500, chat_permissions, until_date=until_timestamp + ) + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_set_chat_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("photo") == expected + else: + test_flag = isinstance(data.get("photo"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.set_chat_photo(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + + async def test_timeout_propagation_explicit(self, monkeypatch, bot, chat_id): + # Use BaseException that's not a subclass of Exception such that + # OkException should not be caught anywhere + class OkException(BaseException): + pass + + timeout = 42 + + async def do_request(*args, **kwargs): + obj = kwargs.get("read_timeout") + if obj == timeout: + raise OkException + + return 200, b'{"ok": true, "result": []}' + + monkeypatch.setattr(bot.request, "do_request", do_request) + + # Test file uploading + with pytest.raises(OkException): + await bot.send_photo( + chat_id, data_file("telegram.jpg").open("rb"), read_timeout=timeout + ) + + # Test JSON submission + with pytest.raises(OkException): + await bot.get_chat_administrators(chat_id, read_timeout=timeout) + + async def test_timeout_propagation_implicit(self, monkeypatch, bot, chat_id): + # Use BaseException that's not a subclass of Exception such that + # OkException should not be caught anywhere + class OkException(BaseException): + pass + + async def do_request(*args, **kwargs): + obj = kwargs.get("write_timeout") + if obj == 20: + raise OkException + + return 200, b'{"ok": true, "result": []}' + + monkeypatch.setattr(bot.request, "do_request", do_request) + + # Test file uploading + with pytest.raises(OkException): + await bot.send_photo(chat_id, data_file("telegram.jpg").open("rb")) + + async def test_log_out(self, monkeypatch, bot): + # We don't actually make a request as to not break the test setup + async def assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters == {} and url.split("/")[-1] == "logOut" + + monkeypatch.setattr(bot.request, "post", assertion) + + assert await bot.log_out() + + async def test_close(self, monkeypatch, bot): + # We don't actually make a request as to not break the test setup + async def assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters == {} and url.split("/")[-1] == "close" + + monkeypatch.setattr(bot.request, "post", assertion) + + assert await bot.close() + + @pytest.mark.parametrize("json_keyboard", [True, False]) + @pytest.mark.parametrize("caption", ["Test", "", None]) + async def test_copy_message( + self, monkeypatch, bot, chat_id, media_message, json_keyboard, caption + ): + keyboard = InlineKeyboardMarkup( + [[InlineKeyboardButton(text="test", callback_data="test2")]] + ) + + async def post(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + if not all( + [ + data["chat_id"] == chat_id, + data["from_chat_id"] == chat_id, + data["message_id"] == media_message.message_id, + data.get("caption") == caption, + data["parse_mode"] == ParseMode.HTML, + data["reply_to_message_id"] == media_message.message_id, + data["reply_markup"] == keyboard.to_json() + if json_keyboard + else keyboard.to_dict(), + data["disable_notification"] is True, + data["caption_entities"] + == [MessageEntity(MessageEntity.BOLD, 0, 4).to_dict()], + data["protect_content"] is True, + data["message_thread_id"] == 1, + ] + ): + pytest.fail("I got wrong parameters in post") + return data + + monkeypatch.setattr(bot.request, "post", post) + await bot.copy_message( + chat_id, + from_chat_id=chat_id, + message_id=media_message.message_id, + caption=caption, + caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 4)], + parse_mode=ParseMode.HTML, + reply_to_message_id=media_message.message_id, + reply_markup=keyboard.to_json() if json_keyboard else keyboard, + disable_notification=True, + protect_content=True, + message_thread_id=1, + ) + + # TODO: Needs improvement. We need incoming inline query to test answer. + async def test_replace_callback_data_answer_inline_query(self, monkeypatch, cdc_bot, chat_id): + bot = cdc_bot + + # For now just test that our internals pass the correct data + async def make_assertion( + endpoint, + data=None, + *args, + **kwargs, + ): + inline_keyboard = data["results"][0]["reply_markup"].inline_keyboard + assertion_1 = inline_keyboard[0][1] == no_replace_button + assertion_2 = inline_keyboard[0][0] != replace_button + keyboard, button = ( + inline_keyboard[0][0].callback_data[:32], + inline_keyboard[0][0].callback_data[32:], + ) + assertion_3 = ( + bot.callback_data_cache._keyboard_data[keyboard].button_data[button] + == "replace_test" + ) + assertion_4 = data["results"][1].reply_markup is None + return assertion_1 and assertion_2 and assertion_3 and assertion_4 + + try: + replace_button = InlineKeyboardButton(text="replace", callback_data="replace_test") + no_replace_button = InlineKeyboardButton( + text="no_replace", url="http://python-telegram-bot.org/" + ) + reply_markup = InlineKeyboardMarkup.from_row( + [ + replace_button, + no_replace_button, + ] + ) + + bot.username # call this here so `bot.get_me()` won't be called after mocking + monkeypatch.setattr(bot, "_post", make_assertion) + results = [ + InlineQueryResultArticle( + "11", "first", InputTextMessageContent("first"), reply_markup=reply_markup + ), + InlineQueryResultVoice( + "22", + "https://python-telegram-bot.org/static/testfiles/telegram.ogg", + title="second", + ), + ] + + assert await bot.answer_inline_query(chat_id, results=results) + + finally: + bot.callback_data_cache.clear_callback_data() + bot.callback_data_cache.clear_callback_queries() + + @bot_methods() + def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): + camel_case_name = to_camel_case(bot_method_name) + camel_case_function = getattr(bot_class, camel_case_name, False) + assert camel_case_function is not False, f"{camel_case_name} not found" + assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}" + + @bot_methods() + def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): + """Check that all bot methods are defined as async def ...""" + # not islower() skips the camelcase aliases + if not bot_method_name.islower(): + return + # unfortunately `inspect.iscoroutinefunction` doesn't do the trick directly, + # as the @_log decorator interferes + source = "".join(inspect.getsourcelines(bot_method)[0]) + assert ( + f"async def {bot_method_name}" in source + ), f"{bot_method_name} should be a coroutine function" + + @bot_methods() + def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): + """Check that all bot methods have `api_kwargs` and timeout params.""" + param_names = inspect.signature(bot_method).parameters.keys() + assert ( + "pool_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `pool_timeout`" + assert ( + "read_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `read_timeout`" + assert ( + "connect_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `connect_timeout`" + assert ( + "write_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `write_timeout`" + assert ( + "api_kwargs" in param_names + ), f"{bot_method_name} is missing the parameter `api_kwargs`" + + if bot_class is ExtBot and bot_method_name.replace("_", "").lower() != "getupdates": + assert ( + "rate_limit_args" in param_names + ), f"{bot_method_name} of ExtBot is missing the parameter `rate_limit_args`" - copied_results = copy.copy(results) - assert await default_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", + +class TestBotReq: + """ + Most are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot + + Behavior for init of ExtBot with missing optional dependency cachetools (for CallbackDataCache) + is tested in `test_callbackdatacache` + """ + + @staticmethod + def localize(dt, tzinfo): + try: + return tzinfo.localize(dt) + except AttributeError: + # We get here if tzinfo is not a pytz timezone but a datetime.timezone class + # This test class should never be run in if pytz is not installed, we intentionally + # fail if this branch is ever reached. + sys.exit(1) + + async def test_forward_message(self, bot, chat_id, message): + forward_message = await bot.forward_message( + chat_id, from_chat_id=chat_id, message_id=message.message_id ) - # make sure that the results were not edited in-place - assert results == copied_results - for idx, result in enumerate(results): - if hasattr(result, "parse_mode"): - assert result.parse_mode == copied_results[idx].parse_mode - if hasattr(result, "input_message_content"): - assert getattr(result.input_message_content, "parse_mode", None) == getattr( - copied_results[idx].input_message_content, "parse_mode", None - ) - assert getattr( - result.input_message_content, "disable_web_page_preview", None - ) == getattr( - copied_results[idx].input_message_content, "disable_web_page_preview", None - ) - async def test_answer_inline_query_current_offset_error(self, bot, inline_results): - with pytest.raises(ValueError, match=("`current_offset` and `next_offset`")): - await bot.answer_inline_query( - 1234, results=inline_results, next_offset=42, current_offset=51 - ) + assert forward_message.text == message.text + assert forward_message.forward_from.username == message.from_user.username + assert isinstance(forward_message.forward_date, dtm.datetime) - @pytest.mark.parametrize( - "current_offset,num_results,id_offset,expected_next_offset", - [ - ("", InlineQueryLimit.RESULTS, 1, 1), - (1, InlineQueryLimit.RESULTS, 51, 2), - (5, 3, 251, ""), - ], - ) - async def test_answer_inline_query_current_offset_1( - self, - monkeypatch, - bot, - inline_results, - current_offset, - num_results, - id_offset, - expected_next_offset, - ): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - results = data["results"] - length_matches = len(results) == num_results - ids_match = all(int(res["id"]) == id_offset + i for i, res in enumerate(results)) - next_offset_matches = data["next_offset"] == str(expected_next_offset) - return length_matches and ids_match and next_offset_matches + async def test_forward_protected_message(self, bot, message, chat_id): + to_forward_protected = await bot.send_message( + chat_id, "cant forward me", protect_content=True + ) + assert to_forward_protected.has_protected_content - monkeypatch.setattr(bot.request, "post", make_assertion) + with pytest.raises(BadRequest, match="can't be forwarded"): + await to_forward_protected.forward(chat_id) - assert await bot.answer_inline_query( - 1234, results=inline_results, current_offset=current_offset + to_forward_unprotected = await bot.send_message( + chat_id, "forward me", protect_content=False + ) + assert not to_forward_unprotected.has_protected_content + forwarded_but_now_protected = await to_forward_unprotected.forward( + chat_id, protect_content=True ) + assert forwarded_but_now_protected.has_protected_content + with pytest.raises(BadRequest, match="can't be forwarded"): + await forwarded_but_now_protected.forward(chat_id) - async def test_answer_inline_query_current_offset_2(self, monkeypatch, bot, inline_results): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - results = data["results"] - length_matches = len(results) == InlineQueryLimit.RESULTS - ids_match = all(int(res["id"]) == 1 + i for i, res in enumerate(results)) - next_offset_matches = data["next_offset"] == "1" - return length_matches and ids_match and next_offset_matches + async def test_delete_message(self, bot, chat_id): + message = await bot.send_message(chat_id, text="will be deleted") + await asyncio.sleep(2) - monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.delete_message(chat_id=chat_id, message_id=message.message_id) is True - assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) + async def test_delete_message_old_message(self, bot, chat_id): + with pytest.raises(BadRequest): + # Considering that the first message is old enough + await bot.delete_message(chat_id=chat_id, message_id=1) - inline_results = inline_results[:30] + # send_photo, send_audio, send_document, send_sticker, send_video, send_voice, send_video_note, + # send_media_group and send_animation are tested in their respective test modules. No need to + # duplicate here. - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - results = data["results"] - length_matches = len(results) == 30 - ids_match = all(int(res["id"]) == 1 + i for i, res in enumerate(results)) - next_offset_matches = data["next_offset"] == "" - return length_matches and ids_match and next_offset_matches + async def test_send_venue(self, bot, chat_id): + longitude = -46.788279 + latitude = -23.691288 + title = "title" + address = "address" + foursquare_id = "foursquare id" + foursquare_type = "foursquare type" + google_place_id = "google_place id" + google_place_type = "google_place type" - monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_venue( + chat_id=chat_id, + title=title, + address=address, + latitude=latitude, + longitude=longitude, + foursquare_id=foursquare_id, + foursquare_type=foursquare_type, + protect_content=True, + ) - assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) + 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 + assert message.venue.foursquare_id == foursquare_id + assert message.venue.foursquare_type == foursquare_type + assert message.venue.google_place_id is None + assert message.venue.google_place_type is None + assert message.has_protected_content - async def test_answer_inline_query_current_offset_callback(self, monkeypatch, bot, caplog): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - results = data["results"] - length = len(results) == 5 - ids = all(int(res["id"]) == 6 + i for i, res in enumerate(results)) - next_offset = data["next_offset"] == "2" - return length and ids and next_offset + message = await bot.send_venue( + chat_id=chat_id, + title=title, + address=address, + latitude=latitude, + longitude=longitude, + google_place_id=google_place_id, + google_place_type=google_place_type, + protect_content=True, + ) - monkeypatch.setattr(bot.request, "post", make_assertion) + 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 + assert message.venue.google_place_id == google_place_id + assert message.venue.google_place_type == google_place_type + assert message.venue.foursquare_id is None + assert message.venue.foursquare_type is None + assert message.has_protected_content - assert await bot.answer_inline_query( - 1234, results=inline_results_callback, current_offset=1 + async def test_send_contact(self, bot, chat_id): + phone_number = "+11234567890" + first_name = "Leandro" + last_name = "Toledo" + message = await bot.send_contact( + chat_id=chat_id, + phone_number=phone_number, + first_name=first_name, + last_name=last_name, + protect_content=True, + ) + + assert message.contact + assert message.contact.phone_number == phone_number + assert message.contact.first_name == first_name + assert message.contact.last_name == last_name + assert message.has_protected_content + + # TODO: Add bot to group to test polls too + @pytest.mark.parametrize( + "reply_markup", + [ + None, + InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="data") + ), + InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="data") + ).to_dict(), + ], + ) + async def test_send_and_stop_poll(self, bot, super_group_id, reply_markup): + question = "Is this a test?" + answers = ["Yes", "No", "Maybe"] + message = await bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + is_anonymous=False, + allows_multiple_answers=True, + read_timeout=60, + protect_content=True, ) - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - results = data["results"] - length = results == [] - next_offset = data["next_offset"] == "" - return length and next_offset - - monkeypatch.setattr(bot.request, "post", make_assertion) + assert message.poll + assert message.poll.question == question + assert message.poll.options[0].text == answers[0] + assert message.poll.options[1].text == answers[1] + assert message.poll.options[2].text == answers[2] + assert not message.poll.is_anonymous + assert message.poll.allows_multiple_answers + assert not message.poll.is_closed + assert message.poll.type == Poll.REGULAR + assert message.has_protected_content - assert await bot.answer_inline_query( - 1234, results=inline_results_callback, current_offset=6 + # Since only the poll and not the complete message is returned, we can't check that the + # reply_markup is correct. So we just test that sending doesn't give an error. + poll = await bot.stop_poll( + chat_id=super_group_id, + message_id=message.message_id, + reply_markup=reply_markup, + read_timeout=60, ) + assert isinstance(poll, Poll) + assert poll.is_closed + assert poll.options[0].text == answers[0] + assert poll.options[0].voter_count == 0 + assert poll.options[1].text == answers[1] + assert poll.options[1].voter_count == 0 + assert poll.options[2].text == answers[2] + assert poll.options[2].voter_count == 0 + assert poll.question == question + assert poll.total_voter_count == 0 - @pytest.mark.flaky(3, 1) - async def test_get_user_profile_photos(self, bot, chat_id): - user_profile_photos = await bot.get_user_profile_photos(chat_id) - - assert user_profile_photos.photos[0][0].file_size == 5403 - - @pytest.mark.flaky(3, 1) - async def test_get_one_user_profile_photo(self, bot, chat_id): - user_profile_photos = await bot.get_user_profile_photos(chat_id, offset=0, limit=1) - assert user_profile_photos.photos[0][0].file_size == 5403 - - # get_file is tested multiple times in the test_*media* modules. - # Here we only test the behaviour for bot apis in local mode - async def test_get_file_local_mode(self, bot, monkeypatch): - path = str(data_file("game.gif")) + explanation = "[Here is a link](https://google.com)" + explanation_entities = [ + MessageEntity(MessageEntity.TEXT_LINK, 0, 14, url="https://google.com") + ] + message_quiz = await bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation, + explanation_parse_mode=ParseMode.MARKDOWN_V2, + ) + assert message_quiz.poll.correct_option_id == 2 + assert message_quiz.poll.type == Poll.QUIZ + assert message_quiz.poll.is_closed + assert message_quiz.poll.explanation == "Here is a link" + assert message_quiz.poll.explanation_entities == tuple(explanation_entities) - async def _post(*args, **kwargs): - return { - "file_id": None, - "file_unique_id": None, - "file_size": None, - "file_path": path, - } + @pytest.mark.parametrize( + ["open_period", "close_date"], [(5, None), (None, True)], ids=["open_period", "close_date"] + ) + async def test_send_open_period(self, bot, super_group_id, open_period, close_date): + question = "Is this a test?" + answers = ["Yes", "No", "Maybe"] + reply_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="data") + ) - monkeypatch.setattr(bot, "_post", _post) + if close_date: + close_date = dtm.datetime.utcnow() + dtm.timedelta(seconds=5.05) - resulting_path = (await bot.get_file("file_id")).file_path - assert bot.token not in resulting_path - assert resulting_path == path - monkeypatch.delattr(bot, "_post") + message = await bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + is_anonymous=False, + allows_multiple_answers=True, + read_timeout=60, + open_period=open_period, + close_date=close_date, + ) + await asyncio.sleep(5.1) + new_message = await bot.edit_message_reply_markup( + chat_id=super_group_id, + message_id=message.message_id, + reply_markup=reply_markup, + read_timeout=60, + ) + assert new_message.poll.id == message.poll.id + assert new_message.poll.is_closed - # TODO: Needs improvement. No feasible way to test until bots can add members. - async def test_ban_chat_member(self, monkeypatch, bot): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - chat_id = data["chat_id"] == "2" - user_id = data["user_id"] == "32" - until_date = data.get("until_date", "1577887200") == "1577887200" - revoke_msgs = data.get("revoke_messages", "true") == "true" - return chat_id and user_id and until_date and revoke_msgs + async def test_send_close_date_default_tz(self, tz_bot, super_group_id): + question = "Is this a test?" + answers = ["Yes", "No", "Maybe"] + reply_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="data") + ) - monkeypatch.setattr(bot.request, "post", make_assertion) - until = from_timestamp(1577887200) + aware_close_date = dtm.datetime.now(tz=tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=5) + close_date = aware_close_date.replace(tzinfo=None) - assert await bot.ban_chat_member(2, 32) - assert await bot.ban_chat_member(2, 32, until_date=until) - assert await bot.ban_chat_member(2, 32, until_date=1577887200) - assert await bot.ban_chat_member(2, 32, revoke_messages=True) - monkeypatch.delattr(bot.request, "post") + msg = await tz_bot.send_poll( # The timezone returned from this is always converted to UTC + chat_id=super_group_id, + question=question, + options=answers, + close_date=close_date, + read_timeout=60, + ) + msg.poll._unfreeze() + # Sometimes there can be a few seconds delay, so don't let the test fail due to that- + msg.poll.close_date = msg.poll.close_date.astimezone(aware_close_date.tzinfo) + assert abs(msg.poll.close_date - aware_close_date) <= dtm.timedelta(seconds=5) - async def test_ban_chat_member_default_tz(self, monkeypatch, tz_bot): - until = dtm.datetime(2020, 1, 11, 16, 13) - until_timestamp = to_timestamp(until, tzinfo=tz_bot.defaults.tzinfo) + await asyncio.sleep(5.1) - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - chat_id = data["chat_id"] == 2 - user_id = data["user_id"] == 32 - until_date = data.get("until_date", until_timestamp) == until_timestamp - return chat_id and user_id and until_date + new_message = await tz_bot.edit_message_reply_markup( + chat_id=super_group_id, + message_id=msg.message_id, + reply_markup=reply_markup, + read_timeout=60, + ) + assert new_message.poll.id == msg.poll.id + assert new_message.poll.is_closed - monkeypatch.setattr(tz_bot.request, "post", make_assertion) + async def test_send_poll_explanation_entities(self, bot, chat_id): + test_string = "Italic Bold Code" + entities = [ + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.ITALIC, 7, 4), + MessageEntity(MessageEntity.ITALIC, 12, 4), + ] + message = await bot.send_poll( + chat_id, + "question", + options=["a", "b"], + correct_option_id=0, + type=Poll.QUIZ, + explanation=test_string, + explanation_entities=entities, + ) - assert await tz_bot.ban_chat_member(2, 32) - assert await tz_bot.ban_chat_member(2, 32, until_date=until) - assert await tz_bot.ban_chat_member(2, 32, until_date=until_timestamp) + assert message.poll.explanation == test_string + assert message.poll.explanation_entities == tuple(entities) - async def test_ban_chat_sender_chat(self, monkeypatch, bot): - # For now, we just test that we pass the correct data to TG - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - chat_id = data["chat_id"] == 2 - sender_chat_id = data["sender_chat_id"] == 32 - return chat_id and sender_chat_id + @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) + async def test_send_poll_default_parse_mode(self, default_bot, super_group_id): + explanation = "Italic Bold Code" + explanation_markdown = "_Italic_ *Bold* `Code`" + question = "Is this a test?" + answers = ["Yes", "No", "Maybe"] - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.ban_chat_sender_chat(2, 32) - monkeypatch.delattr(bot.request, "post") + message = await default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + ) + assert message.poll.explanation == explanation + assert message.poll.explanation_entities == ( + MessageEntity(MessageEntity.ITALIC, 0, 6), + MessageEntity(MessageEntity.BOLD, 7, 4), + MessageEntity(MessageEntity.CODE, 12, 4), + ) - # TODO: Needs improvement. - @pytest.mark.parametrize("only_if_banned", [True, False, None]) - async def test_unban_chat_member(self, monkeypatch, bot, only_if_banned): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - chat_id = data["chat_id"] == 2 - user_id = data["user_id"] == 32 - o_i_b = data.get("only_if_banned", None) == only_if_banned - return chat_id and user_id and o_i_b + message = await default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + explanation_parse_mode=None, + ) + assert message.poll.explanation == explanation_markdown + assert message.poll.explanation_entities == () - monkeypatch.setattr(bot.request, "post", make_assertion) + message = await default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + explanation_parse_mode="HTML", + ) + assert message.poll.explanation == explanation_markdown + assert message.poll.explanation_entities == () - assert await bot.unban_chat_member(2, 32, only_if_banned=only_if_banned) + @pytest.mark.parametrize( + "default_bot,custom", + [ + ({"allow_sending_without_reply": True}, None), + ({"allow_sending_without_reply": False}, None), + ({"allow_sending_without_reply": False}, True), + ], + indirect=["default_bot"], + ) + async def test_send_poll_default_allow_sending_without_reply( + self, default_bot, chat_id, custom + ): + question = "Is this a test?" + answers = ["Yes", "No", "Maybe"] + reply_to_message = await default_bot.send_message(chat_id, "test") + await reply_to_message.delete() + if custom is not None: + message = await default_bot.send_poll( + chat_id, + question=question, + options=answers, + allow_sending_without_reply=custom, + reply_to_message_id=reply_to_message.message_id, + ) + assert message.reply_to_message is None + elif default_bot.defaults.allow_sending_without_reply: + message = await default_bot.send_poll( + chat_id, + question=question, + options=answers, + reply_to_message_id=reply_to_message.message_id, + ) + assert message.reply_to_message is None + else: + with pytest.raises(BadRequest, match="message not found"): + await default_bot.send_poll( + chat_id, + question=question, + options=answers, + reply_to_message_id=reply_to_message.message_id, + ) - async def test_unban_chat_sender_chat(self, monkeypatch, bot): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - chat_id = data["chat_id"] == "2" - sender_chat_id = data["sender_chat_id"] == "32" - return chat_id and sender_chat_id + @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) + async def test_send_poll_default_protect_content(self, chat_id, default_bot): + protected_poll = await default_bot.send_poll(chat_id, "Test", ["1", "2"]) + assert protected_poll.has_protected_content + unprotect_poll = await default_bot.send_poll( + chat_id, "test", ["1", "2"], protect_content=False + ) + assert not unprotect_poll.has_protected_content - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.unban_chat_sender_chat(2, 32) + @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI + [None]) + async def test_send_dice(self, bot, chat_id, emoji): + message = await bot.send_dice(chat_id, emoji=emoji, protect_content=True) - async def test_set_chat_permissions(self, monkeypatch, bot, chat_permissions): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - chat_id = data["chat_id"] == "2" - permissions = data["permissions"] == chat_permissions.to_json() - return chat_id and permissions + assert message.dice + assert message.has_protected_content + if emoji is None: + assert message.dice.emoji == Dice.DICE + else: + assert message.dice.emoji == emoji - monkeypatch.setattr(bot.request, "post", make_assertion) + @pytest.mark.parametrize( + "default_bot,custom", + [ + ({"allow_sending_without_reply": True}, None), + ({"allow_sending_without_reply": False}, None), + ({"allow_sending_without_reply": False}, True), + ], + indirect=["default_bot"], + ) + async def test_send_dice_default_allow_sending_without_reply( + self, default_bot, chat_id, custom + ): + reply_to_message = await default_bot.send_message(chat_id, "test") + await reply_to_message.delete() + if custom is not None: + message = await default_bot.send_dice( + chat_id, + allow_sending_without_reply=custom, + reply_to_message_id=reply_to_message.message_id, + ) + assert message.reply_to_message is None + elif default_bot.defaults.allow_sending_without_reply: + message = await default_bot.send_dice( + chat_id, + reply_to_message_id=reply_to_message.message_id, + ) + assert message.reply_to_message is None + else: + with pytest.raises(BadRequest, match="message not found"): + await default_bot.send_dice( + chat_id, reply_to_message_id=reply_to_message.message_id + ) - assert await bot.set_chat_permissions(2, chat_permissions) + @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) + async def test_send_dice_default_protect_content(self, chat_id, default_bot): + protected_dice = await default_bot.send_dice(chat_id) + assert protected_dice.has_protected_content + unprotected_dice = await default_bot.send_dice(chat_id, protect_content=False) + assert not unprotected_dice.has_protected_content - async def test_set_chat_administrator_custom_title(self, monkeypatch, bot): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - chat_id = data["chat_id"] == 2 - user_id = data["user_id"] == 32 - custom_title = data["custom_title"] == "custom_title" - return chat_id and user_id and custom_title + @pytest.mark.parametrize("chat_action", list(ChatAction)) + async def test_send_chat_action(self, bot, chat_id, chat_action): + assert await bot.send_chat_action(chat_id, chat_action) - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.set_chat_administrator_custom_title(2, 32, "custom_title") + async def test_wrong_chat_action(self, bot, chat_id): + with pytest.raises(BadRequest, match="Wrong parameter action"): + await bot.send_chat_action(chat_id, "unknown action") - # TODO: Needs improvement. Need an incoming callbackquery to test - async def test_answer_callback_query(self, monkeypatch, bot): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "callback_query_id": 23, - "show_alert": True, - "url": "no_url", - "cache_time": 1, - "text": "answer", - } + async def test_answer_inline_query_current_offset_error(self, bot, inline_results): + with pytest.raises(ValueError, match=("`current_offset` and `next_offset`")): + await bot.answer_inline_query( + 1234, results=inline_results, next_offset=42, current_offset=51 + ) - monkeypatch.setattr(bot.request, "post", make_assertion) + async def test_get_user_profile_photos(self, bot, chat_id): + user_profile_photos = await bot.get_user_profile_photos(chat_id) + assert user_profile_photos.photos[0][0].file_size == 5403 - assert await bot.answer_callback_query( - 23, text="answer", show_alert=True, url="no_url", cache_time=1 - ) + async def test_get_one_user_profile_photo(self, bot, chat_id): + user_profile_photos = await bot.get_user_profile_photos(chat_id, offset=0, limit=1) + assert user_profile_photos.photos[0][0].file_size == 5403 - @pytest.mark.flaky(3, 1) async def test_edit_message_text(self, bot, message): message = await bot.edit_message_text( text="new_text", @@ -1601,7 +1947,6 @@ async def test_edit_message_text(self, bot, message): assert message.text == "new_text" - @pytest.mark.flaky(3, 1) async def test_edit_message_text_entities(self, bot, message): test_string = "Italic Bold Code" entities = [ @@ -1619,7 +1964,6 @@ async def test_edit_message_text_entities(self, bot, message): assert message.text == test_string assert message.entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_edit_message_text_default_parse_mode(self, default_bot, message): test_string = "Italic Bold Code" @@ -1664,7 +2008,6 @@ async def test_edit_message_text_default_parse_mode(self, default_bot, message): async def test_edit_message_text_inline(self): pass - @pytest.mark.flaky(3, 1) async def test_edit_message_caption(self, bot, media_message): message = await bot.edit_message_caption( caption="new_caption", @@ -1674,7 +2017,6 @@ async def test_edit_message_caption(self, bot, media_message): assert message.caption == "new_caption" - @pytest.mark.flaky(3, 1) async def test_edit_message_caption_entities(self, bot, media_message): test_string = "Italic Bold Code" entities = [ @@ -1694,7 +2036,6 @@ async def test_edit_message_caption_entities(self, bot, media_message): # edit_message_media is tested in test_inputmedia - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_edit_message_caption_default_parse_mode(self, default_bot, media_message): test_string = "Italic Bold Code" @@ -1731,7 +2072,6 @@ async def test_edit_message_caption_default_parse_mode(self, default_bot, media_ assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) async def test_edit_message_caption_with_parse_mode(self, bot, media_message): message = await bot.edit_message_caption( caption="new *caption*", @@ -1746,7 +2086,6 @@ async def test_edit_message_caption_with_parse_mode(self, bot, media_message): async def test_edit_message_caption_inline(self): pass - @pytest.mark.flaky(3, 1) async def test_edit_reply_markup(self, bot, message): new_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="test", callback_data="1")]]) message = await bot.edit_message_reply_markup( @@ -1760,7 +2099,6 @@ async def test_edit_reply_markup_inline(self): pass # TODO: Actually send updates to the test bot so this can be tested properly - @pytest.mark.flaky(3, 1) async def test_get_updates(self, bot): await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed updates = await bot.get_updates(timeout=1) @@ -1806,7 +2144,6 @@ async def post(*args, **kwargs): bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("use_ip", [True, False]) # local file path as file_input is tested below in test_set_webhook_params @pytest.mark.parametrize("file_input", ["bytes", "file_handle"]) @@ -1844,66 +2181,6 @@ async def test_set_webhook_get_webhook_info_and_delete_webhook(self, bot, use_ip assert info.ip_address is None assert info.has_custom_certificate is False - @pytest.mark.parametrize("drop_pending_updates", [True, False]) - async def test_set_webhook_delete_webhook_drop_pending_updates( - self, bot, drop_pending_updates, monkeypatch - ): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - return data.get("drop_pending_updates") == drop_pending_updates - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.set_webhook("", drop_pending_updates=drop_pending_updates) - assert await bot.delete_webhook(drop_pending_updates=drop_pending_updates) - - @pytest.mark.parametrize("local_file", ["str", "Path", False]) - async def test_set_webhook_params(self, bot, monkeypatch, local_file): - # actually making calls to TG is done in - # test_set_webhook_get_webhook_info_and_delete_webhook. Sadly secret_token can't be tested - # there so we have this function \o/ - async def make_assertion(*args, **_): - kwargs = args[1] - - if local_file is False: - cert_assertion = ( - kwargs["certificate"].input_file_content - == data_file("sslcert.pem").read_bytes() - ) - else: - cert_assertion = data_file("sslcert.pem").as_uri() - - return ( - kwargs["url"] == "example.com" - and cert_assertion - and kwargs["max_connections"] == 7 - and kwargs["allowed_updates"] == ["messages"] - and kwargs["ip_address"] == "127.0.0.1" - and kwargs["drop_pending_updates"] - and kwargs["secret_token"] == "SoSecretToken" - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - - cert_path = data_file("sslcert.pem") - if local_file == "str": - certificate = str(cert_path) - elif local_file == "Path": - certificate = cert_path - else: - certificate = cert_path.read_bytes() - - assert await bot.set_webhook( - "example.com", - certificate, - 7, - ["messages"], - "127.0.0.1", - True, - "SoSecretToken", - ) - - @pytest.mark.flaky(3, 1) async def test_leave_chat(self, bot): with pytest.raises(BadRequest, match="Chat not found"): await bot.leave_chat(-123456) @@ -1911,7 +2188,6 @@ async def test_leave_chat(self, bot): with pytest.raises(NetworkError, match="Chat not found"): await bot.leave_chat(-123456) - @pytest.mark.flaky(3, 1) async def test_get_chat(self, bot, super_group_id): chat = await bot.get_chat(super_group_id) @@ -1919,7 +2195,6 @@ async def test_get_chat(self, bot, super_group_id): assert chat.title == f">>> telegram.Bot(test) @{bot.username}" assert chat.id == int(super_group_id) - @pytest.mark.flaky(3, 1) async def test_get_chat_administrators(self, bot, channel_id): admins = await bot.get_chat_administrators(channel_id) assert isinstance(admins, tuple) @@ -1927,13 +2202,11 @@ async def test_get_chat_administrators(self, bot, channel_id): for a in admins: assert a.status in ("administrator", "creator") - @pytest.mark.flaky(3, 1) async def test_get_chat_member_count(self, bot, channel_id): count = await bot.get_chat_member_count(channel_id) assert isinstance(count, int) assert count > 3 - @pytest.mark.flaky(3, 1) async def test_get_chat_member(self, bot, channel_id, chat_id): chat_member = await bot.get_chat_member(channel_id, chat_id) @@ -1949,7 +2222,6 @@ async def test_set_chat_sticker_set(self): async def test_delete_chat_sticker_set(self): pass - @pytest.mark.flaky(3, 1) async def test_send_game(self, bot, chat_id): game_short_name = "test_game" message = await bot.send_game(chat_id, game_short_name, protect_content=True) @@ -1964,7 +2236,6 @@ async def test_send_game(self, bot, chat_id): assert message.game.photo[0].file_size in [851, 4928, 850] assert message.has_protected_content - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -2001,7 +2272,6 @@ async def test_send_game_default_allow_sending_without_reply( chat_id, game_short_name, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,val", [({"protect_content": True}, True), ({"protect_content": False}, None)], @@ -2102,58 +2372,8 @@ async def test_get_game_high_scores(self, bot, chat_id): # We assume that the other game score tests ran within 20 sec assert high_scores[0].score == BASE_GAME_SCORE - 10 - # send_invoice and create_invoice_link is tested in test_invoice - - # TODO: Needs improvement. Need incoming shipping queries to test - async def test_answer_shipping_query_ok(self, monkeypatch, bot): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "shipping_query_id": 1, - "ok": True, - "shipping_options": [ - {"title": "option1", "prices": [{"label": "price", "amount": 100}], "id": 1} - ], - } - - monkeypatch.setattr(bot.request, "post", make_assertion) - shipping_options = ShippingOption(1, "option1", [LabeledPrice("price", 100)]) - assert await bot.answer_shipping_query(1, True, shipping_options=[shipping_options]) - - async def test_answer_shipping_query_error_message(self, monkeypatch, bot): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "shipping_query_id": 1, - "error_message": "Not enough fish", - "ok": False, - } - - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.answer_shipping_query(1, False, error_message="Not enough fish") - - # TODO: Needs improvement. Need incoming pre checkout queries to test - async def test_answer_pre_checkout_query_ok(self, monkeypatch, bot): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == {"pre_checkout_query_id": 1, "ok": True} - - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.answer_pre_checkout_query(1, True) - - async def test_answer_pre_checkout_query_error_message(self, monkeypatch, bot): - # For now just test that our internals pass the correct data - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters == { - "pre_checkout_query_id": 1, - "error_message": "Not enough fish", - "ok": False, - } - - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.answer_pre_checkout_query(1, False, error_message="Not enough fish") + # send_invoice and create_invoice_link is tested in test_invoice - @pytest.mark.flaky(3, 1) async def test_restrict_chat_member(self, bot, channel_id, chat_permissions): # TODO: Add bot to supergroup so this can be tested properly with pytest.raises(BadRequest, match="Method is available only for supergroups"): @@ -2161,26 +2381,6 @@ async def test_restrict_chat_member(self, bot, channel_id, chat_permissions): channel_id, 95205500, chat_permissions, until_date=dtm.datetime.utcnow() ) - async def test_restrict_chat_member_default_tz( - self, monkeypatch, tz_bot, channel_id, chat_permissions - ): - until = dtm.datetime(2020, 1, 11, 16, 13) - until_timestamp = to_timestamp(until, tzinfo=tz_bot.defaults.tzinfo) - - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters.get("until_date", until_timestamp) == until_timestamp - - monkeypatch.setattr(tz_bot.request, "post", make_assertion) - - assert await tz_bot.restrict_chat_member(channel_id, 95205500, chat_permissions) - assert await tz_bot.restrict_chat_member( - channel_id, 95205500, chat_permissions, until_date=until - ) - assert await tz_bot.restrict_chat_member( - channel_id, 95205500, chat_permissions, until_date=until_timestamp - ) - - @pytest.mark.flaky(3, 1) async def test_promote_chat_member(self, bot, channel_id, monkeypatch): # TODO: Add bot to supergroup so this can be tested properly / give bot perms with pytest.raises(BadRequest, match="Not enough rights"): @@ -2239,14 +2439,12 @@ async def make_assertion(*args, **_): can_manage_topics=12, ) - @pytest.mark.flaky(3, 1) async def test_export_chat_invite_link(self, bot, channel_id): # Each link is unique apparently invite_link = await bot.export_chat_invite_link(channel_id) assert isinstance(invite_link, str) assert invite_link != "" - @pytest.mark.flaky(3, 1) async def test_edit_revoke_chat_invite_link_passing_link_objects(self, bot, channel_id): invite_link = await bot.create_chat_invite_link(chat_id=channel_id) assert invite_link.name is None @@ -2264,7 +2462,6 @@ async def test_edit_revoke_chat_invite_link_passing_link_objects(self, bot, chan assert revoked_link.is_revoked is True assert revoked_link.name == "some_name" - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("creates_join_request", [True, False]) @pytest.mark.parametrize("name", [None, "name"]) async def test_create_chat_invite_link_basics( @@ -2287,7 +2484,6 @@ async def test_create_chat_invite_link_basics( ) assert revoked_link.is_revoked - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("datetime", argvalues=[True, False], ids=["datetime", "integer"]) async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): # we are testing this all in one function in order to save api calls @@ -2342,7 +2538,6 @@ async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): assert revoked_invite_link.invite_link == invite_link.invite_link assert revoked_invite_link.is_revoked - @pytest.mark.flaky(3, 1) async def test_advanced_chat_invite_links_default_tzinfo(self, tz_bot, channel_id): # we are testing this all in one function in order to save api calls add_seconds = dtm.timedelta(0, 70) @@ -2391,7 +2586,6 @@ async def test_advanced_chat_invite_links_default_tzinfo(self, tz_bot, channel_i assert revoked_invite_link.invite_link == invite_link.invite_link assert revoked_invite_link.is_revoked - @pytest.mark.flaky(3, 1) async def test_approve_chat_join_request(self, bot, chat_id, channel_id): # TODO: Need incoming join request to properly test # Since we can't create join requests on the fly, we just tests the call to TG @@ -2399,7 +2593,6 @@ async def test_approve_chat_join_request(self, bot, chat_id, channel_id): with pytest.raises(BadRequest, match="User_already_participant"): await bot.approve_chat_join_request(chat_id=channel_id, user_id=chat_id) - @pytest.mark.flaky(3, 1) async def test_decline_chat_join_request(self, bot, chat_id, channel_id): # TODO: Need incoming join request to properly test # Since we can't create join requests on the fly, we just tests the call to TG @@ -2410,7 +2603,6 @@ async def test_decline_chat_join_request(self, bot, chat_id, channel_id): with pytest.raises(BadRequest, match="User_already_participant|Hide_requester_missing"): await bot.decline_chat_join_request(chat_id=channel_id, user_id=chat_id) - @pytest.mark.flaky(3, 1) async def test_set_chat_photo(self, bot, channel_id): async def func(): assert await bot.set_chat_photo(channel_id, f) @@ -2420,44 +2612,18 @@ async def func(): func, "Type of file mismatch", "Telegram did not accept the file." ) - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_set_chat_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("photo") == expected - else: - test_flag = isinstance(data.get("photo"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.set_chat_photo(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) async def test_delete_chat_photo(self, bot, channel_id): async def func(): assert await bot.delete_chat_photo(channel_id) await expect_bad_request(func, "Chat_not_modified", "Chat photo was not set.") - @pytest.mark.flaky(3, 1) async def test_set_chat_title(self, bot, channel_id): assert await bot.set_chat_title(channel_id, ">>> telegram.Bot() - Tests") - @pytest.mark.flaky(3, 1) async def test_set_chat_description(self, bot, channel_id): assert await bot.set_chat_description(channel_id, "Time: " + str(time.time())) - @pytest.mark.flaky(3, 1) async def test_pin_and_unpin_message(self, bot, super_group_id): message1 = await bot.send_message(super_group_id, text="test_pin_message_1") message2 = await bot.send_message(super_group_id, text="test_pin_message_2") @@ -2510,53 +2676,6 @@ async def test_pin_and_unpin_message(self, bot, super_group_id): # get_forum_topic_icon_stickers, edit_forum_topic, etc... # are tested in the test_forum module. - async def test_timeout_propagation_explicit(self, monkeypatch, bot, chat_id): - # Use BaseException that's not a subclass of Exception such that - # OkException should not be caught anywhere - class OkException(BaseException): - pass - - timeout = 42 - - async def do_request(*args, **kwargs): - obj = kwargs.get("read_timeout") - if obj == timeout: - raise OkException - - return 200, b'{"ok": true, "result": []}' - - monkeypatch.setattr(bot.request, "do_request", do_request) - - # Test file uploading - with pytest.raises(OkException): - await bot.send_photo( - chat_id, data_file("telegram.jpg").open("rb"), read_timeout=timeout - ) - - # Test JSON submission - with pytest.raises(OkException): - await bot.get_chat_administrators(chat_id, read_timeout=timeout) - - async def test_timeout_propagation_implicit(self, monkeypatch, bot, chat_id): - # Use BaseException that's not a subclass of Exception such that - # OkException should not be caught anywhere - class OkException(BaseException): - pass - - async def do_request(*args, **kwargs): - obj = kwargs.get("write_timeout") - if obj == 20: - raise OkException - - return 200, b'{"ok": true, "result": []}' - - monkeypatch.setattr(bot.request, "do_request", do_request) - - # Test file uploading - with pytest.raises(OkException): - await bot.send_photo(chat_id, data_file("telegram.jpg").open("rb")) - - @pytest.mark.flaky(3, 1) async def test_send_message_entities(self, bot, chat_id): test_string = "Italic Bold Code Spoiler" entities = [ @@ -2569,7 +2688,6 @@ async def test_send_message_entities(self, bot, chat_id): assert message.text == test_string assert message.entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_message_default_parse_mode(self, default_bot, chat_id): test_string = "Italic Bold Code" @@ -2587,7 +2705,6 @@ async def test_send_message_default_parse_mode(self, default_bot, chat_id): assert message.text == test_markdown_string assert message.text_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_message_default_protect_content(self, default_bot, chat_id): to_check = await default_bot.send_message(chat_id, "test") @@ -2596,7 +2713,6 @@ async def test_send_message_default_protect_content(self, default_bot, chat_id): no_protect = await default_bot.send_message(chat_id, "test", protect_content=False) assert not no_protect.has_protected_content - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -2630,7 +2746,6 @@ async def test_send_message_default_allow_sending_without_reply( chat_id, "test", reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.asyncio async def test_get_set_my_default_administrator_rights(self, bot): # Test that my default administrator rights for group are as all False await bot.set_my_default_administrator_rights() @@ -2656,7 +2771,6 @@ async def test_get_set_my_default_administrator_rights(self, bot): assert my_admin_rights_ch.can_pin_messages is None # Not returned for channels assert my_admin_rights_ch.can_manage_topics is None # Not returned for channels - @pytest.mark.asyncio async def test_get_set_chat_menu_button(self, bot, chat_id): # Test our chat menu button is commands- menu_button = await bot.get_chat_menu_button() @@ -2677,7 +2791,6 @@ async def test_get_set_chat_menu_button(self, bot, chat_id): menu_button = await bot.get_chat_menu_button(chat_id=chat_id) assert isinstance(menu_button, MenuButtonDefault) - @pytest.mark.flaky(3, 1) async def test_set_and_get_my_commands(self, bot): commands = [BotCommand("cmd1", "descr1"), ["cmd2", "descr2"]] await bot.set_my_commands([]) @@ -2688,7 +2801,6 @@ async def test_set_and_get_my_commands(self, bot): assert bc.command == f"cmd{i+1}" assert bc.description == f"descr{i+1}" - @pytest.mark.flaky(3, 1) async def test_get_set_delete_my_commands_with_scope(self, bot, super_group_id, chat_id): group_cmds = [BotCommand("group_cmd", "visible to this supergroup only")] private_cmds = [BotCommand("private_cmd", "visible to this private chat only")] @@ -2723,73 +2835,6 @@ async def test_get_set_delete_my_commands_with_scope(self, bot, super_group_id, await bot.delete_my_commands() # Delete commands from default scope assert len(await bot.get_my_commands()) == 0 - async def test_log_out(self, monkeypatch, bot): - # We don't actually make a request as to not break the test setup - async def assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters == {} and url.split("/")[-1] == "logOut" - - monkeypatch.setattr(bot.request, "post", assertion) - - assert await bot.log_out() - - async def test_close(self, monkeypatch, bot): - # We don't actually make a request as to not break the test setup - async def assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters == {} and url.split("/")[-1] == "close" - - monkeypatch.setattr(bot.request, "post", assertion) - - assert await bot.close() - - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("json_keyboard", [True, False]) - @pytest.mark.parametrize("caption", ["Test", "", None]) - async def test_copy_message( - self, monkeypatch, bot, chat_id, media_message, json_keyboard, caption - ): - keyboard = InlineKeyboardMarkup( - [[InlineKeyboardButton(text="test", callback_data="test2")]] - ) - - async def post(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - if not all( - [ - data["chat_id"] == chat_id, - data["from_chat_id"] == chat_id, - data["message_id"] == media_message.message_id, - data.get("caption") == caption, - data["parse_mode"] == ParseMode.HTML, - data["reply_to_message_id"] == media_message.message_id, - data["reply_markup"] == keyboard.to_json() - if json_keyboard - else keyboard.to_dict(), - data["disable_notification"] is True, - data["caption_entities"] - == [MessageEntity(MessageEntity.BOLD, 0, 4).to_dict()], - data["protect_content"] is True, - data["message_thread_id"] == 1, - ] - ): - pytest.fail("I got wrong parameters in post") - return data - - monkeypatch.setattr(bot.request, "post", post) - await bot.copy_message( - chat_id, - from_chat_id=chat_id, - message_id=media_message.message_id, - caption=caption, - caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 4)], - parse_mode=ParseMode.HTML, - reply_to_message_id=media_message.message_id, - reply_markup=keyboard.to_json() if json_keyboard else keyboard, - disable_notification=True, - protect_content=True, - message_thread_id=1, - ) - - @pytest.mark.flaky(3, 1) async def test_copy_message_without_reply(self, bot, chat_id, media_message): keyboard = InlineKeyboardMarkup( [[InlineKeyboardButton(text="test", callback_data="test2")]] @@ -2815,7 +2860,6 @@ async def test_copy_message_without_reply(self, bot, chat_id, media_message): assert len(message.caption_entities) == 1 assert message.reply_markup == keyboard - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot", [ @@ -2946,62 +2990,6 @@ async def test_replace_callback_data_copy_message(self, cdc_bot, chat_id): bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - # TODO: Needs improvement. We need incoming inline query to test answer. - async def test_replace_callback_data_answer_inline_query(self, monkeypatch, cdc_bot, chat_id): - bot = cdc_bot - - # For now just test that our internals pass the correct data - async def make_assertion( - endpoint, - data=None, - *args, - **kwargs, - ): - inline_keyboard = data["results"][0]["reply_markup"].inline_keyboard - assertion_1 = inline_keyboard[0][1] == no_replace_button - assertion_2 = inline_keyboard[0][0] != replace_button - keyboard, button = ( - inline_keyboard[0][0].callback_data[:32], - inline_keyboard[0][0].callback_data[32:], - ) - assertion_3 = ( - bot.callback_data_cache._keyboard_data[keyboard].button_data[button] - == "replace_test" - ) - assertion_4 = data["results"][1].reply_markup is None - return assertion_1 and assertion_2 and assertion_3 and assertion_4 - - try: - replace_button = InlineKeyboardButton(text="replace", callback_data="replace_test") - no_replace_button = InlineKeyboardButton( - text="no_replace", url="http://python-telegram-bot.org/" - ) - reply_markup = InlineKeyboardMarkup.from_row( - [ - replace_button, - no_replace_button, - ] - ) - - bot.username # call this here so `bot.get_me()` won't be called after mocking - monkeypatch.setattr(bot, "_post", make_assertion) - results = [ - InlineQueryResultArticle( - "11", "first", InputTextMessageContent("first"), reply_markup=reply_markup - ), - InlineQueryResultVoice( - "22", - "https://python-telegram-bot.org/static/testfiles/telegram.ogg", - title="second", - ), - ] - - assert await bot.answer_inline_query(chat_id, results=results) - - finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() - async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): bot = cdc_bot @@ -3186,48 +3174,3 @@ async def post(*args, **kwargs): finally: bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - - @bot_methods() - def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): - camel_case_name = to_camel_case(bot_method_name) - camel_case_function = getattr(bot_class, camel_case_name, False) - assert camel_case_function is not False, f"{camel_case_name} not found" - assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}" - - @bot_methods() - def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): - """Check that all bot methods are defined as async def ...""" - # not islower() skips the camelcase aliases - if not bot_method_name.islower(): - return - # unfortunately `inspect.iscoroutinefunction` doesn't do the trick directly, - # as the @_log decorator interferes - source = "".join(inspect.getsourcelines(bot_method)[0]) - assert ( - f"async def {bot_method_name}" in source - ), f"{bot_method_name} should be a coroutine function" - - @bot_methods() - def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): - """Check that all bot methods have `api_kwargs` and timeout params.""" - param_names = inspect.signature(bot_method).parameters.keys() - assert ( - "pool_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `pool_timeout`" - assert ( - "read_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `read_timeout`" - assert ( - "connect_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `connect_timeout`" - assert ( - "write_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `write_timeout`" - assert ( - "api_kwargs" in param_names - ), f"{bot_method_name} is missing the parameter `api_kwargs`" - - if bot_class is ExtBot and bot_method_name.replace("_", "").lower() != "getupdates": - assert ( - "rate_limit_args" in param_names - ), f"{bot_method_name} of ExtBot is missing the parameter `rate_limit_args`" diff --git a/tests/test_botcommand.py b/tests/test_botcommand.py index a9fbbb9c5bd..f9965e4eeac 100644 --- a/tests/test_botcommand.py +++ b/tests/test_botcommand.py @@ -22,12 +22,12 @@ from telegram import BotCommand, Dice -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def bot_command(): return BotCommand(command="start", description="A command") -class TestBotCommand: +class TestBotCommandNoReq: command = "start" description = "A command" diff --git a/tests/test_botcommandscope.py b/tests/test_botcommandscope.py index 2b074b2a197..3ff14783872 100644 --- a/tests/test_botcommandscope.py +++ b/tests/test_botcommandscope.py @@ -33,7 +33,7 @@ ) -@pytest.fixture(scope="class", params=["str", "int"]) +@pytest.fixture(scope="module", params=["str", "int"]) def chat_id(request): if request.param == "str": return "@supergroupusername" @@ -57,7 +57,7 @@ def scope_type(request): @pytest.fixture( - scope="class", + scope="module", params=[ BotCommandScopeDefault, BotCommandScopeAllPrivateChats, @@ -82,7 +82,7 @@ def scope_class(request): @pytest.fixture( - scope="class", + scope="module", params=[ (BotCommandScopeDefault, BotCommandScope.DEFAULT), (BotCommandScopeAllPrivateChats, BotCommandScope.ALL_PRIVATE_CHATS), @@ -106,7 +106,7 @@ def scope_class_and_type(request): return request.param -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def bot_command_scope(scope_class_and_type, chat_id): # we use de_json here so that we don't have to worry about which class needs which arguments return scope_class_and_type[0].de_json( @@ -115,7 +115,7 @@ def bot_command_scope(scope_class_and_type, chat_id): # All the scope types are very similar, so we test everything via parametrization -class TestBotCommandScope: +class TestBotCommandScopeNoReq: def test_slot_behaviour(self, bot_command_scope, mro_slots): for attr in bot_command_scope.__slots__: assert getattr(bot_command_scope, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 13b6133e298..2135f7569c2 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -32,23 +32,23 @@ @pytest.fixture(scope="function", 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, + Space.id_, + Space.from_user, + Space.chat_instance, + data=Space.data, + game_short_name=Space.game_short_name, ) cbq.set_bot(bot) cbq._unfreeze() if request.param == "message": - cbq.message = TestCallbackQuery.message + cbq.message = Space.message cbq.message.set_bot(bot) else: - cbq.inline_message_id = TestCallbackQuery.inline_message_id + cbq.inline_message_id = Space.inline_message_id return cbq -class TestCallbackQuery: +class Space: id_ = "id" from_user = User(1, "test_user", False) chat_instance = "chat_instance" @@ -57,6 +57,8 @@ class TestCallbackQuery: inline_message_id = "inline_message_id" game_short_name = "the_game" + +class TestCallbackQueryNoReq: @staticmethod def skip_params(callback_query: CallbackQuery): if callback_query.inline_message_id: @@ -88,24 +90,24 @@ def test_slot_behaviour(self, callback_query, mro_slots): 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, + "id": Space.id_, + "from": Space.from_user.to_dict(), + "chat_instance": Space.chat_instance, + "message": Space.message.to_dict(), + "data": Space.data, + "inline_message_id": Space.inline_message_id, + "game_short_name": Space.game_short_name, } callback_query = CallbackQuery.de_json(json_dict, bot) assert callback_query.api_kwargs == {} - 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 + assert callback_query.id == Space.id_ + assert callback_query.from_user == Space.from_user + assert callback_query.chat_instance == Space.chat_instance + assert callback_query.message == Space.message + assert callback_query.data == Space.data + assert callback_query.inline_message_id == Space.inline_message_id + assert callback_query.game_short_name == Space.game_short_name def test_to_dict(self, callback_query): callback_query_dict = callback_query.to_dict() @@ -449,11 +451,11 @@ async def make_assertion(*args, **kwargs): assert await callback_query.copy_message(1) def test_equality(self): - a = CallbackQuery(self.id_, self.from_user, "chat") - b = CallbackQuery(self.id_, self.from_user, "chat") - c = CallbackQuery(self.id_, None, "") + a = CallbackQuery(Space.id_, Space.from_user, "chat") + b = CallbackQuery(Space.id_, Space.from_user, "chat") + c = CallbackQuery(Space.id_, None, "") d = CallbackQuery("", None, "chat") - e = Audio(self.id_, "unique_id", 1) + e = Audio(Space.id_, "unique_id", 1) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_chat.py b/tests/test_chat.py index a8418ec9f6b..1f78a4ad4f4 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -29,35 +29,35 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat(bot): chat = Chat( - TestChat.id_, - title=TestChat.title, - type=TestChat.type_, - username=TestChat.username, - sticker_set_name=TestChat.sticker_set_name, - can_set_sticker_set=TestChat.can_set_sticker_set, - permissions=TestChat.permissions, - slow_mode_delay=TestChat.slow_mode_delay, - bio=TestChat.bio, - linked_chat_id=TestChat.linked_chat_id, - location=TestChat.location, + Space.id_, + title=Space.title, + type=Space.type_, + username=Space.username, + sticker_set_name=Space.sticker_set_name, + can_set_sticker_set=Space.can_set_sticker_set, + permissions=Space.permissions, + slow_mode_delay=Space.slow_mode_delay, + bio=Space.bio, + linked_chat_id=Space.linked_chat_id, + location=Space.location, has_private_forwards=True, has_protected_content=True, join_to_send_messages=True, join_by_request=True, has_restricted_voice_and_video_messages=True, is_forum=True, - active_usernames=TestChat.active_usernames, - emoji_status_custom_emoji_id=TestChat.emoji_status_custom_emoji_id, + active_usernames=Space.active_usernames, + emoji_status_custom_emoji_id=Space.emoji_status_custom_emoji_id, ) chat.set_bot(bot) chat._unfreeze() return chat -class TestChat: +class Space: id_ = -28767330 title = "ToledosPalaceBot - Group" type_ = "group" @@ -83,6 +83,8 @@ class TestChat: active_usernames = ["These", "Are", "Usernames!"] emoji_status_custom_emoji_id = "VeryUniqueCustomEmojiID" + +class TestChatNoReq: def test_slot_behaviour(self, chat, mro_slots): for attr in chat.__slots__: assert getattr(chat, attr, "err") != "err", f"got extra slot '{attr}'" @@ -90,57 +92,57 @@ def test_slot_behaviour(self, chat, mro_slots): def test_de_json(self, bot): json_dict = { - "id": self.id_, - "title": self.title, - "type": self.type_, - "username": self.username, - "all_members_are_administrators": self.all_members_are_administrators, - "sticker_set_name": self.sticker_set_name, - "can_set_sticker_set": self.can_set_sticker_set, - "permissions": self.permissions.to_dict(), - "slow_mode_delay": self.slow_mode_delay, - "bio": self.bio, - "has_protected_content": self.has_protected_content, - "has_private_forwards": self.has_private_forwards, - "linked_chat_id": self.linked_chat_id, - "location": self.location.to_dict(), - "join_to_send_messages": self.join_to_send_messages, - "join_by_request": self.join_by_request, + "id": Space.id_, + "title": Space.title, + "type": Space.type_, + "username": Space.username, + "all_members_are_administrators": Space.all_members_are_administrators, + "sticker_set_name": Space.sticker_set_name, + "can_set_sticker_set": Space.can_set_sticker_set, + "permissions": Space.permissions.to_dict(), + "slow_mode_delay": Space.slow_mode_delay, + "bio": Space.bio, + "has_protected_content": Space.has_protected_content, + "has_private_forwards": Space.has_private_forwards, + "linked_chat_id": Space.linked_chat_id, + "location": Space.location.to_dict(), + "join_to_send_messages": Space.join_to_send_messages, + "join_by_request": Space.join_by_request, "has_restricted_voice_and_video_messages": ( - self.has_restricted_voice_and_video_messages + Space.has_restricted_voice_and_video_messages ), - "is_forum": self.is_forum, - "active_usernames": self.active_usernames, - "emoji_status_custom_emoji_id": self.emoji_status_custom_emoji_id, + "is_forum": Space.is_forum, + "active_usernames": Space.active_usernames, + "emoji_status_custom_emoji_id": Space.emoji_status_custom_emoji_id, } chat = Chat.de_json(json_dict, bot) - assert chat.id == self.id_ - assert chat.title == self.title - assert chat.type == self.type_ - assert chat.username == self.username - assert chat.sticker_set_name == self.sticker_set_name - assert chat.can_set_sticker_set == self.can_set_sticker_set - assert chat.permissions == self.permissions - assert chat.slow_mode_delay == self.slow_mode_delay - assert chat.bio == self.bio - assert chat.has_protected_content == self.has_protected_content - assert chat.has_private_forwards == self.has_private_forwards - assert chat.linked_chat_id == self.linked_chat_id - assert chat.location.location == self.location.location - assert chat.location.address == self.location.address - assert chat.join_to_send_messages == self.join_to_send_messages - assert chat.join_by_request == self.join_by_request + assert chat.id == Space.id_ + assert chat.title == Space.title + assert chat.type == Space.type_ + assert chat.username == Space.username + assert chat.sticker_set_name == Space.sticker_set_name + assert chat.can_set_sticker_set == Space.can_set_sticker_set + assert chat.permissions == Space.permissions + assert chat.slow_mode_delay == Space.slow_mode_delay + assert chat.bio == Space.bio + assert chat.has_protected_content == Space.has_protected_content + assert chat.has_private_forwards == Space.has_private_forwards + assert chat.linked_chat_id == Space.linked_chat_id + assert chat.location.location == Space.location.location + assert chat.location.address == Space.location.address + assert chat.join_to_send_messages == Space.join_to_send_messages + assert chat.join_by_request == Space.join_by_request assert ( chat.has_restricted_voice_and_video_messages - == self.has_restricted_voice_and_video_messages + == Space.has_restricted_voice_and_video_messages ) assert chat.api_kwargs == { - "all_members_are_administrators": self.all_members_are_administrators + "all_members_are_administrators": Space.all_members_are_administrators } - assert chat.is_forum == self.is_forum - assert chat.active_usernames == tuple(self.active_usernames) - assert chat.emoji_status_custom_emoji_id == self.emoji_status_custom_emoji_id + assert chat.is_forum == Space.is_forum + assert chat.active_usernames == tuple(Space.active_usernames) + assert chat.emoji_status_custom_emoji_id == Space.emoji_status_custom_emoji_id def test_to_dict(self, chat): chat_dict = chat.to_dict() @@ -403,7 +405,7 @@ async def make_assertion(*_, **kwargs): async def test_set_permissions(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): chat_id = kwargs["chat_id"] == chat.id - permissions = kwargs["permissions"] == self.permissions + permissions = kwargs["permissions"] == Space.permissions return chat_id and permissions assert check_shortcut_signature( @@ -415,7 +417,7 @@ async def make_assertion(*_, **kwargs): assert await check_defaults_handling(chat.set_permissions, chat.get_bot()) monkeypatch.setattr(chat.get_bot(), "set_chat_permissions", make_assertion) - assert await chat.set_permissions(permissions=self.permissions) + assert await chat.set_permissions(permissions=Space.permissions) async def test_set_administrator_custom_title(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): @@ -1126,11 +1128,11 @@ def test_mention_markdown_v2(self): chat.mention_markdown_v2() def test_equality(self): - 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_, "", False) + a = Chat(Space.id_, Space.title, Space.type_) + b = Chat(Space.id_, Space.title, Space.type_) + c = Chat(Space.id_, "", "") + d = Chat(0, Space.title, Space.type_) + e = User(Space.id_, "", False) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_chatadministratorrights.py b/tests/test_chatadministratorrights.py index 83826f74bac..100291f4a74 100644 --- a/tests/test_chatadministratorrights.py +++ b/tests/test_chatadministratorrights.py @@ -21,7 +21,7 @@ from telegram import ChatAdministratorRights -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_admin_rights(): return ChatAdministratorRights( can_change_info=True, @@ -39,7 +39,7 @@ def chat_admin_rights(): ) -class TestChatAdministratorRights: +class TestChatAdministratorRightsNoReq: def test_slot_behaviour(self, chat_admin_rights, mro_slots): inst = chat_admin_rights for attr in inst.__slots__: diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 1f940d39ab5..b4868c6c80e 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -24,28 +24,27 @@ from telegram._utils.datetime import to_timestamp -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def creator(): return User(1, "First name", False) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def invite_link(creator): return ChatInviteLink( - TestChatInviteLink.link, + Space.link, creator, - TestChatInviteLink.creates_join_request, - TestChatInviteLink.primary, - TestChatInviteLink.revoked, - expire_date=TestChatInviteLink.expire_date, - member_limit=TestChatInviteLink.member_limit, - name=TestChatInviteLink.name, - pending_join_request_count=TestChatInviteLink.pending_join_request_count, + Space.creates_join_request, + Space.primary, + Space.revoked, + expire_date=Space.expire_date, + member_limit=Space.member_limit, + name=Space.name, + pending_join_request_count=Space.pending_join_request_count, ) -class TestChatInviteLink: - +class Space: link = "thisialink" creates_join_request = False primary = True @@ -55,6 +54,8 @@ class TestChatInviteLink: name = "LinkName" pending_join_request_count = 42 + +class TestChatInviteLinkNoReq: def test_slot_behaviour(self, mro_slots, invite_link): for attr in invite_link.__slots__: assert getattr(invite_link, attr, "err") != "err", f"got extra slot '{attr}'" @@ -62,48 +63,48 @@ def test_slot_behaviour(self, mro_slots, invite_link): def test_de_json_required_args(self, bot, creator): json_dict = { - "invite_link": self.link, + "invite_link": Space.link, "creator": creator.to_dict(), - "creates_join_request": self.creates_join_request, - "is_primary": self.primary, - "is_revoked": self.revoked, + "creates_join_request": Space.creates_join_request, + "is_primary": Space.primary, + "is_revoked": Space.revoked, } invite_link = ChatInviteLink.de_json(json_dict, bot) assert invite_link.api_kwargs == {} - assert invite_link.invite_link == self.link + assert invite_link.invite_link == Space.link assert invite_link.creator == creator - assert invite_link.creates_join_request == self.creates_join_request - assert invite_link.is_primary == self.primary - assert invite_link.is_revoked == self.revoked + assert invite_link.creates_join_request == Space.creates_join_request + assert invite_link.is_primary == Space.primary + assert invite_link.is_revoked == Space.revoked def test_de_json_all_args(self, bot, creator): json_dict = { - "invite_link": self.link, + "invite_link": Space.link, "creator": creator.to_dict(), - "creates_join_request": self.creates_join_request, - "is_primary": self.primary, - "is_revoked": self.revoked, - "expire_date": to_timestamp(self.expire_date), - "member_limit": self.member_limit, - "name": self.name, - "pending_join_request_count": str(self.pending_join_request_count), + "creates_join_request": Space.creates_join_request, + "is_primary": Space.primary, + "is_revoked": Space.revoked, + "expire_date": to_timestamp(Space.expire_date), + "member_limit": Space.member_limit, + "name": Space.name, + "pending_join_request_count": str(Space.pending_join_request_count), } invite_link = ChatInviteLink.de_json(json_dict, bot) assert invite_link.api_kwargs == {} - assert invite_link.invite_link == self.link + assert invite_link.invite_link == Space.link assert invite_link.creator == creator - assert invite_link.creates_join_request == self.creates_join_request - assert invite_link.is_primary == self.primary - assert invite_link.is_revoked == self.revoked - assert abs(invite_link.expire_date - self.expire_date) < datetime.timedelta(seconds=1) - assert to_timestamp(invite_link.expire_date) == to_timestamp(self.expire_date) - assert invite_link.member_limit == self.member_limit - assert invite_link.name == self.name - assert invite_link.pending_join_request_count == self.pending_join_request_count + assert invite_link.creates_join_request == Space.creates_join_request + assert invite_link.is_primary == Space.primary + assert invite_link.is_revoked == Space.revoked + assert abs(invite_link.expire_date - Space.expire_date) < datetime.timedelta(seconds=1) + assert to_timestamp(invite_link.expire_date) == to_timestamp(Space.expire_date) + assert invite_link.member_limit == Space.member_limit + assert invite_link.name == Space.name + assert invite_link.pending_join_request_count == Space.pending_join_request_count def test_to_dict(self, invite_link): invite_link_dict = invite_link.to_dict() @@ -111,12 +112,12 @@ def test_to_dict(self, invite_link): assert invite_link_dict["creator"] == invite_link.creator.to_dict() assert invite_link_dict["invite_link"] == invite_link.invite_link assert invite_link_dict["creates_join_request"] == invite_link.creates_join_request - assert invite_link_dict["is_primary"] == self.primary - assert invite_link_dict["is_revoked"] == self.revoked - assert invite_link_dict["expire_date"] == to_timestamp(self.expire_date) - assert invite_link_dict["member_limit"] == self.member_limit - assert invite_link_dict["name"] == self.name - assert invite_link_dict["pending_join_request_count"] == self.pending_join_request_count + assert invite_link_dict["is_primary"] == Space.primary + assert invite_link_dict["is_revoked"] == Space.revoked + assert invite_link_dict["expire_date"] == to_timestamp(Space.expire_date) + assert invite_link_dict["member_limit"] == Space.member_limit + assert invite_link_dict["name"] == Space.name + assert invite_link_dict["pending_join_request_count"] == Space.pending_join_request_count def test_equality(self): a = ChatInviteLink("link", User(1, "", False), True, True, True) diff --git a/tests/test_chatjoinrequest.py b/tests/test_chatjoinrequest.py index b01d6f48758..d7718ef4500 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -29,25 +29,25 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def time(): return datetime.datetime.now(tz=UTC) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_join_request(bot, time): cjr = ChatJoinRequest( - chat=TestChatJoinRequest.chat, - from_user=TestChatJoinRequest.from_user, + chat=Space.chat, + from_user=Space.from_user, date=time, - bio=TestChatJoinRequest.bio, - invite_link=TestChatJoinRequest.invite_link, + bio=Space.bio, + invite_link=Space.invite_link, ) cjr.set_bot(bot) return cjr -class TestChatJoinRequest: +class Space: chat = Chat(1, Chat.SUPERGROUP) from_user = User(2, "first_name", False) bio = "bio" @@ -60,6 +60,8 @@ class TestChatJoinRequest: is_primary=False, ) + +class TestChatJoinRequestNoReq: def test_slot_behaviour(self, chat_join_request, mro_slots): inst = chat_join_request for attr in inst.__slots__: @@ -68,28 +70,28 @@ def test_slot_behaviour(self, chat_join_request, mro_slots): def test_de_json(self, bot, time): json_dict = { - "chat": self.chat.to_dict(), - "from": self.from_user.to_dict(), + "chat": Space.chat.to_dict(), + "from": Space.from_user.to_dict(), "date": to_timestamp(time), } chat_join_request = ChatJoinRequest.de_json(json_dict, bot) assert chat_join_request.api_kwargs == {} - assert chat_join_request.chat == self.chat - assert chat_join_request.from_user == self.from_user + assert chat_join_request.chat == Space.chat + assert chat_join_request.from_user == Space.from_user assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1) assert to_timestamp(chat_join_request.date) == to_timestamp(time) - json_dict.update({"bio": self.bio, "invite_link": self.invite_link.to_dict()}) + json_dict.update({"bio": Space.bio, "invite_link": Space.invite_link.to_dict()}) chat_join_request = ChatJoinRequest.de_json(json_dict, bot) assert chat_join_request.api_kwargs == {} - assert chat_join_request.chat == self.chat - assert chat_join_request.from_user == self.from_user + assert chat_join_request.chat == Space.chat + assert chat_join_request.from_user == Space.from_user assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1) assert to_timestamp(chat_join_request.date) == to_timestamp(time) - assert chat_join_request.bio == self.bio - assert chat_join_request.invite_link == self.invite_link + assert chat_join_request.bio == Space.bio + assert chat_join_request.invite_link == Space.invite_link def test_to_dict(self, chat_join_request, time): chat_join_request_dict = chat_join_request.to_dict() @@ -103,10 +105,10 @@ def test_to_dict(self, chat_join_request, time): def test_equality(self, chat_join_request, time): a = chat_join_request - b = ChatJoinRequest(self.chat, self.from_user, time) - c = ChatJoinRequest(self.chat, self.from_user, time, bio="bio") - d = ChatJoinRequest(self.chat, self.from_user, time + datetime.timedelta(1)) - e = ChatJoinRequest(self.chat, User(-1, "last_name", True), time) + b = ChatJoinRequest(Space.chat, Space.from_user, time) + c = ChatJoinRequest(Space.chat, Space.from_user, time, bio="bio") + d = ChatJoinRequest(Space.chat, Space.from_user, time + datetime.timedelta(1)) + e = ChatJoinRequest(Space.chat, User(-1, "last_name", True), time) f = User(456, "", False) assert a == b diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index ea9bd3bc6a8..91f6ff5c7bc 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -22,15 +22,17 @@ from telegram import ChatLocation, Location, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_location(bot): - return ChatLocation(TestChatLocation.location, TestChatLocation.address) + return ChatLocation(Space.location, Space.address) -class TestChatLocation: +class Space: location = Location(123, 456) address = "The Shire" + +class TestChatLocationNoReq: def test_slot_behaviour(self, chat_location, mro_slots): inst = chat_location for attr in inst.__slots__: @@ -39,14 +41,14 @@ def test_slot_behaviour(self, chat_location, mro_slots): def test_de_json(self, bot): json_dict = { - "location": self.location.to_dict(), - "address": self.address, + "location": Space.location.to_dict(), + "address": Space.address, } chat_location = ChatLocation.de_json(json_dict, bot) assert chat_location.api_kwargs == {} - assert chat_location.location == self.location - assert chat_location.address == self.address + assert chat_location.location == Space.location + assert chat_location.address == Space.address def test_to_dict(self, chat_location): chat_location_dict = chat_location.to_dict() @@ -57,9 +59,9 @@ def test_to_dict(self, chat_location): def test_equality(self, chat_location): a = chat_location - b = ChatLocation(self.location, self.address) - c = ChatLocation(self.location, "Mordor") - d = ChatLocation(Location(456, 132), self.address) + b = ChatLocation(Space.location, Space.address) + c = ChatLocation(Space.location, "Mordor") + d = ChatLocation(Location(456, 132), Space.address) e = User(456, "", False) assert a == b diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index ab7e7d23da2..83a103db015 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -175,7 +175,7 @@ def chat_member_type(request): ], indirect=True, ) -class TestChatMemberTypes: +class TestChatMemberTypesNoReq: def test_slot_behaviour(self, chat_member_type, mro_slots): inst = chat_member_type for attr in inst.__slots__: diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index 29cc9e5824f..724b51ec9d8 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -34,26 +34,26 @@ from telegram._utils.datetime import UTC, to_timestamp -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def user(): return User(1, "First name", False) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat(): return Chat(1, Chat.SUPERGROUP, "Chat") -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def old_chat_member(user): - return ChatMember(user, TestChatMemberUpdated.old_status) + return ChatMember(user, Space.old_status) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def new_chat_member(user): return ChatMemberAdministrator( user, - TestChatMemberUpdated.new_status, + Space.new_status, True, True, True, @@ -66,25 +66,27 @@ def new_chat_member(user): ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def time(): return datetime.datetime.now(tz=UTC) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def invite_link(user): return ChatInviteLink("link", user, False, True, True) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_member_updated(user, chat, old_chat_member, new_chat_member, invite_link, time): return ChatMemberUpdated(chat, user, time, old_chat_member, new_chat_member, invite_link) -class TestChatMemberUpdated: +class Space: old_status = ChatMember.MEMBER new_status = ChatMember.ADMINISTRATOR + +class TestChatMemberUpdatedNoReq: def test_slot_behaviour(self, mro_slots, chat_member_updated): action = chat_member_updated for attr in action.__slots__: diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index 5498bae24ca..66ccf95c5f3 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -22,7 +22,7 @@ from telegram import ChatPermissions, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chat_permissions(): return ChatPermissions( can_send_messages=True, @@ -37,7 +37,7 @@ def chat_permissions(): ) -class TestChatPermissions: +class Space: can_send_messages = True can_send_media_messages = True can_send_polls = True @@ -48,6 +48,8 @@ class TestChatPermissions: can_pin_messages = None can_manage_topics = None + +class TestChatPermissionsNoReq: def test_slot_behaviour(self, chat_permissions, mro_slots): inst = chat_permissions for attr in inst.__slots__: @@ -56,28 +58,28 @@ def test_slot_behaviour(self, chat_permissions, mro_slots): def test_de_json(self, bot): json_dict = { - "can_send_messages": self.can_send_messages, - "can_send_media_messages": self.can_send_media_messages, - "can_send_polls": self.can_send_polls, - "can_send_other_messages": self.can_send_other_messages, - "can_add_web_page_previews": self.can_add_web_page_previews, - "can_change_info": self.can_change_info, - "can_invite_users": self.can_invite_users, - "can_pin_messages": self.can_pin_messages, - "can_manage_topics": self.can_manage_topics, + "can_send_messages": Space.can_send_messages, + "can_send_media_messages": Space.can_send_media_messages, + "can_send_polls": Space.can_send_polls, + "can_send_other_messages": Space.can_send_other_messages, + "can_add_web_page_previews": Space.can_add_web_page_previews, + "can_change_info": Space.can_change_info, + "can_invite_users": Space.can_invite_users, + "can_pin_messages": Space.can_pin_messages, + "can_manage_topics": Space.can_manage_topics, } permissions = ChatPermissions.de_json(json_dict, bot) assert permissions.api_kwargs == {} - assert permissions.can_send_messages == self.can_send_messages - assert permissions.can_send_media_messages == self.can_send_media_messages - assert permissions.can_send_polls == self.can_send_polls - assert permissions.can_send_other_messages == self.can_send_other_messages - assert permissions.can_add_web_page_previews == self.can_add_web_page_previews - assert permissions.can_change_info == self.can_change_info - assert permissions.can_invite_users == self.can_invite_users - assert permissions.can_pin_messages == self.can_pin_messages - assert permissions.can_manage_topics == self.can_manage_topics + assert permissions.can_send_messages == Space.can_send_messages + assert permissions.can_send_media_messages == Space.can_send_media_messages + assert permissions.can_send_polls == Space.can_send_polls + assert permissions.can_send_other_messages == Space.can_send_other_messages + assert permissions.can_add_web_page_previews == Space.can_add_web_page_previews + assert permissions.can_change_info == Space.can_change_info + assert permissions.can_invite_users == Space.can_invite_users + assert permissions.can_pin_messages == Space.can_pin_messages + assert permissions.can_manage_topics == Space.can_manage_topics def test_to_dict(self, chat_permissions): permissions_dict = chat_permissions.to_dict() diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index 902402bfe69..cb357378ea6 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -33,7 +33,7 @@ from tests.conftest import data_file, expect_bad_request -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def chatphoto_file(): f = data_file("telegram.jpg").open("rb") yield f @@ -50,53 +50,20 @@ async def func(): ) -class TestChatPhoto: +class Space: chatphoto_small_file_id = "smallCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_big_file_id = "bigCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_small_file_unique_id = "smalladc3145fd2e84d95b64d68eaa22aa33e" chatphoto_big_file_unique_id = "bigadc3145fd2e84d95b64d68eaa22aa33e" chatphoto_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.jpg" + +class TestChatPhotoNoReq: def test_slot_behaviour(self, chat_photo, mro_slots): for attr in chat_photo.__slots__: assert getattr(chat_photo, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(chat_photo)) == len(set(mro_slots(chat_photo))), "duplicate slot" - @pytest.mark.flaky(3, 1) - async def test_send_all_args( - self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file - ): - async def func(): - assert await bot.set_chat_photo(super_group_id, chatphoto_file) - - await expect_bad_request( - func, "Type of file mismatch", "Telegram did not accept the file." - ) - - @pytest.mark.flaky(3, 1) - async def test_get_and_download(self, bot, chat_photo): - jpg_file = Path("telegram.jpg") - if jpg_file.is_file(): - jpg_file.unlink() - - new_file = await bot.get_file(chat_photo.small_file_id) - - assert new_file.file_unique_id == chat_photo.small_file_unique_id - assert new_file.file_path.startswith("https://") - - await new_file.download_to_drive(jpg_file) - - assert jpg_file.is_file() - - new_file = await bot.get_file(chat_photo.big_file_id) - - assert new_file.file_unique_id == chat_photo.big_file_unique_id - assert new_file.file_path.startswith("https://") - - await new_file.download_to_drive(jpg_file) - - assert jpg_file.is_file() - async def test_send_with_chat_photo(self, monkeypatch, bot, super_group_id, chat_photo): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.parameters["photo"] == chat_photo.to_dict() @@ -107,17 +74,17 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): def test_de_json(self, bot, chat_photo): json_dict = { - "small_file_id": self.chatphoto_small_file_id, - "big_file_id": self.chatphoto_big_file_id, - "small_file_unique_id": self.chatphoto_small_file_unique_id, - "big_file_unique_id": self.chatphoto_big_file_unique_id, + "small_file_id": Space.chatphoto_small_file_id, + "big_file_id": Space.chatphoto_big_file_id, + "small_file_unique_id": Space.chatphoto_small_file_unique_id, + "big_file_unique_id": Space.chatphoto_big_file_unique_id, } chat_photo = ChatPhoto.de_json(json_dict, bot) assert chat_photo.api_kwargs == {} - assert chat_photo.small_file_id == self.chatphoto_small_file_id - assert chat_photo.big_file_id == self.chatphoto_big_file_id - assert chat_photo.small_file_unique_id == self.chatphoto_small_file_unique_id - assert chat_photo.big_file_unique_id == self.chatphoto_big_file_unique_id + assert chat_photo.small_file_id == Space.chatphoto_small_file_id + assert chat_photo.big_file_id == Space.chatphoto_big_file_id + assert chat_photo.small_file_unique_id == Space.chatphoto_small_file_unique_id + assert chat_photo.big_file_unique_id == Space.chatphoto_big_file_unique_id async def test_to_dict(self, chat_photo): chat_photo_dict = chat_photo.to_dict() @@ -128,22 +95,6 @@ async def test_to_dict(self, chat_photo): assert chat_photo_dict["small_file_unique_id"] == chat_photo.small_file_unique_id assert chat_photo_dict["big_file_unique_id"] == chat_photo.big_file_unique_id - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file(self, bot, super_group_id): - chatphoto_file = open(os.devnull, "rb") - - with pytest.raises(TelegramError): - await bot.set_chat_photo(chat_id=super_group_id, photo=chatphoto_file) - - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file_id(self, bot, super_group_id): - with pytest.raises(TelegramError): - await bot.set_chat_photo(chat_id=super_group_id, photo="") - - async def test_error_send_without_required_args(self, bot, super_group_id): - with pytest.raises(TypeError): - await bot.set_chat_photo(chat_id=super_group_id) - async def test_get_small_file_instance_method(self, monkeypatch, chat_photo): async def make_assertion(*_, **kwargs): return kwargs["file_id"] == chat_photo.small_file_id @@ -170,22 +121,22 @@ async def make_assertion(*_, **kwargs): def test_equality(self): a = ChatPhoto( - self.chatphoto_small_file_id, - self.chatphoto_big_file_id, - self.chatphoto_small_file_unique_id, - self.chatphoto_big_file_unique_id, + Space.chatphoto_small_file_id, + Space.chatphoto_big_file_id, + Space.chatphoto_small_file_unique_id, + Space.chatphoto_big_file_unique_id, ) b = ChatPhoto( - self.chatphoto_small_file_id, - self.chatphoto_big_file_id, - self.chatphoto_small_file_unique_id, - self.chatphoto_big_file_unique_id, + Space.chatphoto_small_file_id, + Space.chatphoto_big_file_id, + Space.chatphoto_small_file_unique_id, + Space.chatphoto_big_file_unique_id, ) c = ChatPhoto( - "", "", self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id + "", "", Space.chatphoto_small_file_unique_id, Space.chatphoto_big_file_unique_id ) d = ChatPhoto("", "", 0, 0) - e = Voice(self.chatphoto_small_file_id, self.chatphoto_small_file_unique_id, 0) + e = Voice(Space.chatphoto_small_file_id, Space.chatphoto_small_file_unique_id, 0) assert a == b assert hash(a) == hash(b) @@ -199,3 +150,52 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + + +class TestChatPhotoReq: + async def test_send_all_args( + self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file + ): + async def func(): + assert await bot.set_chat_photo(super_group_id, chatphoto_file) + + await expect_bad_request( + func, "Type of file mismatch", "Telegram did not accept the file." + ) + + async def test_get_and_download(self, bot, chat_photo): + jpg_file = Path("telegram.jpg") + if jpg_file.is_file(): + jpg_file.unlink() + + new_file = await bot.get_file(chat_photo.small_file_id) + + assert new_file.file_unique_id == chat_photo.small_file_unique_id + assert new_file.file_path.startswith("https://") + + await new_file.download_to_drive(jpg_file) + + assert jpg_file.is_file() + + new_file = await bot.get_file(chat_photo.big_file_id) + + assert new_file.file_unique_id == chat_photo.big_file_unique_id + assert new_file.file_path.startswith("https://") + + await new_file.download_to_drive(jpg_file) + + assert jpg_file.is_file() + + async def test_error_send_empty_file(self, bot, super_group_id): + chatphoto_file = open(os.devnull, "rb") + + with pytest.raises(TelegramError): + await bot.set_chat_photo(chat_id=super_group_id, photo=chatphoto_file) + + async def test_error_send_empty_file_id(self, bot, super_group_id): + with pytest.raises(TelegramError): + await bot.set_chat_photo(chat_id=super_group_id, photo="") + + async def test_error_send_without_required_args(self, bot, super_group_id): + with pytest.raises(TypeError): + await bot.set_chat_photo(chat_id=super_group_id) diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 636aeceeeec..05e41ad621a 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -22,22 +22,24 @@ from telegram import ChosenInlineResult, Location, User, Voice -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def user(): user = User(1, "First name", False) user._unfreeze() return user -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def chosen_inline_result(user): - return ChosenInlineResult(TestChosenInlineResult.result_id, user, TestChosenInlineResult.query) + return ChosenInlineResult(Space.result_id, user, Space.query) -class TestChosenInlineResult: +class Space: result_id = "result id" query = "query text" + +class TestChosenInlineResultNoReq: def test_slot_behaviour(self, chosen_inline_result, mro_slots): inst = chosen_inline_result for attr in inst.__slots__: @@ -45,29 +47,29 @@ def test_slot_behaviour(self, chosen_inline_result, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json_required(self, bot, user): - json_dict = {"result_id": self.result_id, "from": user.to_dict(), "query": self.query} + json_dict = {"result_id": Space.result_id, "from": user.to_dict(), "query": Space.query} result = ChosenInlineResult.de_json(json_dict, bot) assert result.api_kwargs == {} - assert result.result_id == self.result_id + assert result.result_id == Space.result_id assert result.from_user == user - assert result.query == self.query + assert result.query == Space.query def test_de_json_all(self, bot, user): loc = Location(-42.003, 34.004) json_dict = { - "result_id": self.result_id, + "result_id": Space.result_id, "from": user.to_dict(), - "query": self.query, + "query": Space.query, "location": loc.to_dict(), "inline_message_id": "a random id", } result = ChosenInlineResult.de_json(json_dict, bot) assert result.api_kwargs == {} - assert result.result_id == self.result_id + assert result.result_id == Space.result_id assert result.from_user == user - assert result.query == self.query + assert result.query == Space.query assert result.location == loc assert result.inline_message_id == "a random id" @@ -80,11 +82,11 @@ def test_to_dict(self, chosen_inline_result): 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, "", "") + a = ChosenInlineResult(Space.result_id, user, "Query", "") + b = ChosenInlineResult(Space.result_id, user, "Query", "") + c = ChosenInlineResult(Space.result_id, user, "", "") d = ChosenInlineResult("", user, "Query", "") - e = Voice(self.result_id, "unique_id", 0) + e = Voice(Space.result_id, "unique_id", 0) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_constants.py b/tests/test_constants.py index 0a37fa3e75d..e7908b3bc8a 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -36,7 +36,7 @@ class IntEnumTest(IntEnum): BAR = 2 -class TestConstants: +class TestConstantsNoReq: """Also test _utils.enum.StringEnum on the fly because tg.constants is currently the only place where that class is used.""" @@ -110,7 +110,26 @@ def test_int_inheritance(self): assert hash(IntEnumTest.FOO) == hash(1) - @pytest.mark.flaky(3, 1) + def test_bot_api_version_and_info(self): + assert constants.BOT_API_VERSION == str(constants.BOT_API_VERSION_INFO) + assert constants.BOT_API_VERSION_INFO == tuple( + int(x) for x in constants.BOT_API_VERSION.split(".") + ) + + def test_bot_api_version_info(self): + vi = constants.BOT_API_VERSION_INFO + assert isinstance(vi, tuple) + assert repr(vi) == f"BotAPIVersion(major={vi[0]}, minor={vi[1]})" + assert vi == (vi[0], vi[1]) + assert not (vi < (vi[0], vi[1])) + assert vi < (vi[0], vi[1] + 1) + assert vi < (vi[0] + 1, vi[1]) + assert vi < (vi[0] + 1, vi[1] + 1) + assert vi[0] == vi.major + assert vi[1] == vi.minor + + +class TestConstantsReq: async def test_max_message_length(self, bot, chat_id): await bot.send_message(chat_id=chat_id, text="a" * constants.MessageLimit.MAX_TEXT_LENGTH) @@ -122,7 +141,6 @@ async def test_max_message_length(self, bot, chat_id): chat_id=chat_id, text="a" * (constants.MessageLimit.MAX_TEXT_LENGTH + 1) ) - @pytest.mark.flaky(3, 1) async def test_max_caption_length(self, bot, chat_id): good_caption = "a" * constants.MessageLimit.CAPTION_LENGTH with data_file("telegram.png").open("rb") as f: @@ -133,21 +151,3 @@ async def test_max_caption_length(self, bot, chat_id): match = "Message caption is too long" with pytest.raises(BadRequest, match=match), data_file("telegram.png").open("rb") as f: await bot.send_photo(photo=f, caption=bad_caption, chat_id=chat_id) - - def test_bot_api_version_and_info(self): - assert constants.BOT_API_VERSION == str(constants.BOT_API_VERSION_INFO) - assert constants.BOT_API_VERSION_INFO == tuple( - int(x) for x in constants.BOT_API_VERSION.split(".") - ) - - def test_bot_api_version_info(self): - vi = constants.BOT_API_VERSION_INFO - assert isinstance(vi, tuple) - assert repr(vi) == f"BotAPIVersion(major={vi[0]}, minor={vi[1]})" - assert vi == (vi[0], vi[1]) - assert not (vi < (vi[0], vi[1])) - assert vi < (vi[0], vi[1] + 1) - assert vi < (vi[0] + 1, vi[1]) - assert vi < (vi[0] + 1, vi[1] + 1) - assert vi[0] == vi.major - assert vi[1] == vi.minor diff --git a/tests/test_contact.py b/tests/test_contact.py index d35280a39b0..dd9a12f7404 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -24,49 +24,51 @@ from telegram.request import RequestData -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def contact(): return Contact( - TestContact.phone_number, - TestContact.first_name, - TestContact.last_name, - TestContact.user_id, + Space.phone_number, + Space.first_name, + Space.last_name, + Space.user_id, ) -class TestContact: +class Space: phone_number = "+11234567890" first_name = "Leandro" last_name = "Toledo" user_id = 23 + +class TestContactNoReq: def test_slot_behaviour(self, contact, mro_slots): for attr in contact.__slots__: assert getattr(contact, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(contact)) == len(set(mro_slots(contact))), "duplicate slot" def test_de_json_required(self, bot): - json_dict = {"phone_number": self.phone_number, "first_name": self.first_name} + json_dict = {"phone_number": Space.phone_number, "first_name": Space.first_name} contact = Contact.de_json(json_dict, bot) assert contact.api_kwargs == {} - assert contact.phone_number == self.phone_number - assert contact.first_name == self.first_name + assert contact.phone_number == Space.phone_number + assert contact.first_name == Space.first_name 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, + "phone_number": Space.phone_number, + "first_name": Space.first_name, + "last_name": Space.last_name, + "user_id": Space.user_id, } contact = Contact.de_json(json_dict, bot) assert contact.api_kwargs == {} - 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 + assert contact.phone_number == Space.phone_number + assert contact.first_name == Space.first_name + assert contact.last_name == Space.last_name + assert contact.user_id == Space.user_id async def test_send_with_contact(self, monkeypatch, bot, chat_id, contact): async def make_assertion(url, request_data: RequestData, *args, **kwargs): @@ -80,7 +82,50 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): message = await bot.send_contact(contact=contact, chat_id=chat_id) assert message - @pytest.mark.flaky(3, 1) + async def test_send_contact_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match="Either contact or phone_number and first_name"): + await bot.send_contact(chat_id=chat_id) + + async def test_send_mutually_exclusive(self, bot, chat_id, contact): + with pytest.raises(ValueError, match="Not both"): + await bot.send_contact( + chat_id=chat_id, + contact=contact, + phone_number=contact.phone_number, + first_name=contact.first_name, + ) + + 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 = Contact(Space.phone_number, Space.first_name) + b = Contact(Space.phone_number, Space.first_name) + c = Contact(Space.phone_number, "") + d = Contact("", Space.first_name) + e = Voice("", "unique_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) + + +class TestContactReq: @pytest.mark.parametrize( "default_bot,custom", [ @@ -114,7 +159,6 @@ async def test_send_contact_default_allow_sending_without_reply( chat_id, contact=contact, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_contact_default_protect_content(self, chat_id, default_bot, contact): protected = await default_bot.send_contact(chat_id, contact=contact) @@ -123,45 +167,3 @@ async def test_send_contact_default_protect_content(self, chat_id, default_bot, chat_id, contact=contact, protect_content=False ) assert not unprotected.has_protected_content - - async def test_send_contact_without_required(self, bot, chat_id): - with pytest.raises(ValueError, match="Either contact or phone_number and first_name"): - await bot.send_contact(chat_id=chat_id) - - async def test_send_mutually_exclusive(self, bot, chat_id, contact): - with pytest.raises(ValueError, match="Not both"): - await bot.send_contact( - chat_id=chat_id, - contact=contact, - phone_number=contact.phone_number, - first_name=contact.first_name, - ) - - 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 = 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("", "unique_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_dice.py b/tests/test_dice.py index 39d37d7be40..573bbf22cb5 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -22,14 +22,16 @@ from telegram import BotCommand, Dice -@pytest.fixture(scope="class", params=Dice.ALL_EMOJI) +@pytest.fixture(scope="module", params=Dice.ALL_EMOJI) def dice(request): return Dice(value=5, emoji=request.param) -class TestDice: +class Space: value = 4 + +class TestDiceNoReq: def test_slot_behaviour(self, dice, mro_slots): for attr in dice.__slots__: assert getattr(dice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -37,11 +39,11 @@ def test_slot_behaviour(self, dice, mro_slots): @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI) def test_de_json(self, bot, emoji): - json_dict = {"value": self.value, "emoji": emoji} + json_dict = {"value": Space.value, "emoji": emoji} dice = Dice.de_json(json_dict, bot) assert dice.api_kwargs == {} - assert dice.value == self.value + assert dice.value == Space.value assert dice.emoji == emoji assert Dice.de_json(None, bot) is None diff --git a/tests/test_document.py b/tests/test_document.py index 1600eb45e0a..f00bf3b26fc 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -40,13 +40,13 @@ def document_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def document(bot, chat_id): with data_file("telegram.png").open("rb") as f: return (await bot.send_document(chat_id, document=f, read_timeout=50)).document -class TestDocument: +class Space: caption = "DocumentTest - *Caption*" document_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.gif" file_size = 12948 @@ -58,6 +58,8 @@ class TestDocument: document_file_id = "5a3128a4d2a04750b5b58397f3b5e812" document_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" + +class TestDocumentNoReq: def test_slot_behaviour(self, document, mro_slots): for attr in document.__slots__: assert getattr(document, attr, "err") != "err", f"got extra slot '{attr}'" @@ -71,19 +73,154 @@ def test_creation(self, document): assert document.file_unique_id != "" 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_height - - @pytest.mark.flaky(3, 1) + assert document.file_size == Space.file_size + assert document.mime_type == Space.mime_type + assert document.file_name == Space.file_name + assert document.thumb.file_size == Space.thumb_file_size + assert document.thumb.width == Space.thumb_width + assert document.thumb.height == Space.thumb_height + + @pytest.mark.parametrize("disable_content_type_detection", [True, False, None]) + async def test_send_with_document( + self, monkeypatch, bot, chat_id, document, disable_content_type_detection + ): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.parameters + type_detection = ( + data.get("disable_content_type_detection") == disable_content_type_detection + ) + return data["document"] == document.file_id and type_detection + + monkeypatch.setattr(bot.request, "post", make_assertion) + + message = await bot.send_document( + document=document, + chat_id=chat_id, + disable_content_type_detection=disable_content_type_detection, + ) + + assert message + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_document_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("document") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("document"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_document(chat_id, file, thumb=file) + assert test_flag + finally: + bot._local_mode = False + + def test_de_json(self, bot, document): + json_dict = { + "file_id": Space.document_file_id, + "file_unique_id": Space.document_file_unique_id, + "thumb": document.thumb.to_dict(), + "file_name": Space.file_name, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + } + test_document = Document.de_json(json_dict, bot) + assert test_document.api_kwargs == {} + + assert test_document.file_id == Space.document_file_id + assert test_document.file_unique_id == Space.document_file_unique_id + assert test_document.thumb == document.thumb + assert test_document.file_name == Space.file_name + assert test_document.mime_type == Space.mime_type + assert test_document.file_size == Space.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_unique_id"] == document.file_unique_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 + + async def test_error_send_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_document(chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, document): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == document.file_id + + assert check_shortcut_signature(Document.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(document.get_file, document.get_bot(), "get_file") + assert await check_defaults_handling(document.get_file, document.get_bot()) + + monkeypatch.setattr(document.get_bot(), "get_file", make_assertion) + assert await document.get_file() + + def test_equality(self, document): + a = Document(document.file_id, document.file_unique_id) + b = Document("", document.file_unique_id) + d = Document("", "") + e = Voice(document.file_id, document.file_unique_id, 0) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + +class TestDocumentReq: + async def test_error_send_empty_file(self, bot, chat_id): + with open(os.devnull, "rb") as f: + with pytest.raises(TelegramError): + await bot.send_document(chat_id=chat_id, document=f) + + async def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + await bot.send_document(chat_id=chat_id, document="") + + async def test_get_and_download(self, bot, document): + path = Path("telegram.png") + if path.is_file(): + path.unlink() + + new_file = await bot.get_file(document.file_id) + + assert new_file.file_size == document.file_size + assert new_file.file_id == document.file_id + assert new_file.file_unique_id == document.file_unique_id + assert new_file.file_path.startswith("https://") + + await new_file.download_to_drive("telegram.png") + + assert path.is_file() + + async def test_send_resend(self, bot, chat_id, document): + message = await bot.send_document(chat_id=chat_id, document=document.file_id) + assert message.document == document + async def test_send_all_args(self, bot, chat_id, document_file, document, thumb_file): message = await bot.send_document( chat_id, document=document_file, - caption=self.caption, + caption=Space.caption, disable_notification=False, protect_content=True, filename="telegram_custom.png", @@ -100,31 +237,13 @@ async def test_send_all_args(self, bot, chat_id, document_file, document, thumb_ 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.caption == self.caption.replace("*", "") - assert message.document.thumb.width == self.thumb_width - assert message.document.thumb.height == self.thumb_height + assert message.caption == Space.caption.replace("*", "") + assert message.document.thumb.width == Space.thumb_width + assert message.document.thumb.height == Space.thumb_height assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_get_and_download(self, bot, document): - path = Path("telegram.png") - if path.is_file(): - path.unlink() - - new_file = await bot.get_file(document.file_id) - - assert new_file.file_size == document.file_size - assert new_file.file_id == document.file_id - assert new_file.file_unique_id == document.file_unique_id - assert new_file.file_path.startswith("https://") - - await new_file.download_to_drive("telegram.png") - - assert path.is_file() - - @pytest.mark.flaky(3, 1) async def test_send_url_gif_file(self, bot, chat_id): - message = await bot.send_document(chat_id, self.document_file_url) + message = await bot.send_document(chat_id, Space.document_file_url) document = message.document @@ -138,34 +257,13 @@ async def test_send_url_gif_file(self, bot, chat_id): assert document.mime_type == "image/gif" assert document.file_size == 3878 - @pytest.mark.flaky(3, 1) - async def test_send_resend(self, bot, chat_id, document): - message = await bot.send_document(chat_id=chat_id, document=document.file_id) - - assert message.document == document - - @pytest.mark.parametrize("disable_content_type_detection", [True, False, None]) - async def test_send_with_document( - self, monkeypatch, bot, chat_id, document, disable_content_type_detection - ): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.parameters - type_detection = ( - data.get("disable_content_type_detection") == disable_content_type_detection - ) - return data["document"] == document.file_id and type_detection - - monkeypatch.setattr(bot.request, "post", make_assertion) - - message = await bot.send_document( - document=document, - chat_id=chat_id, - disable_content_type_detection=disable_content_type_detection, - ) - - assert message + @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) + async def test_send_document_default_protect_content(self, chat_id, default_bot, document): + protected = await default_bot.send_document(chat_id, document) + assert protected.has_protected_content + unprotected = await default_bot.send_document(chat_id, document, protect_content=False) + assert not unprotected.has_protected_content - @pytest.mark.flaky(3, 1) async def test_send_document_caption_entities(self, bot, chat_id, document): test_string = "Italic Bold Code" entities = [ @@ -180,7 +278,6 @@ async def test_send_document_caption_entities(self, bot, chat_id, document): assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_document_default_parse_mode_1(self, default_bot, chat_id, document): test_string = "Italic Bold Code" @@ -190,7 +287,6 @@ async def test_send_document_default_parse_mode_1(self, default_bot, chat_id, do assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_document_default_parse_mode_2(self, default_bot, chat_id, document): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -201,7 +297,6 @@ async def test_send_document_default_parse_mode_2(self, default_bot, chat_id, do assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_document_default_parse_mode_3(self, default_bot, chat_id, document): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -212,7 +307,6 @@ async def test_send_document_default_parse_mode_3(self, default_bot, chat_id, do assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -245,106 +339,3 @@ async def test_send_document_default_allow_sending_without_reply( await default_bot.send_document( chat_id, document, reply_to_message_id=reply_to_message.message_id ) - - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) - async def test_send_document_default_protect_content(self, chat_id, default_bot, document): - protected = await default_bot.send_document(chat_id, document) - assert protected.has_protected_content - unprotected = await default_bot.send_document(chat_id, document, protect_content=False) - assert not unprotected.has_protected_content - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_document_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("document") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("document"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_document(chat_id, file, thumb=file) - assert test_flag - finally: - bot._local_mode = False - - def test_de_json(self, bot, document): - json_dict = { - "file_id": self.document_file_id, - "file_unique_id": self.document_file_unique_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.api_kwargs == {} - - assert test_document.file_id == self.document_file_id - assert test_document.file_unique_id == self.document_file_unique_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_unique_id"] == document.file_unique_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 - - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file(self, bot, chat_id): - with open(os.devnull, "rb") as f: - with pytest.raises(TelegramError): - await bot.send_document(chat_id=chat_id, document=f) - - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file_id(self, bot, chat_id): - with pytest.raises(TelegramError): - await bot.send_document(chat_id=chat_id, document="") - - async def test_error_send_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_document(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, document): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == document.file_id - - assert check_shortcut_signature(Document.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(document.get_file, document.get_bot(), "get_file") - assert await check_defaults_handling(document.get_file, document.get_bot()) - - monkeypatch.setattr(document.get_bot(), "get_file", make_assertion) - assert await document.get_file() - - def test_equality(self, document): - a = Document(document.file_id, document.file_unique_id) - b = Document("", document.file_unique_id) - d = Document("", "") - e = Voice(document.file_id, document.file_unique_id, 0) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) diff --git a/tests/test_encryptedcredentials.py b/tests/test_encryptedcredentials.py index c56a6ce4244..dc94bfd7117 100644 --- a/tests/test_encryptedcredentials.py +++ b/tests/test_encryptedcredentials.py @@ -22,20 +22,18 @@ from telegram import EncryptedCredentials, PassportElementError -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def encrypted_credentials(): - return EncryptedCredentials( - TestEncryptedCredentials.data, - TestEncryptedCredentials.hash, - TestEncryptedCredentials.secret, - ) + return EncryptedCredentials(Space.data, Space.hash, Space.secret) -class TestEncryptedCredentials: +class Space: data = "data" hash = "hash" secret = "secret" + +class TestEncryptedCredentialsNoReq: def test_slot_behaviour(self, encrypted_credentials, mro_slots): inst = encrypted_credentials for attr in inst.__slots__: @@ -43,9 +41,9 @@ def test_slot_behaviour(self, encrypted_credentials, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, encrypted_credentials): - assert encrypted_credentials.data == self.data - assert encrypted_credentials.hash == self.hash - assert encrypted_credentials.secret == self.secret + assert encrypted_credentials.data == Space.data + assert encrypted_credentials.hash == Space.hash + assert encrypted_credentials.secret == Space.secret def test_to_dict(self, encrypted_credentials): encrypted_credentials_dict = encrypted_credentials.to_dict() @@ -56,11 +54,11 @@ def test_to_dict(self, encrypted_credentials): assert encrypted_credentials_dict["secret"] == encrypted_credentials.secret def test_equality(self): - a = EncryptedCredentials(self.data, self.hash, self.secret) - b = EncryptedCredentials(self.data, self.hash, self.secret) - c = EncryptedCredentials(self.data, "", "") - d = EncryptedCredentials("", self.hash, "") - e = EncryptedCredentials("", "", self.secret) + a = EncryptedCredentials(Space.data, Space.hash, Space.secret) + b = EncryptedCredentials(Space.data, Space.hash, Space.secret) + c = EncryptedCredentials(Space.data, "", "") + d = EncryptedCredentials("", Space.hash, "") + e = EncryptedCredentials("", "", Space.secret) f = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index f57193d1a7a..a7399050947 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="class") def encrypted_passport_element(): return EncryptedPassportElement( - TestEncryptedPassportElement.type_, + Space.type_, "this is a hash", - data=TestEncryptedPassportElement.data, - phone_number=TestEncryptedPassportElement.phone_number, - email=TestEncryptedPassportElement.email, - files=TestEncryptedPassportElement.files, - front_side=TestEncryptedPassportElement.front_side, - reverse_side=TestEncryptedPassportElement.reverse_side, - selfie=TestEncryptedPassportElement.selfie, + data=Space.data, + phone_number=Space.phone_number, + email=Space.email, + files=Space.files, + front_side=Space.front_side, + reverse_side=Space.reverse_side, + selfie=Space.selfie, ) -class TestEncryptedPassportElement: +class Space: type_ = "type" hash = "this is a hash" data = "data" @@ -48,6 +48,8 @@ class TestEncryptedPassportElement: reverse_side = PassportFile("file_id", 50, 0, 25) selfie = PassportFile("file_id", 50, 0, 25) + +class TestEncryptedPassportElementNoReq: def test_slot_behaviour(self, encrypted_passport_element, mro_slots): inst = encrypted_passport_element for attr in inst.__slots__: @@ -55,15 +57,15 @@ def test_slot_behaviour(self, encrypted_passport_element, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, encrypted_passport_element): - assert encrypted_passport_element.type == self.type_ - assert encrypted_passport_element.hash == self.hash - assert encrypted_passport_element.data == self.data - assert encrypted_passport_element.phone_number == self.phone_number - assert encrypted_passport_element.email == self.email - assert encrypted_passport_element.files == tuple(self.files) - assert encrypted_passport_element.front_side == self.front_side - assert encrypted_passport_element.reverse_side == self.reverse_side - assert encrypted_passport_element.selfie == self.selfie + assert encrypted_passport_element.type == Space.type_ + assert encrypted_passport_element.hash == Space.hash + assert encrypted_passport_element.data == Space.data + assert encrypted_passport_element.phone_number == Space.phone_number + assert encrypted_passport_element.email == Space.email + assert encrypted_passport_element.files == tuple(Space.files) + assert encrypted_passport_element.front_side == Space.front_side + assert encrypted_passport_element.reverse_side == Space.reverse_side + assert encrypted_passport_element.selfie == Space.selfie def test_to_dict(self, encrypted_passport_element): encrypted_passport_element_dict = encrypted_passport_element.to_dict() @@ -91,14 +93,14 @@ def test_to_dict(self, encrypted_passport_element): ) def test_attributes_always_tuple(self): - element = EncryptedPassportElement(self.type_, self.hash) + element = EncryptedPassportElement(Space.type_, Space.hash) assert element.files == () assert element.translation == () def test_equality(self): - a = EncryptedPassportElement(self.type_, self.hash, data=self.data) - b = EncryptedPassportElement(self.type_, self.hash, data=self.data) - c = EncryptedPassportElement(self.data, "") + a = EncryptedPassportElement(Space.type_, Space.hash, data=Space.data) + b = EncryptedPassportElement(Space.type_, Space.hash, data=Space.data) + c = EncryptedPassportElement(Space.data, "") d = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_file.py b/tests/test_file.py index 91fd3a3c880..99d0f9e3702 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -27,20 +27,20 @@ from tests.conftest import data_file -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def file(bot): file = File( - TestFile.file_id, - TestFile.file_unique_id, - file_path=TestFile.file_path, - file_size=TestFile.file_size, + Space.file_id, + Space.file_unique_id, + file_path=Space.file_path, + file_size=Space.file_size, ) file.set_bot(bot) file._unfreeze() return file -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def encrypted_file(bot): # check https://github.com/python-telegram-bot/python-telegram-bot/wiki/\ # PTB-test-writing-knowledge-base#how-to-generate-encrypted-passport-files @@ -49,13 +49,13 @@ def encrypted_file(bot): "Oq3G4sX+bKZthoyms1YlPqvWou9esb+z0Bi/KqQUG8s=", "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) - ef = File(TestFile.file_id, TestFile.file_unique_id, TestFile.file_size, TestFile.file_path) + ef = File(Space.file_id, Space.file_unique_id, Space.file_size, Space.file_path) ef.set_bot(bot) ef.set_credentials(fc) return ef -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def encrypted_local_file(bot): # check encrypted_file() for the source of the fc values fc = FileCredentials( @@ -63,9 +63,9 @@ def encrypted_local_file(bot): "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) ef = File( - TestFile.file_id, - TestFile.file_unique_id, - TestFile.file_size, + Space.file_id, + Space.file_unique_id, + Space.file_size, file_path=str(data_file("image_encrypted.jpg")), ) ef.set_bot(bot) @@ -73,19 +73,19 @@ def encrypted_local_file(bot): return ef -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def local_file(bot): file = File( - TestFile.file_id, - TestFile.file_unique_id, + Space.file_id, + Space.file_unique_id, file_path=str(data_file("local_file.txt")), - file_size=TestFile.file_size, + file_size=Space.file_size, ) file.set_bot(bot) return file -class TestFile: +class Space: file_id = "NOTVALIDDOESNOTMATTER" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_path = ( @@ -94,6 +94,8 @@ class TestFile: file_size = 28232 file_content = "Saint-Saëns".encode() # Intentionally contains unicode chars. + +class TestFileNoReq: def test_slot_behaviour(self, file, mro_slots): for attr in file.__slots__: assert getattr(file, attr, "err") != "err", f"got extra slot '{attr}'" @@ -101,18 +103,18 @@ def test_slot_behaviour(self, file, mro_slots): def test_de_json(self, bot): json_dict = { - "file_id": self.file_id, - "file_unique_id": self.file_unique_id, - "file_path": self.file_path, - "file_size": self.file_size, + "file_id": Space.file_id, + "file_unique_id": Space.file_unique_id, + "file_path": Space.file_path, + "file_size": Space.file_size, } new_file = File.de_json(json_dict, bot) assert new_file.api_kwargs == {} - assert new_file.file_id == self.file_id - assert new_file.file_unique_id == self.file_unique_id - assert new_file.file_path == self.file_path - assert new_file.file_size == self.file_size + assert new_file.file_id == Space.file_id + assert new_file.file_unique_id == Space.file_unique_id + assert new_file.file_path == Space.file_path + assert new_file.file_size == Space.file_size def test_to_dict(self, file): file_dict = file.to_dict() @@ -123,32 +125,24 @@ def test_to_dict(self, file): assert file_dict["file_path"] == file.file_path assert file_dict["file_size"] == file.file_size - @pytest.mark.flaky(3, 1) - async def test_error_get_empty_file_id(self, bot): - with pytest.raises(TelegramError): - await bot.get_file(file_id="") - async def test_download(self, monkeypatch, file): async def test(*args, **kwargs): - return self.file_content + return Space.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) out_file = await file.download_to_drive() try: - assert out_file.read_bytes() == self.file_content + assert out_file.read_bytes() == Space.file_content finally: out_file.unlink() - async def test_download_local_file(self, local_file): - assert await local_file.download_to_drive() == Path(local_file.file_path) - @pytest.mark.parametrize( "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] ) async def test_download_custom_path(self, monkeypatch, file, custom_path_type): async def test(*args, **kwargs): - return self.file_content + return Space.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) file_handle, custom_path = mkstemp() @@ -156,28 +150,14 @@ async def test(*args, **kwargs): try: out_file = await file.download_to_drive(custom_path_type(custom_path)) assert out_file == custom_path - assert out_file.read_bytes() == self.file_content - finally: - os.close(file_handle) - custom_path.unlink() - - @pytest.mark.parametrize( - "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] - ) - async def test_download_custom_path_local_file(self, local_file, custom_path_type): - file_handle, custom_path = mkstemp() - custom_path = Path(custom_path) - try: - out_file = await local_file.download_to_drive(custom_path_type(custom_path)) - assert out_file == custom_path - assert out_file.read_bytes() == self.file_content + assert out_file.read_bytes() == Space.file_content finally: os.close(file_handle) custom_path.unlink() async def test_download_no_filename(self, monkeypatch, file): async def test(*args, **kwargs): - return self.file_content + return Space.file_content file.file_path = None @@ -186,35 +166,29 @@ async def test(*args, **kwargs): assert str(out_file)[-len(file.file_id) :] == file.file_id try: - assert out_file.read_bytes() == self.file_content + assert out_file.read_bytes() == Space.file_content finally: out_file.unlink() async def test_download_file_obj(self, monkeypatch, file): async def test(*args, **kwargs): - return self.file_content + return Space.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) with TemporaryFile() as custom_fobj: await file.download_to_memory(out=custom_fobj) custom_fobj.seek(0) - assert custom_fobj.read() == self.file_content - - async def test_download_file_obj_local_file(self, local_file): - with TemporaryFile() as custom_fobj: - await local_file.download_to_memory(out=custom_fobj) - custom_fobj.seek(0) - assert custom_fobj.read() == self.file_content + assert custom_fobj.read() == Space.file_content async def test_download_bytearray(self, monkeypatch, file): async def test(*args, **kwargs): - return self.file_content + return Space.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) # Check that a download to a newly allocated bytearray works. buf = await file.download_as_bytearray() - assert buf == bytearray(self.file_content) + assert buf == bytearray(Space.file_content) # Check that a download to a given bytearray works (extends the bytearray). buf2 = buf[:] @@ -223,18 +197,6 @@ async def test(*args, **kwargs): assert buf2[len(buf) :] == buf assert buf2[: len(buf)] == buf - async def test_download_bytearray_local_file(self, local_file): - # Check that a download to a newly allocated bytearray works. - buf = await local_file.download_as_bytearray() - assert buf == bytearray(self.file_content) - - # Check that a download to a given bytearray works (extends the bytearray). - buf2 = buf[:] - buf3 = await local_file.download_as_bytearray(buf=buf2) - assert buf3 is buf2 - assert buf2[len(buf) :] == buf - assert buf2[: len(buf)] == buf - async def test_download_encrypted(self, monkeypatch, bot, encrypted_file): async def test(*args, **kwargs): return data_file("image_encrypted.jpg").read_bytes() @@ -257,13 +219,6 @@ async def test(*args, **kwargs): custom_fobj.seek(0) assert custom_fobj.read() == data_file("image_decrypted.jpg").read_bytes() - async def test_download_local_file_encrypted(self, encrypted_local_file): - out_file = await encrypted_local_file.download_to_drive() - try: - assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes() - finally: - out_file.unlink() - @pytest.mark.parametrize( "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] ) @@ -307,24 +262,12 @@ async def test(*args, **kwargs): assert buf2[len(buf) :] == buf assert buf2[: len(buf)] == buf - async def test_download_bytearray_local_file_encrypted(self, encrypted_local_file): - # Check that a download to a newly allocated bytearray works. - buf = await encrypted_local_file.download_as_bytearray() - assert buf == bytearray(data_file("image_decrypted.jpg").read_bytes()) - - # Check that a download to a given bytearray works (extends the bytearray). - buf2 = buf[:] - buf3 = await encrypted_local_file.download_as_bytearray(buf=buf2) - assert buf3 is buf2 - assert buf2[len(buf) :] == buf - assert buf2[: len(buf)] == buf - def test_equality(self, bot): - a = File(self.file_id, self.file_unique_id, bot) - b = File("", self.file_unique_id, bot) - c = File(self.file_id, self.file_unique_id, None) + a = File(Space.file_id, Space.file_unique_id, bot) + b = File("", Space.file_unique_id, bot) + c = File(Space.file_id, Space.file_unique_id, None) d = File("", "", bot) - e = Voice(self.file_id, self.file_unique_id, 0) + e = Voice(Space.file_id, Space.file_unique_id, 0) assert a == b assert hash(a) == hash(b) @@ -338,3 +281,63 @@ def test_equality(self, bot): assert a != e assert hash(a) != hash(e) + + +class TestFileReq: + async def test_error_get_empty_file_id(self, bot): + with pytest.raises(TelegramError): + await bot.get_file(file_id="") + + async def test_download_local_file(self, local_file): + assert await local_file.download_to_drive() == Path(local_file.file_path) + + @pytest.mark.parametrize( + "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] + ) + async def test_download_custom_path_local_file(self, local_file, custom_path_type): + file_handle, custom_path = mkstemp() + custom_path = Path(custom_path) + try: + out_file = await local_file.download_to_drive(custom_path_type(custom_path)) + assert out_file == custom_path + assert out_file.read_bytes() == Space.file_content + finally: + os.close(file_handle) + custom_path.unlink() + + async def test_download_file_obj_local_file(self, local_file): + with TemporaryFile() as custom_fobj: + await local_file.download_to_memory(out=custom_fobj) + custom_fobj.seek(0) + assert custom_fobj.read() == Space.file_content + + async def test_download_local_file_encrypted(self, encrypted_local_file): + out_file = await encrypted_local_file.download_to_drive() + try: + assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes() + finally: + out_file.unlink() + + async def test_download_bytearray_local_file(self, local_file): + # Check that a download to a newly allocated bytearray works. + buf = await local_file.download_as_bytearray() + assert buf == bytearray(Space.file_content) + + # Check that a download to a given bytearray works (extends the bytearray). + buf2 = buf[:] + buf3 = await local_file.download_as_bytearray(buf=buf2) + assert buf3 is buf2 + assert buf2[len(buf) :] == buf + assert buf2[: len(buf)] == buf + + async def test_download_bytearray_local_file_encrypted(self, encrypted_local_file): + # Check that a download to a newly allocated bytearray works. + buf = await encrypted_local_file.download_as_bytearray() + assert buf == bytearray(data_file("image_decrypted.jpg").read_bytes()) + + # Check that a download to a given bytearray works (extends the bytearray). + buf2 = buf[:] + buf3 = await encrypted_local_file.download_as_bytearray(buf=buf2) + assert buf3 is buf2 + assert buf2[len(buf) :] == buf + assert buf2[: len(buf)] == buf diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index 1b41ddfa776..4585c0a2a5a 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -22,34 +22,27 @@ from telegram import ForceReply, ReplyKeyboardRemove -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def force_reply(): - return ForceReply( - TestForceReply.selective, - TestForceReply.input_field_placeholder, - ) + return ForceReply(Space.selective, Space.input_field_placeholder) -class TestForceReply: +class Space: force_reply = True selective = True input_field_placeholder = "force replies can be annoying if not used properly" + +class TestForceReplyNoReq: def test_slot_behaviour(self, force_reply, mro_slots): for attr in force_reply.__slots__: assert getattr(force_reply, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(force_reply)) == len(set(mro_slots(force_reply))), "duplicate slot" - @pytest.mark.flaky(3, 1) - async def test_send_message_with_force_reply(self, bot, chat_id, force_reply): - message = await 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 - assert force_reply.input_field_placeholder == self.input_field_placeholder + assert force_reply.force_reply == Space.force_reply + assert force_reply.selective == Space.selective + assert force_reply.input_field_placeholder == Space.input_field_placeholder def test_to_dict(self, force_reply): force_reply_dict = force_reply.to_dict() @@ -73,3 +66,9 @@ def test_equality(self): assert a != d assert hash(a) != hash(d) + + +class TestForceReplyReq: + async def test_send_message_with_force_reply(self, bot, chat_id, force_reply): + message = await bot.send_message(chat_id, "text", reply_markup=force_reply) + assert message.text == "text" diff --git a/tests/test_forum.py b/tests/test_forum.py index d903d3e3d1a..bc5e017789c 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -32,7 +32,7 @@ async def emoji_id(bot): return first_sticker.custom_emoji_id -@pytest.fixture +@pytest.fixture(scope="module") async def forum_topic_object(forum_group_id, emoji_id): return ForumTopic( message_thread_id=forum_group_id, @@ -42,7 +42,7 @@ async def forum_topic_object(forum_group_id, emoji_id): ) -@pytest.fixture +@pytest.fixture(scope="module") async def real_topic(bot, emoji_id, forum_group_id): result = await bot.create_forum_topic( chat_id=forum_group_id, @@ -59,7 +59,7 @@ async def real_topic(bot, emoji_id, forum_group_id): assert result is True, "Topic was not deleted" -class TestForumTopic: +class TestForumTopicNoReq: def test_slot_behaviour(self, mro_slots, forum_topic_object): for attr in forum_topic_object.__slots__: assert getattr(forum_topic_object, attr, "err") != "err", f"got extra slot '{attr}'" @@ -139,7 +139,8 @@ def test_equality(self, emoji_id, forum_group_id): assert a != e assert hash(a) != hash(e) - @pytest.mark.flaky(3, 1) + +class TestForumTopicReq: async def test_create_forum_topic(self, real_topic): result = real_topic assert isinstance(result, ForumTopic) @@ -161,7 +162,6 @@ async def test_create_forum_topic_with_only_required_args(self, bot, forum_group ) assert result is True, "Failed to delete forum topic" - @pytest.mark.flaky(3, 1) async def test_get_forum_topic_icon_stickers(self, bot): emoji_sticker_list = await bot.get_forum_topic_icon_stickers() first_sticker = emoji_sticker_list[0] @@ -194,7 +194,6 @@ async def test_edit_forum_topic(self, emoji_id, forum_group_id, bot, real_topic) assert result is True, "Failed to edit forum topic" # no way of checking the edited name, just the boolean result - @pytest.mark.flaky(3, 1) async def test_send_message_to_topic(self, bot, forum_group_id, real_topic): message_thread_id = real_topic.message_thread_id @@ -245,12 +244,12 @@ async def test_unpin_all_forum_topic_messages(self, bot, forum_group_id, real_to assert result is True, "Failed to unpin all the messages in forum topic" -@pytest.fixture +@pytest.fixture(scope="module") def topic_created(): return ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR) -class TestForumTopicCreated: +class TestForumTopicCreatedNoReq: def test_slot_behaviour(self, topic_created, mro_slots): for attr in topic_created.__slots__: assert getattr(topic_created, attr, "err") != "err", f"got extra slot '{attr}'" @@ -299,7 +298,7 @@ def test_equality(self, emoji_id): assert hash(a) != hash(d) -class TestForumTopicClosed: +class TestForumTopicClosedNoReq: def test_slot_behaviour(self, mro_slots): action = ForumTopicClosed() for attr in action.__slots__: @@ -317,7 +316,7 @@ def test_to_dict(self): assert action_dict == {} -class TestForumTopicReopened: +class TestForumTopicReopenedNoReq: def test_slot_behaviour(self, mro_slots): action = ForumTopicReopened() for attr in action.__slots__: diff --git a/tests/test_game.py b/tests/test_game.py index dc775016467..9c63cac0a29 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -22,21 +22,21 @@ from telegram import Animation, Game, MessageEntity, PhotoSize -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def game(): game = Game( - TestGame.title, - TestGame.description, - TestGame.photo, - text=TestGame.text, - text_entities=TestGame.text_entities, - animation=TestGame.animation, + Space.title, + Space.description, + Space.photo, + text=Space.text, + text_entities=Space.text_entities, + animation=Space.animation, ) game._unfreeze() return game -class TestGame: +class Space: title = "Python-telegram-bot Test Game" description = "description" photo = [PhotoSize("Blah", "ElseBlah", 640, 360, file_size=0)] @@ -47,6 +47,8 @@ class TestGame: text_entities = [MessageEntity(13, 17, MessageEntity.URL)] animation = Animation("blah", "unique_id", 320, 180, 1) + +class TestGameNoReq: def test_slot_behaviour(self, game, mro_slots): for attr in game.__slots__: assert getattr(game, attr, "err") != "err", f"got extra slot '{attr}'" @@ -54,35 +56,35 @@ def test_slot_behaviour(self, game, mro_slots): def test_de_json_required(self, bot): json_dict = { - "title": self.title, - "description": self.description, - "photo": [self.photo[0].to_dict()], + "title": Space.title, + "description": Space.description, + "photo": [Space.photo[0].to_dict()], } game = Game.de_json(json_dict, bot) assert game.api_kwargs == {} - assert game.title == self.title - assert game.description == self.description - assert game.photo == tuple(self.photo) + assert game.title == Space.title + assert game.description == Space.description + assert game.photo == tuple(Space.photo) 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(), + "title": Space.title, + "description": Space.description, + "photo": [Space.photo[0].to_dict()], + "text": Space.text, + "text_entities": [Space.text_entities[0].to_dict()], + "animation": Space.animation.to_dict(), } game = Game.de_json(json_dict, bot) assert game.api_kwargs == {} - assert game.title == self.title - assert game.description == self.description - assert game.photo == tuple(self.photo) - assert game.text == self.text - assert game.text_entities == tuple(self.text_entities) - assert game.animation == self.animation + assert game.title == Space.title + assert game.description == Space.description + assert game.photo == tuple(Space.photo) + assert game.text == Space.text + assert game.text_entities == tuple(Space.text_entities) + assert game.animation == Space.animation def test_to_dict(self, game): game_dict = game.to_dict() diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py index 43ebbe99312..669ddf2d62f 100644 --- a/tests/test_gamehighscore.py +++ b/tests/test_gamehighscore.py @@ -22,31 +22,35 @@ from telegram import GameHighScore, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def game_highscore(): - return GameHighScore( - TestGameHighScore.position, TestGameHighScore.user, TestGameHighScore.score - ) + return GameHighScore(Space.position, Space.user, Space.score) -class TestGameHighScore: +class Space: position = 12 user = User(2, "test user", False) score = 42 + +class TestGameHighScoreNoReq: def test_slot_behaviour(self, game_highscore, mro_slots): for attr in game_highscore.__slots__: assert getattr(game_highscore, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(game_highscore)) == len(set(mro_slots(game_highscore))), "same slot" def test_de_json(self, bot): - json_dict = {"position": self.position, "user": self.user.to_dict(), "score": self.score} + json_dict = { + "position": Space.position, + "user": Space.user.to_dict(), + "score": Space.score, + } highscore = GameHighScore.de_json(json_dict, bot) assert highscore.api_kwargs == {} - assert highscore.position == self.position - assert highscore.user == self.user - assert highscore.score == self.score + assert highscore.position == Space.position + assert highscore.user == Space.user + assert highscore.score == Space.score assert GameHighScore.de_json(None, bot) is None diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index dad079ead7a..d4e64e7cff1 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -22,22 +22,22 @@ from telegram import CallbackGame, InlineKeyboardButton, LoginUrl, WebAppInfo -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - login_url=TestInlineKeyboardButton.login_url, - web_app=TestInlineKeyboardButton.web_app, + Space.text, + url=Space.url, + callback_data=Space.callback_data, + switch_inline_query=Space.switch_inline_query, + switch_inline_query_current_chat=Space.switch_inline_query_current_chat, + callback_game=Space.callback_game, + pay=Space.pay, + login_url=Space.login_url, + web_app=Space.web_app, ) -class TestInlineKeyboardButton: +class Space: text = "text" url = "url" callback_data = "callback data" @@ -48,6 +48,8 @@ class TestInlineKeyboardButton: login_url = LoginUrl("http://google.com") web_app = WebAppInfo(url="https://example.com") + +class TestInlineKeyboardButtonNoReq: def test_slot_behaviour(self, inline_keyboard_button, mro_slots): inst = inline_keyboard_button for attr in inst.__slots__: @@ -55,18 +57,18 @@ def test_slot_behaviour(self, inline_keyboard_button, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_keyboard_button): - 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.text == Space.text + assert inline_keyboard_button.url == Space.url + assert inline_keyboard_button.callback_data == Space.callback_data + assert inline_keyboard_button.switch_inline_query == Space.switch_inline_query assert ( inline_keyboard_button.switch_inline_query_current_chat - == self.switch_inline_query_current_chat + == Space.switch_inline_query_current_chat ) assert isinstance(inline_keyboard_button.callback_game, CallbackGame) - assert inline_keyboard_button.pay == self.pay - assert inline_keyboard_button.login_url == self.login_url - assert inline_keyboard_button.web_app == self.web_app + assert inline_keyboard_button.pay == Space.pay + assert inline_keyboard_button.login_url == Space.login_url + assert inline_keyboard_button.web_app == Space.web_app def test_to_dict(self, inline_keyboard_button): inline_keyboard_button_dict = inline_keyboard_button.to_dict() @@ -95,32 +97,32 @@ def test_to_dict(self, inline_keyboard_button): 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_current_chat": self.switch_inline_query_current_chat, - "callback_game": self.callback_game.to_dict(), - "web_app": self.web_app.to_dict(), - "login_url": self.login_url.to_dict(), - "pay": self.pay, + "text": Space.text, + "url": Space.url, + "callback_data": Space.callback_data, + "switch_inline_query": Space.switch_inline_query, + "switch_inline_query_current_chat": Space.switch_inline_query_current_chat, + "callback_game": Space.callback_game.to_dict(), + "web_app": Space.web_app.to_dict(), + "login_url": Space.login_url.to_dict(), + "pay": Space.pay, } inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, None) assert inline_keyboard_button.api_kwargs == {} - 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.text == Space.text + assert inline_keyboard_button.url == Space.url + assert inline_keyboard_button.callback_data == Space.callback_data + assert inline_keyboard_button.switch_inline_query == Space.switch_inline_query assert ( inline_keyboard_button.switch_inline_query_current_chat - == self.switch_inline_query_current_chat + == Space.switch_inline_query_current_chat ) # CallbackGame has empty _id_attrs, so just test if the class is created. assert isinstance(inline_keyboard_button.callback_game, CallbackGame) - assert inline_keyboard_button.pay == self.pay - assert inline_keyboard_button.login_url == self.login_url - assert inline_keyboard_button.web_app == self.web_app + assert inline_keyboard_button.pay == Space.pay + assert inline_keyboard_button.login_url == Space.login_url + assert inline_keyboard_button.web_app == Space.web_app none = InlineKeyboardButton.de_json({}, bot) assert none is None diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index d852f685bf7..1c63e14624d 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -28,12 +28,12 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_keyboard_markup(): - return InlineKeyboardMarkup(TestInlineKeyboardMarkup.inline_keyboard) + return InlineKeyboardMarkup(Space.inline_keyboard) -class TestInlineKeyboardMarkup: +class Space: inline_keyboard = [ [ InlineKeyboardButton(text="button1", callback_data="data1"), @@ -41,22 +41,14 @@ class TestInlineKeyboardMarkup: ] ] + +class TestInlineKeyboardMarkupNoReq: def test_slot_behaviour(self, inline_keyboard_markup, mro_slots): inst = inline_keyboard_markup for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - @pytest.mark.flaky(3, 1) - async def test_send_message_with_inline_keyboard_markup( - self, bot, chat_id, inline_keyboard_markup - ): - message = await bot.send_message( - chat_id, "Testing InlineKeyboardMarkup", reply_markup=inline_keyboard_markup - ) - - assert message.text == "Testing InlineKeyboardMarkup" - def test_from_button(self): inline_keyboard_markup = InlineKeyboardMarkup.from_button( InlineKeyboardButton(text="button1", callback_data="data1") @@ -87,7 +79,7 @@ def test_from_column(self): def test_expected_values(self, inline_keyboard_markup): assert inline_keyboard_markup.inline_keyboard == tuple( - tuple(row) for row in self.inline_keyboard + tuple(row) for row in Space.inline_keyboard ) def test_wrong_keyboard_inputs(self): @@ -142,7 +134,7 @@ def test_to_dict(self, inline_keyboard_markup): 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()] + [Space.inline_keyboard[0][0].to_dict(), Space.inline_keyboard[0][1].to_dict()] ] def test_de_json(self): @@ -231,3 +223,14 @@ def test_equality(self): assert a != g assert hash(a) != hash(g) + + +class TestInlineKeyborardMarkupReq: + async def test_send_message_with_inline_keyboard_markup( + self, bot, chat_id, inline_keyboard_markup + ): + message = await bot.send_message( + chat_id, "Testing InlineKeyboardMarkup", reply_markup=inline_keyboard_markup + ) + + assert message.text == "Testing InlineKeyboardMarkup" diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 86d14453092..a99cd6ee42b 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -27,26 +27,28 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query(bot): ilq = InlineQuery( - TestInlineQuery.id_, - TestInlineQuery.from_user, - TestInlineQuery.query, - TestInlineQuery.offset, - location=TestInlineQuery.location, + Space.id_, + Space.from_user, + Space.query, + Space.offset, + location=Space.location, ) ilq.set_bot(bot) return ilq -class TestInlineQuery: +class Space: id_ = 1234 from_user = User(1, "First name", False) query = "query text" offset = "offset" location = Location(8.8, 53.1) + +class TestInlineQueryNoReq: def test_slot_behaviour(self, inline_query, mro_slots): for attr in inline_query.__slots__: assert getattr(inline_query, attr, "err") != "err", f"got extra slot '{attr}'" @@ -54,20 +56,20 @@ def test_slot_behaviour(self, inline_query, mro_slots): 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(), + "id": Space.id_, + "from": Space.from_user.to_dict(), + "query": Space.query, + "offset": Space.offset, + "location": Space.location.to_dict(), } inline_query_json = InlineQuery.de_json(json_dict, bot) assert inline_query_json.api_kwargs == {} - 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 + assert inline_query_json.id == Space.id_ + assert inline_query_json.from_user == Space.from_user + assert inline_query_json.location == Space.location + assert inline_query_json.query == Space.query + assert inline_query_json.offset == Space.offset def test_to_dict(self, inline_query): inline_query_dict = inline_query.to_dict() @@ -108,11 +110,11 @@ async def make_assertion(*_, **kwargs): assert await inline_query.answer(results=[], auto_pagination=True) def test_equality(self): - a = InlineQuery(self.id_, User(1, "", False), "", "") - b = InlineQuery(self.id_, User(1, "", False), "", "") - c = InlineQuery(self.id_, User(0, "", False), "", "") + a = InlineQuery(Space.id_, User(1, "", False), "", "") + b = InlineQuery(Space.id_, User(1, "", False), "", "") + c = InlineQuery(Space.id_, User(0, "", False), "", "") d = InlineQuery(0, User(1, "", False), "", "") - e = Update(self.id_) + e = Update(Space.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index 67626d54c38..3d93580f976 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -28,23 +28,23 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, + Space.id_, + Space.title, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, + url=Space.url, + hide_url=Space.hide_url, + description=Space.description, + thumb_url=Space.thumb_url, + thumb_height=Space.thumb_height, + thumb_width=Space.thumb_width, ) -class TestInlineQueryResultArticle: +class Space: id_ = "id" type_ = "article" title = "title" @@ -57,6 +57,8 @@ class TestInlineQueryResultArticle: thumb_height = 10 thumb_width = 15 + +class TestInlineQueryResultArticleNoReq: def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): inst = inline_query_result_article for attr in inst.__slots__: @@ -64,20 +66,20 @@ def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.type == Space.type_ + assert inline_query_result_article.id == Space.id_ + assert inline_query_result_article.title == Space.title assert ( inline_query_result_article.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.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 + assert inline_query_result_article.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_article.url == Space.url + assert inline_query_result_article.hide_url == Space.hide_url + assert inline_query_result_article.description == Space.description + assert inline_query_result_article.thumb_url == Space.thumb_url + assert inline_query_result_article.thumb_height == Space.thumb_height + assert inline_query_result_article.thumb_width == Space.thumb_width def test_to_dict(self, inline_query_result_article): inline_query_result_article_dict = inline_query_result_article.to_dict() @@ -113,11 +115,11 @@ def test_to_dict(self, inline_query_result_article): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultArticle(Space.id_, Space.title, Space.input_message_content) + b = InlineQueryResultArticle(Space.id_, Space.title, Space.input_message_content) + c = InlineQueryResultArticle(Space.id_, "", Space.input_message_content) + d = InlineQueryResultArticle("", Space.title, Space.input_message_content) + e = InlineQueryResultAudio(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index e7056f62465..a0b084d153f 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -29,23 +29,23 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - parse_mode=TestInlineQueryResultAudio.parse_mode, - caption_entities=TestInlineQueryResultAudio.caption_entities, - input_message_content=TestInlineQueryResultAudio.input_message_content, - reply_markup=TestInlineQueryResultAudio.reply_markup, + Space.id_, + Space.audio_url, + Space.title, + performer=Space.performer, + audio_duration=Space.audio_duration, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultAudio: +class Space: id_ = "id" type_ = "audio" audio_url = "audio url" @@ -58,6 +58,8 @@ class TestInlineQueryResultAudio: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultAudioNoReq: def test_slot_behaviour(self, inline_query_result_audio, mro_slots): inst = inline_query_result_audio for attr in inst.__slots__: @@ -65,20 +67,20 @@ def test_slot_behaviour(self, inline_query_result_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_audio.caption_entities == tuple(self.caption_entities) + assert inline_query_result_audio.type == Space.type_ + assert inline_query_result_audio.id == Space.id_ + assert inline_query_result_audio.audio_url == Space.audio_url + assert inline_query_result_audio.title == Space.title + assert inline_query_result_audio.performer == Space.performer + assert inline_query_result_audio.audio_duration == Space.audio_duration + assert inline_query_result_audio.caption == Space.caption + assert inline_query_result_audio.parse_mode == Space.parse_mode + assert inline_query_result_audio.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_audio.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_audio.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_audio.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_to_dict(self, inline_query_result_audio): inline_query_result_audio_dict = inline_query_result_audio.to_dict() @@ -108,15 +110,15 @@ def test_to_dict(self, inline_query_result_audio): ) def test_caption_entities_always_tuple(self): - inline_query_result_audio = InlineQueryResultAudio(self.id_, self.audio_url, self.title) + inline_query_result_audio = InlineQueryResultAudio(Space.id_, Space.audio_url, Space.title) assert inline_query_result_audio.caption_entities == () def test_equality(self): - 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_, "", "") + a = InlineQueryResultAudio(Space.id_, Space.audio_url, Space.title) + b = InlineQueryResultAudio(Space.id_, Space.title, Space.title) + c = InlineQueryResultAudio(Space.id_, "", Space.title) + d = InlineQueryResultAudio("", Space.audio_url, Space.title) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index ac654e915a5..d1c56de3403 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -29,20 +29,20 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_audio(): return InlineQueryResultCachedAudio( - TestInlineQueryResultCachedAudio.id_, - TestInlineQueryResultCachedAudio.audio_file_id, - caption=TestInlineQueryResultCachedAudio.caption, - parse_mode=TestInlineQueryResultCachedAudio.parse_mode, - caption_entities=TestInlineQueryResultCachedAudio.caption_entities, - input_message_content=TestInlineQueryResultCachedAudio.input_message_content, - reply_markup=TestInlineQueryResultCachedAudio.reply_markup, + Space.id_, + Space.audio_file_id, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedAudio: +class Space: id_ = "id" type_ = "audio" audio_file_id = "audio file id" @@ -52,6 +52,8 @@ class TestInlineQueryResultCachedAudio: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedAudioNoReq: def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): inst = inline_query_result_cached_audio for attr in inst.__slots__: @@ -59,22 +61,22 @@ def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_audio.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_audio.type == Space.type_ + assert inline_query_result_cached_audio.id == Space.id_ + assert inline_query_result_cached_audio.audio_file_id == Space.audio_file_id + assert inline_query_result_cached_audio.caption == Space.caption + assert inline_query_result_cached_audio.parse_mode == Space.parse_mode + assert inline_query_result_cached_audio.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_cached_audio.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( - inline_query_result_cached_audio.reply_markup.to_dict() == self.reply_markup.to_dict() + inline_query_result_cached_audio.reply_markup.to_dict() == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - audio = InlineQueryResultCachedAudio(self.id_, self.audio_file_id) + audio = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) assert audio.caption_entities == () def test_to_dict(self, inline_query_result_cached_audio): @@ -110,11 +112,11 @@ def test_to_dict(self, inline_query_result_cached_audio): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) + b = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) + c = InlineQueryResultCachedAudio(Space.id_, "") + d = InlineQueryResultCachedAudio("", Space.audio_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index e728d333d17..8c0edb485e4 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -29,22 +29,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_document(): return InlineQueryResultCachedDocument( - TestInlineQueryResultCachedDocument.id_, - TestInlineQueryResultCachedDocument.title, - TestInlineQueryResultCachedDocument.document_file_id, - caption=TestInlineQueryResultCachedDocument.caption, - parse_mode=TestInlineQueryResultCachedDocument.parse_mode, - caption_entities=TestInlineQueryResultCachedDocument.caption_entities, - description=TestInlineQueryResultCachedDocument.description, - input_message_content=TestInlineQueryResultCachedDocument.input_message_content, - reply_markup=TestInlineQueryResultCachedDocument.reply_markup, + Space.id_, + Space.title, + Space.document_file_id, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + description=Space.description, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedDocument: +class Space: id_ = "id" type_ = "document" document_file_id = "document file id" @@ -56,6 +56,8 @@ class TestInlineQueryResultCachedDocument: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedDocumentNoReq: def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): inst = inline_query_result_cached_document for attr in inst.__slots__: @@ -63,25 +65,27 @@ def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_document.caption_entities == tuple(self.caption_entities) - assert inline_query_result_cached_document.description == self.description + assert inline_query_result_cached_document.id == Space.id_ + assert inline_query_result_cached_document.type == Space.type_ + assert inline_query_result_cached_document.document_file_id == Space.document_file_id + assert inline_query_result_cached_document.title == Space.title + assert inline_query_result_cached_document.caption == Space.caption + assert inline_query_result_cached_document.parse_mode == Space.parse_mode + assert inline_query_result_cached_document.caption_entities == tuple( + Space.caption_entities + ) + assert inline_query_result_cached_document.description == Space.description assert ( inline_query_result_cached_document.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( inline_query_result_cached_document.reply_markup.to_dict() - == self.reply_markup.to_dict() + == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - test = InlineQueryResultCachedDocument(self.id_, self.title, self.document_file_id) + test = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) assert test.caption_entities == () def test_to_dict(self, inline_query_result_cached_document): @@ -129,11 +133,11 @@ def test_to_dict(self, inline_query_result_cached_document): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) + b = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) + c = InlineQueryResultCachedDocument(Space.id_, Space.title, "") + d = InlineQueryResultCachedDocument("", Space.title, Space.document_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index 7af70a7daa7..0cb3375ab67 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -28,21 +28,21 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_gif(): return InlineQueryResultCachedGif( - TestInlineQueryResultCachedGif.id_, - TestInlineQueryResultCachedGif.gif_file_id, - title=TestInlineQueryResultCachedGif.title, - caption=TestInlineQueryResultCachedGif.caption, - parse_mode=TestInlineQueryResultCachedGif.parse_mode, - caption_entities=TestInlineQueryResultCachedGif.caption_entities, - input_message_content=TestInlineQueryResultCachedGif.input_message_content, - reply_markup=TestInlineQueryResultCachedGif.reply_markup, + Space.id_, + Space.gif_file_id, + title=Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedGif: +class Space: id_ = "id" type_ = "gif" gif_file_id = "gif file id" @@ -53,6 +53,8 @@ class TestInlineQueryResultCachedGif: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedGifNoReq: def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): inst = inline_query_result_cached_gif for attr in inst.__slots__: @@ -60,21 +62,23 @@ def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_gif.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_gif.type == Space.type_ + assert inline_query_result_cached_gif.id == Space.id_ + assert inline_query_result_cached_gif.gif_file_id == Space.gif_file_id + assert inline_query_result_cached_gif.title == Space.title + assert inline_query_result_cached_gif.caption == Space.caption + assert inline_query_result_cached_gif.parse_mode == Space.parse_mode + assert inline_query_result_cached_gif.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_cached_gif.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() + ) + assert ( + inline_query_result_cached_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() ) - assert inline_query_result_cached_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedGif(self.id_, self.gif_file_id) + result = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_gif): @@ -109,11 +113,11 @@ def test_to_dict(self, inline_query_result_cached_gif): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) + b = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) + c = InlineQueryResultCachedGif(Space.id_, "") + d = InlineQueryResultCachedGif("", Space.gif_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index df273eff1af..360ef648697 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -28,21 +28,21 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_mpeg4_gif(): return InlineQueryResultCachedMpeg4Gif( - TestInlineQueryResultCachedMpeg4Gif.id_, - TestInlineQueryResultCachedMpeg4Gif.mpeg4_file_id, - title=TestInlineQueryResultCachedMpeg4Gif.title, - caption=TestInlineQueryResultCachedMpeg4Gif.caption, - parse_mode=TestInlineQueryResultCachedMpeg4Gif.parse_mode, - caption_entities=TestInlineQueryResultCachedMpeg4Gif.caption_entities, - input_message_content=TestInlineQueryResultCachedMpeg4Gif.input_message_content, - reply_markup=TestInlineQueryResultCachedMpeg4Gif.reply_markup, + Space.id_, + Space.mpeg4_file_id, + title=Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedMpeg4Gif: +class Space: id_ = "id" type_ = "mpeg4_gif" mpeg4_file_id = "mpeg4 file id" @@ -53,6 +53,8 @@ class TestInlineQueryResultCachedMpeg4Gif: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedMpeg4GifNoReq: def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): inst = inline_query_result_cached_mpeg4_gif for attr in inst.__slots__: @@ -60,26 +62,26 @@ def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode + assert inline_query_result_cached_mpeg4_gif.type == Space.type_ + assert inline_query_result_cached_mpeg4_gif.id == Space.id_ + assert inline_query_result_cached_mpeg4_gif.mpeg4_file_id == Space.mpeg4_file_id + assert inline_query_result_cached_mpeg4_gif.title == Space.title + assert inline_query_result_cached_mpeg4_gif.caption == Space.caption + assert inline_query_result_cached_mpeg4_gif.parse_mode == Space.parse_mode assert inline_query_result_cached_mpeg4_gif.caption_entities == tuple( - self.caption_entities + Space.caption_entities ) assert ( inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() - == self.reply_markup.to_dict() + == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedMpeg4Gif(self.id_, self.mpeg4_file_id) + result = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_mpeg4_gif): @@ -123,11 +125,11 @@ def test_to_dict(self, inline_query_result_cached_mpeg4_gif): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) + b = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) + c = InlineQueryResultCachedMpeg4Gif(Space.id_, "") + d = InlineQueryResultCachedMpeg4Gif("", Space.mpeg4_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 2ef9fbe62cf..473d3772194 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -28,22 +28,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_photo(): return InlineQueryResultCachedPhoto( - TestInlineQueryResultCachedPhoto.id_, - TestInlineQueryResultCachedPhoto.photo_file_id, - title=TestInlineQueryResultCachedPhoto.title, - description=TestInlineQueryResultCachedPhoto.description, - caption=TestInlineQueryResultCachedPhoto.caption, - parse_mode=TestInlineQueryResultCachedPhoto.parse_mode, - caption_entities=TestInlineQueryResultCachedPhoto.caption_entities, - input_message_content=TestInlineQueryResultCachedPhoto.input_message_content, - reply_markup=TestInlineQueryResultCachedPhoto.reply_markup, + Space.id_, + Space.photo_file_id, + title=Space.title, + description=Space.description, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedPhoto: +class Space: id_ = "id" type_ = "photo" photo_file_id = "photo file id" @@ -55,6 +55,8 @@ class TestInlineQueryResultCachedPhoto: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedPhotoNoReq: def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): inst = inline_query_result_cached_photo for attr in inst.__slots__: @@ -62,24 +64,24 @@ def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_photo.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_photo.type == Space.type_ + assert inline_query_result_cached_photo.id == Space.id_ + assert inline_query_result_cached_photo.photo_file_id == Space.photo_file_id + assert inline_query_result_cached_photo.title == Space.title + assert inline_query_result_cached_photo.description == Space.description + assert inline_query_result_cached_photo.caption == Space.caption + assert inline_query_result_cached_photo.parse_mode == Space.parse_mode + assert inline_query_result_cached_photo.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_cached_photo.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( - inline_query_result_cached_photo.reply_markup.to_dict() == self.reply_markup.to_dict() + inline_query_result_cached_photo.reply_markup.to_dict() == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedPhoto(self.id_, self.photo_file_id) + result = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_photo): @@ -123,11 +125,11 @@ def test_to_dict(self, inline_query_result_cached_photo): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) + b = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) + c = InlineQueryResultCachedPhoto(Space.id_, "") + d = InlineQueryResultCachedPhoto("", Space.photo_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index d698e306f3e..a02bb1d5d0f 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -27,23 +27,25 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, + Space.id_, + Space.sticker_file_id, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedSticker: +class Space: id_ = "id" type_ = "sticker" sticker_file_id = "sticker file id" input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedStickerNoReq: def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): inst = inline_query_result_cached_sticker for attr in inst.__slots__: @@ -51,16 +53,16 @@ def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.type == Space.type_ + assert inline_query_result_cached_sticker.id == Space.id_ + assert inline_query_result_cached_sticker.sticker_file_id == Space.sticker_file_id assert ( inline_query_result_cached_sticker.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( inline_query_result_cached_sticker.reply_markup.to_dict() - == self.reply_markup.to_dict() + == Space.reply_markup.to_dict() ) def test_to_dict(self, inline_query_result_cached_sticker): @@ -88,11 +90,11 @@ def test_to_dict(self, inline_query_result_cached_sticker): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedSticker(Space.id_, Space.sticker_file_id) + b = InlineQueryResultCachedSticker(Space.id_, Space.sticker_file_id) + c = InlineQueryResultCachedSticker(Space.id_, "") + d = InlineQueryResultCachedSticker("", Space.sticker_file_id) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index c7861e0ce0c..884d4face6d 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -28,22 +28,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_video(): return InlineQueryResultCachedVideo( - TestInlineQueryResultCachedVideo.id_, - TestInlineQueryResultCachedVideo.video_file_id, - TestInlineQueryResultCachedVideo.title, - caption=TestInlineQueryResultCachedVideo.caption, - parse_mode=TestInlineQueryResultCachedVideo.parse_mode, - caption_entities=TestInlineQueryResultCachedVideo.caption_entities, - description=TestInlineQueryResultCachedVideo.description, - input_message_content=TestInlineQueryResultCachedVideo.input_message_content, - reply_markup=TestInlineQueryResultCachedVideo.reply_markup, + Space.id_, + Space.video_file_id, + Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + description=Space.description, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedVideo: +class Space: id_ = "id" type_ = "video" video_file_id = "video file id" @@ -55,6 +55,8 @@ class TestInlineQueryResultCachedVideo: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedVideoNoReq: def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): inst = inline_query_result_cached_video for attr in inst.__slots__: @@ -62,24 +64,24 @@ def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_video.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_video.type == Space.type_ + assert inline_query_result_cached_video.id == Space.id_ + assert inline_query_result_cached_video.video_file_id == Space.video_file_id + assert inline_query_result_cached_video.title == Space.title + assert inline_query_result_cached_video.description == Space.description + assert inline_query_result_cached_video.caption == Space.caption + assert inline_query_result_cached_video.parse_mode == Space.parse_mode + assert inline_query_result_cached_video.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_cached_video.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( - inline_query_result_cached_video.reply_markup.to_dict() == self.reply_markup.to_dict() + inline_query_result_cached_video.reply_markup.to_dict() == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - video = InlineQueryResultCachedVideo(self.id_, self.video_file_id, self.title) + video = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) assert video.caption_entities == () @@ -124,11 +126,11 @@ def test_to_dict(self, inline_query_result_cached_video): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) + b = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) + c = InlineQueryResultCachedVideo(Space.id_, "", Space.title) + d = InlineQueryResultCachedVideo("", Space.video_file_id, Space.title) + e = InlineQueryResultCachedVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index c4033edc386..6ee7159dcee 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -28,21 +28,21 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_cached_voice(): return InlineQueryResultCachedVoice( - TestInlineQueryResultCachedVoice.id_, - TestInlineQueryResultCachedVoice.voice_file_id, - TestInlineQueryResultCachedVoice.title, - caption=TestInlineQueryResultCachedVoice.caption, - parse_mode=TestInlineQueryResultCachedVoice.parse_mode, - caption_entities=TestInlineQueryResultCachedVoice.caption_entities, - input_message_content=TestInlineQueryResultCachedVoice.input_message_content, - reply_markup=TestInlineQueryResultCachedVoice.reply_markup, + Space.id_, + Space.voice_file_id, + Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultCachedVoice: +class Space: id_ = "id" type_ = "voice" voice_file_id = "voice file id" @@ -53,6 +53,8 @@ class TestInlineQueryResultCachedVoice: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultCachedVoiceNoReq: def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): inst = inline_query_result_cached_voice for attr in inst.__slots__: @@ -60,23 +62,23 @@ def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_cached_voice.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_voice.type == Space.type_ + assert inline_query_result_cached_voice.id == Space.id_ + assert inline_query_result_cached_voice.voice_file_id == Space.voice_file_id + assert inline_query_result_cached_voice.title == Space.title + assert inline_query_result_cached_voice.caption == Space.caption + assert inline_query_result_cached_voice.parse_mode == Space.parse_mode + assert inline_query_result_cached_voice.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_cached_voice.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) assert ( - inline_query_result_cached_voice.reply_markup.to_dict() == self.reply_markup.to_dict() + inline_query_result_cached_voice.reply_markup.to_dict() == Space.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedVoice(self.id_, self.voice_file_id, self.title) + result = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_voice): @@ -116,11 +118,11 @@ def test_to_dict(self, inline_query_result_cached_voice): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) + b = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) + c = InlineQueryResultCachedVoice(Space.id_, "", Space.title) + d = InlineQueryResultCachedVoice("", Space.voice_file_id, Space.title) + e = InlineQueryResultCachedAudio(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index c3a0c845428..cdbc922c57c 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -27,22 +27,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, + Space.id_, + Space.phone_number, + Space.first_name, + last_name=Space.last_name, + thumb_url=Space.thumb_url, + thumb_width=Space.thumb_width, + thumb_height=Space.thumb_height, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultContact: +class Space: id_ = "id" type_ = "contact" phone_number = "phone_number" @@ -54,6 +54,8 @@ class TestInlineQueryResultContact: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultContactNoReq: def test_slot_behaviour(self, inline_query_result_contact, mro_slots): inst = inline_query_result_contact for attr in inst.__slots__: @@ -61,19 +63,19 @@ def test_slot_behaviour(self, inline_query_result_contact, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.id == Space.id_ + assert inline_query_result_contact.type == Space.type_ + assert inline_query_result_contact.phone_number == Space.phone_number + assert inline_query_result_contact.first_name == Space.first_name + assert inline_query_result_contact.last_name == Space.last_name + assert inline_query_result_contact.thumb_url == Space.thumb_url + assert inline_query_result_contact.thumb_width == Space.thumb_width + assert inline_query_result_contact.thumb_height == Space.thumb_height assert ( inline_query_result_contact.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_contact.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_contact.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_to_dict(self, inline_query_result_contact): inline_query_result_contact_dict = inline_query_result_contact.to_dict() @@ -113,11 +115,11 @@ def test_to_dict(self, inline_query_result_contact): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultContact(Space.id_, Space.phone_number, Space.first_name) + b = InlineQueryResultContact(Space.id_, Space.phone_number, Space.first_name) + c = InlineQueryResultContact(Space.id_, "", Space.first_name) + d = InlineQueryResultContact("", Space.phone_number, Space.first_name) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index 2915e7451e6..f9aa3ae7a0f 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -28,26 +28,26 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_document(): return InlineQueryResultDocument( - TestInlineQueryResultDocument.id_, - TestInlineQueryResultDocument.document_url, - TestInlineQueryResultDocument.title, - TestInlineQueryResultDocument.mime_type, - caption=TestInlineQueryResultDocument.caption, - parse_mode=TestInlineQueryResultDocument.parse_mode, - caption_entities=TestInlineQueryResultDocument.caption_entities, - 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, + Space.id_, + Space.document_url, + Space.title, + Space.mime_type, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + description=Space.description, + thumb_url=Space.thumb_url, + thumb_width=Space.thumb_width, + thumb_height=Space.thumb_height, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultDocument: +class Space: id_ = "id" type_ = "document" document_url = "document url" @@ -63,6 +63,8 @@ class TestInlineQueryResultDocument: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultDocumentNoReq: def test_slot_behaviour(self, inline_query_result_document, mro_slots): inst = inline_query_result_document for attr in inst.__slots__: @@ -70,26 +72,28 @@ def test_slot_behaviour(self, inline_query_result_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_document.caption_entities == tuple(self.caption_entities) - 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.id == Space.id_ + assert inline_query_result_document.type == Space.type_ + assert inline_query_result_document.document_url == Space.document_url + assert inline_query_result_document.title == Space.title + assert inline_query_result_document.caption == Space.caption + assert inline_query_result_document.parse_mode == Space.parse_mode + assert inline_query_result_document.caption_entities == tuple(Space.caption_entities) + assert inline_query_result_document.mime_type == Space.mime_type + assert inline_query_result_document.description == Space.description + assert inline_query_result_document.thumb_url == Space.thumb_url + assert inline_query_result_document.thumb_width == Space.thumb_width + assert inline_query_result_document.thumb_height == Space.thumb_height assert ( inline_query_result_document.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_document.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_document.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultDocument(self.id_, self.document_url, self.title, self.mime_type) + result = InlineQueryResultDocument( + Space.id_, Space.document_url, Space.title, Space.mime_type + ) assert result.caption_entities == () def test_to_dict(self, inline_query_result_document): @@ -141,11 +145,11 @@ def test_to_dict(self, inline_query_result_document): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultDocument(Space.id_, Space.document_url, Space.title, Space.mime_type) + b = InlineQueryResultDocument(Space.id_, Space.document_url, Space.title, Space.mime_type) + c = InlineQueryResultDocument(Space.id_, "", Space.title, Space.mime_type) + d = InlineQueryResultDocument("", Space.document_url, Space.title, Space.mime_type) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py index 3c65c61acb5..df7e120f22b 100644 --- a/tests/test_inlinequeryresultgame.py +++ b/tests/test_inlinequeryresultgame.py @@ -26,21 +26,23 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_game(): return InlineQueryResultGame( - TestInlineQueryResultGame.id_, - TestInlineQueryResultGame.game_short_name, - reply_markup=TestInlineQueryResultGame.reply_markup, + Space.id_, + Space.game_short_name, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultGame: +class Space: id_ = "id" type_ = "game" game_short_name = "game short name" reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultGameNoReq: def test_slot_behaviour(self, inline_query_result_game, mro_slots): inst = inline_query_result_game for attr in inst.__slots__: @@ -48,10 +50,10 @@ def test_slot_behaviour(self, inline_query_result_game, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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() + assert inline_query_result_game.type == Space.type_ + assert inline_query_result_game.id == Space.id_ + assert inline_query_result_game.game_short_name == Space.game_short_name + assert inline_query_result_game.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_to_dict(self, inline_query_result_game): inline_query_result_game_dict = inline_query_result_game.to_dict() @@ -69,11 +71,11 @@ def test_to_dict(self, inline_query_result_game): ) 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_, "", "") + a = InlineQueryResultGame(Space.id_, Space.game_short_name) + b = InlineQueryResultGame(Space.id_, Space.game_short_name) + c = InlineQueryResultGame(Space.id_, "") + d = InlineQueryResultGame("", Space.game_short_name) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index f0242148155..c00da6eb514 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -28,26 +28,26 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - parse_mode=TestInlineQueryResultGif.parse_mode, - caption_entities=TestInlineQueryResultGif.caption_entities, - input_message_content=TestInlineQueryResultGif.input_message_content, - reply_markup=TestInlineQueryResultGif.reply_markup, - thumb_mime_type=TestInlineQueryResultGif.thumb_mime_type, + Space.id_, + Space.gif_url, + Space.thumb_url, + gif_width=Space.gif_width, + gif_height=Space.gif_height, + gif_duration=Space.gif_duration, + title=Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, + thumb_mime_type=Space.thumb_mime_type, ) -class TestInlineQueryResultGif: +class Space: id_ = "id" type_ = "gif" gif_url = "gif url" @@ -63,6 +63,8 @@ class TestInlineQueryResultGif: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultGifNoReq: def test_slot_behaviour(self, inline_query_result_gif, mro_slots): inst = inline_query_result_gif for attr in inst.__slots__: @@ -70,27 +72,27 @@ def test_slot_behaviour(self, inline_query_result_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_caption_entities_always_tuple(self): - result = InlineQueryResultGif(self.id_, self.gif_url, self.thumb_url) + result = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) assert result.caption_entities == () 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.thumb_mime_type == self.thumb_mime_type - assert inline_query_result_gif.title == self.title - assert inline_query_result_gif.caption == self.caption - assert inline_query_result_gif.parse_mode == self.parse_mode - assert inline_query_result_gif.caption_entities == tuple(self.caption_entities) + assert inline_query_result_gif.type == Space.type_ + assert inline_query_result_gif.id == Space.id_ + assert inline_query_result_gif.gif_url == Space.gif_url + assert inline_query_result_gif.gif_width == Space.gif_width + assert inline_query_result_gif.gif_height == Space.gif_height + assert inline_query_result_gif.gif_duration == Space.gif_duration + assert inline_query_result_gif.thumb_url == Space.thumb_url + assert inline_query_result_gif.thumb_mime_type == Space.thumb_mime_type + assert inline_query_result_gif.title == Space.title + assert inline_query_result_gif.caption == Space.caption + assert inline_query_result_gif.parse_mode == Space.parse_mode + assert inline_query_result_gif.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_gif.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_gif.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_to_dict(self, inline_query_result_gif): inline_query_result_gif_dict = inline_query_result_gif.to_dict() @@ -123,11 +125,11 @@ def test_to_dict(self, inline_query_result_gif): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) + b = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) + c = InlineQueryResultGif(Space.id_, "", Space.thumb_url) + d = InlineQueryResultGif("", Space.gif_url, Space.thumb_url) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 912273d2782..ac746613db4 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -27,26 +27,26 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_location(): return InlineQueryResultLocation( - TestInlineQueryResultLocation.id_, - TestInlineQueryResultLocation.latitude, - TestInlineQueryResultLocation.longitude, - TestInlineQueryResultLocation.title, - live_period=TestInlineQueryResultLocation.live_period, - 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, - horizontal_accuracy=TestInlineQueryResultLocation.horizontal_accuracy, - heading=TestInlineQueryResultLocation.heading, - proximity_alert_radius=TestInlineQueryResultLocation.proximity_alert_radius, + Space.id_, + Space.latitude, + Space.longitude, + Space.title, + live_period=Space.live_period, + thumb_url=Space.thumb_url, + thumb_width=Space.thumb_width, + thumb_height=Space.thumb_height, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, + horizontal_accuracy=Space.horizontal_accuracy, + heading=Space.heading, + proximity_alert_radius=Space.proximity_alert_radius, ) -class TestInlineQueryResultLocation: +class Space: id_ = "id" type_ = "location" latitude = 0.0 @@ -62,6 +62,8 @@ class TestInlineQueryResultLocation: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultLocationNoReq: def test_slot_behaviour(self, inline_query_result_location, mro_slots): inst = inline_query_result_location for attr in inst.__slots__: @@ -69,23 +71,23 @@ def test_slot_behaviour(self, inline_query_result_location, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.live_period == self.live_period - 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.id == Space.id_ + assert inline_query_result_location.type == Space.type_ + assert inline_query_result_location.latitude == Space.latitude + assert inline_query_result_location.longitude == Space.longitude + assert inline_query_result_location.title == Space.title + assert inline_query_result_location.live_period == Space.live_period + assert inline_query_result_location.thumb_url == Space.thumb_url + assert inline_query_result_location.thumb_width == Space.thumb_width + assert inline_query_result_location.thumb_height == Space.thumb_height assert ( inline_query_result_location.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_location.reply_markup.to_dict() == self.reply_markup.to_dict() - assert inline_query_result_location.heading == self.heading - assert inline_query_result_location.horizontal_accuracy == self.horizontal_accuracy - assert inline_query_result_location.proximity_alert_radius == self.proximity_alert_radius + assert inline_query_result_location.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_location.heading == Space.heading + assert inline_query_result_location.horizontal_accuracy == Space.horizontal_accuracy + assert inline_query_result_location.proximity_alert_radius == Space.proximity_alert_radius def test_to_dict(self, inline_query_result_location): inline_query_result_location_dict = inline_query_result_location.to_dict() @@ -136,11 +138,11 @@ def test_to_dict(self, inline_query_result_location): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultLocation(Space.id_, Space.longitude, Space.latitude, Space.title) + b = InlineQueryResultLocation(Space.id_, Space.longitude, Space.latitude, Space.title) + c = InlineQueryResultLocation(Space.id_, 0, Space.latitude, Space.title) + d = InlineQueryResultLocation("", Space.longitude, Space.latitude, Space.title) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 2c564d94fd7..f4a65e7a062 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -28,26 +28,26 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - parse_mode=TestInlineQueryResultMpeg4Gif.parse_mode, - caption_entities=TestInlineQueryResultMpeg4Gif.caption_entities, - input_message_content=TestInlineQueryResultMpeg4Gif.input_message_content, - reply_markup=TestInlineQueryResultMpeg4Gif.reply_markup, - thumb_mime_type=TestInlineQueryResultMpeg4Gif.thumb_mime_type, + Space.id_, + Space.mpeg4_url, + Space.thumb_url, + mpeg4_width=Space.mpeg4_width, + mpeg4_height=Space.mpeg4_height, + mpeg4_duration=Space.mpeg4_duration, + title=Space.title, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, + thumb_mime_type=Space.thumb_mime_type, ) -class TestInlineQueryResultMpeg4Gif: +class Space: id_ = "id" type_ = "mpeg4_gif" mpeg4_url = "mpeg4 url" @@ -63,6 +63,8 @@ class TestInlineQueryResultMpeg4Gif: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultMpeg4GifNoReq: def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): inst = inline_query_result_mpeg4_gif for attr in inst.__slots__: @@ -70,26 +72,26 @@ def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.thumb_mime_type == self.thumb_mime_type - assert inline_query_result_mpeg4_gif.title == self.title - assert inline_query_result_mpeg4_gif.caption == self.caption - assert inline_query_result_mpeg4_gif.parse_mode == self.parse_mode - assert inline_query_result_mpeg4_gif.caption_entities == tuple(self.caption_entities) + assert inline_query_result_mpeg4_gif.type == Space.type_ + assert inline_query_result_mpeg4_gif.id == Space.id_ + assert inline_query_result_mpeg4_gif.mpeg4_url == Space.mpeg4_url + assert inline_query_result_mpeg4_gif.mpeg4_width == Space.mpeg4_width + assert inline_query_result_mpeg4_gif.mpeg4_height == Space.mpeg4_height + assert inline_query_result_mpeg4_gif.mpeg4_duration == Space.mpeg4_duration + assert inline_query_result_mpeg4_gif.thumb_url == Space.thumb_url + assert inline_query_result_mpeg4_gif.thumb_mime_type == Space.thumb_mime_type + assert inline_query_result_mpeg4_gif.title == Space.title + assert inline_query_result_mpeg4_gif.caption == Space.caption + assert inline_query_result_mpeg4_gif.parse_mode == Space.parse_mode + assert inline_query_result_mpeg4_gif.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_mpeg4_gif.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultMpeg4Gif(self.id_, self.mpeg4_url, self.thumb_url) + result = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) assert result.caption_entities == () def test_to_dict(self, inline_query_result_mpeg4_gif): @@ -143,11 +145,11 @@ def test_to_dict(self, inline_query_result_mpeg4_gif): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) + b = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) + c = InlineQueryResultMpeg4Gif(Space.id_, "", Space.thumb_url) + d = InlineQueryResultMpeg4Gif("", Space.mpeg4_url, Space.thumb_url) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 0e40fc5a3db..c9864b0200a 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -28,25 +28,25 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - parse_mode=TestInlineQueryResultPhoto.parse_mode, - caption_entities=TestInlineQueryResultPhoto.caption_entities, - input_message_content=TestInlineQueryResultPhoto.input_message_content, - reply_markup=TestInlineQueryResultPhoto.reply_markup, + Space.id_, + Space.photo_url, + Space.thumb_url, + photo_width=Space.photo_width, + photo_height=Space.photo_height, + title=Space.title, + description=Space.description, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultPhoto: +class Space: id_ = "id" type_ = "photo" photo_url = "photo url" @@ -62,6 +62,8 @@ class TestInlineQueryResultPhoto: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultPhotoNoReq: def test_slot_behaviour(self, inline_query_result_photo, mro_slots): inst = inline_query_result_photo for attr in inst.__slots__: @@ -69,25 +71,25 @@ def test_slot_behaviour(self, inline_query_result_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_photo.caption_entities == tuple(self.caption_entities) + assert inline_query_result_photo.type == Space.type_ + assert inline_query_result_photo.id == Space.id_ + assert inline_query_result_photo.photo_url == Space.photo_url + assert inline_query_result_photo.photo_width == Space.photo_width + assert inline_query_result_photo.photo_height == Space.photo_height + assert inline_query_result_photo.thumb_url == Space.thumb_url + assert inline_query_result_photo.title == Space.title + assert inline_query_result_photo.description == Space.description + assert inline_query_result_photo.caption == Space.caption + assert inline_query_result_photo.parse_mode == Space.parse_mode + assert inline_query_result_photo.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_photo.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_photo.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_photo.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultPhoto(self.id_, self.photo_url, self.thumb_url) + result = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) assert result.caption_entities == () def test_to_dict(self, inline_query_result_photo): @@ -124,11 +126,11 @@ def test_to_dict(self, inline_query_result_photo): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) + b = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) + c = InlineQueryResultPhoto(Space.id_, "", Space.thumb_url) + d = InlineQueryResultPhoto("", Space.photo_url, Space.thumb_url) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index f9e4f6ab096..015b8615fbb 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -27,27 +27,27 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_venue(): return InlineQueryResultVenue( - TestInlineQueryResultVenue.id_, - TestInlineQueryResultVenue.latitude, - TestInlineQueryResultVenue.longitude, - TestInlineQueryResultVenue.title, - TestInlineQueryResultVenue.address, - foursquare_id=TestInlineQueryResultVenue.foursquare_id, - foursquare_type=TestInlineQueryResultVenue.foursquare_type, - 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, - google_place_id=TestInlineQueryResultVenue.google_place_id, - google_place_type=TestInlineQueryResultVenue.google_place_type, + Space.id_, + Space.latitude, + Space.longitude, + Space.title, + Space.address, + foursquare_id=Space.foursquare_id, + foursquare_type=Space.foursquare_type, + thumb_url=Space.thumb_url, + thumb_width=Space.thumb_width, + thumb_height=Space.thumb_height, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, + google_place_id=Space.google_place_id, + google_place_type=Space.google_place_type, ) -class TestInlineQueryResultVenue: +class Space: id_ = "id" type_ = "venue" latitude = "latitude" @@ -64,6 +64,8 @@ class TestInlineQueryResultVenue: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultVenueNoReq: def test_slot_behaviour(self, inline_query_result_venue, mro_slots): inst = inline_query_result_venue for attr in inst.__slots__: @@ -71,24 +73,24 @@ def test_slot_behaviour(self, inline_query_result_venue, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.foursquare_type == self.foursquare_type - assert inline_query_result_venue.google_place_id == self.google_place_id - assert inline_query_result_venue.google_place_type == self.google_place_type - 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.id == Space.id_ + assert inline_query_result_venue.type == Space.type_ + assert inline_query_result_venue.latitude == Space.latitude + assert inline_query_result_venue.longitude == Space.longitude + assert inline_query_result_venue.title == Space.title + assert inline_query_result_venue.address == Space.address + assert inline_query_result_venue.foursquare_id == Space.foursquare_id + assert inline_query_result_venue.foursquare_type == Space.foursquare_type + assert inline_query_result_venue.google_place_id == Space.google_place_id + assert inline_query_result_venue.google_place_type == Space.google_place_type + assert inline_query_result_venue.thumb_url == Space.thumb_url + assert inline_query_result_venue.thumb_width == Space.thumb_width + assert inline_query_result_venue.thumb_height == Space.thumb_height assert ( inline_query_result_venue.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_venue.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_venue.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_to_dict(self, inline_query_result_venue): inline_query_result_venue_dict = inline_query_result_venue.to_dict() @@ -135,14 +137,14 @@ def test_to_dict(self, inline_query_result_venue): def test_equality(self): a = InlineQueryResultVenue( - self.id_, self.longitude, self.latitude, self.title, self.address + Space.id_, Space.longitude, Space.latitude, Space.title, Space.address ) b = InlineQueryResultVenue( - self.id_, self.longitude, self.latitude, self.title, self.address + Space.id_, Space.longitude, Space.latitude, Space.title, Space.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_, "", "") + c = InlineQueryResultVenue(Space.id_, "", Space.latitude, Space.title, Space.address) + d = InlineQueryResultVenue("", Space.longitude, Space.latitude, Space.title, Space.address) + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index dad63f132be..09cfb722541 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -28,27 +28,27 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, - parse_mode=TestInlineQueryResultVideo.parse_mode, - caption_entities=TestInlineQueryResultVideo.caption_entities, - description=TestInlineQueryResultVideo.description, - input_message_content=TestInlineQueryResultVideo.input_message_content, - reply_markup=TestInlineQueryResultVideo.reply_markup, + Space.id_, + Space.video_url, + Space.mime_type, + Space.thumb_url, + Space.title, + video_width=Space.video_width, + video_height=Space.video_height, + video_duration=Space.video_duration, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + description=Space.description, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultVideo: +class Space: id_ = "id" type_ = "video" video_url = "video url" @@ -65,6 +65,8 @@ class TestInlineQueryResultVideo: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultVideoNoReq: def test_slot_behaviour(self, inline_query_result_video, mro_slots): inst = inline_query_result_video for attr in inst.__slots__: @@ -72,28 +74,28 @@ def test_slot_behaviour(self, inline_query_result_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_video.caption_entities == tuple(self.caption_entities) + assert inline_query_result_video.type == Space.type_ + assert inline_query_result_video.id == Space.id_ + assert inline_query_result_video.video_url == Space.video_url + assert inline_query_result_video.mime_type == Space.mime_type + assert inline_query_result_video.video_width == Space.video_width + assert inline_query_result_video.video_height == Space.video_height + assert inline_query_result_video.video_duration == Space.video_duration + assert inline_query_result_video.thumb_url == Space.thumb_url + assert inline_query_result_video.title == Space.title + assert inline_query_result_video.description == Space.description + assert inline_query_result_video.caption == Space.caption + assert inline_query_result_video.parse_mode == Space.parse_mode + assert inline_query_result_video.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_video.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_video.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_video.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_caption_entities_always_tuple(self): video = InlineQueryResultVideo( - self.id_, self.video_url, self.mime_type, self.thumb_url, self.title + Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title ) assert video.caption_entities == () @@ -137,14 +139,16 @@ def test_to_dict(self, inline_query_result_video): def test_equality(self): a = InlineQueryResultVideo( - self.id_, self.video_url, self.mime_type, self.thumb_url, self.title + Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title ) b = InlineQueryResultVideo( - self.id_, self.video_url, self.mime_type, self.thumb_url, self.title + Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title + ) + c = InlineQueryResultVideo(Space.id_, "", Space.mime_type, Space.thumb_url, Space.title) + d = InlineQueryResultVideo( + "", Space.video_url, Space.mime_type, Space.thumb_url, Space.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_, "", "") + e = InlineQueryResultVoice(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index 0a42aa86402..45046cc0200 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -28,22 +28,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def inline_query_result_voice(): return InlineQueryResultVoice( - id=TestInlineQueryResultVoice.id_, - voice_url=TestInlineQueryResultVoice.voice_url, - title=TestInlineQueryResultVoice.title, - voice_duration=TestInlineQueryResultVoice.voice_duration, - caption=TestInlineQueryResultVoice.caption, - parse_mode=TestInlineQueryResultVoice.parse_mode, - caption_entities=TestInlineQueryResultVoice.caption_entities, - input_message_content=TestInlineQueryResultVoice.input_message_content, - reply_markup=TestInlineQueryResultVoice.reply_markup, + id=Space.id_, + voice_url=Space.voice_url, + title=Space.title, + voice_duration=Space.voice_duration, + caption=Space.caption, + parse_mode=Space.parse_mode, + caption_entities=Space.caption_entities, + input_message_content=Space.input_message_content, + reply_markup=Space.reply_markup, ) -class TestInlineQueryResultVoice: +class Space: id_ = "id" type_ = "voice" voice_url = "voice url" @@ -55,6 +55,8 @@ class TestInlineQueryResultVoice: input_message_content = InputTextMessageContent("input_message_content") reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) + +class TestInlineQueryResultVoiceNoReq: def test_slot_behaviour(self, inline_query_result_voice, mro_slots): inst = inline_query_result_voice for attr in inst.__slots__: @@ -62,25 +64,25 @@ def test_slot_behaviour(self, inline_query_result_voice, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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.parse_mode == self.parse_mode - assert inline_query_result_voice.caption_entities == tuple(self.caption_entities) + assert inline_query_result_voice.type == Space.type_ + assert inline_query_result_voice.id == Space.id_ + assert inline_query_result_voice.voice_url == Space.voice_url + assert inline_query_result_voice.title == Space.title + assert inline_query_result_voice.voice_duration == Space.voice_duration + assert inline_query_result_voice.caption == Space.caption + assert inline_query_result_voice.parse_mode == Space.parse_mode + assert inline_query_result_voice.caption_entities == tuple(Space.caption_entities) assert ( inline_query_result_voice.input_message_content.to_dict() - == self.input_message_content.to_dict() + == Space.input_message_content.to_dict() ) - assert inline_query_result_voice.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_voice.reply_markup.to_dict() == Space.reply_markup.to_dict() def test_caption_entities_always_tuple(self): result = InlineQueryResultVoice( - self.id_, - self.voice_url, - self.title, + Space.id_, + Space.voice_url, + Space.title, ) assert result.caption_entities == () @@ -112,11 +114,11 @@ def test_to_dict(self, inline_query_result_voice): ) def test_equality(self): - 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_, "", "") + a = InlineQueryResultVoice(Space.id_, Space.voice_url, Space.title) + b = InlineQueryResultVoice(Space.id_, Space.voice_url, Space.title) + c = InlineQueryResultVoice(Space.id_, "", Space.title) + d = InlineQueryResultVoice("", Space.voice_url, Space.title) + e = InlineQueryResultAudio(Space.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index e06454afd9f..dad710d20d6 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -21,20 +21,18 @@ from telegram import InputContactMessageContent, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_contact_message_content(): - return InputContactMessageContent( - TestInputContactMessageContent.phone_number, - TestInputContactMessageContent.first_name, - last_name=TestInputContactMessageContent.last_name, - ) + return InputContactMessageContent(Space.phone_number, Space.first_name, Space.last_name) -class TestInputContactMessageContent: +class Space: phone_number = "phone number" first_name = "first name" last_name = "last name" + +class TestInputContactMessageContentNoReq: def test_slot_behaviour(self, input_contact_message_content, mro_slots): inst = input_contact_message_content for attr in inst.__slots__: @@ -42,9 +40,9 @@ def test_slot_behaviour(self, input_contact_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_contact_message_content): - assert input_contact_message_content.first_name == self.first_name - assert input_contact_message_content.phone_number == self.phone_number - assert input_contact_message_content.last_name == self.last_name + assert input_contact_message_content.first_name == Space.first_name + assert input_contact_message_content.phone_number == Space.phone_number + assert input_contact_message_content.last_name == Space.last_name def test_to_dict(self, input_contact_message_content): input_contact_message_content_dict = input_contact_message_content.to_dict() diff --git a/tests/test_inputfile.py b/tests/test_inputfile.py index 1de2f4e4721..bde7c935b00 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -26,12 +26,12 @@ from tests.conftest import data_file -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def png_file(): return data_file("game.png") -class TestInputFile: +class TestInputFileNoReq: def test_slot_behaviour(self, mro_slots): inst = InputFile(BytesIO(b"blah"), filename="tg.jpg") for attr in inst.__slots__: @@ -139,6 +139,8 @@ def read(self): == "blah.jpg" ) + +class TestInputFileReq: async def test_send_bytes(self, bot, chat_id): # We test this here and not at the respective test modules because it's not worth # duplicating the test for the different methods diff --git a/tests/test_inputinvoicemessagecontent.py b/tests/test_inputinvoicemessagecontent.py index 93b79d4cc73..3672be28806 100644 --- a/tests/test_inputinvoicemessagecontent.py +++ b/tests/test_inputinvoicemessagecontent.py @@ -22,33 +22,33 @@ from telegram import InputInvoiceMessageContent, InputTextMessageContent, LabeledPrice -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_invoice_message_content(): return InputInvoiceMessageContent( - title=TestInputInvoiceMessageContent.title, - description=TestInputInvoiceMessageContent.description, - payload=TestInputInvoiceMessageContent.payload, - provider_token=TestInputInvoiceMessageContent.provider_token, - currency=TestInputInvoiceMessageContent.currency, - prices=TestInputInvoiceMessageContent.prices, - max_tip_amount=TestInputInvoiceMessageContent.max_tip_amount, - suggested_tip_amounts=TestInputInvoiceMessageContent.suggested_tip_amounts, - provider_data=TestInputInvoiceMessageContent.provider_data, - photo_url=TestInputInvoiceMessageContent.photo_url, - photo_size=TestInputInvoiceMessageContent.photo_size, - photo_width=TestInputInvoiceMessageContent.photo_width, - photo_height=TestInputInvoiceMessageContent.photo_height, - need_name=TestInputInvoiceMessageContent.need_name, - need_phone_number=TestInputInvoiceMessageContent.need_phone_number, - need_email=TestInputInvoiceMessageContent.need_email, - need_shipping_address=TestInputInvoiceMessageContent.need_shipping_address, - send_phone_number_to_provider=TestInputInvoiceMessageContent.send_phone_number_to_provider, - send_email_to_provider=TestInputInvoiceMessageContent.send_email_to_provider, - is_flexible=TestInputInvoiceMessageContent.is_flexible, + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=Space.provider_token, + currency=Space.currency, + prices=Space.prices, + max_tip_amount=Space.max_tip_amount, + suggested_tip_amounts=Space.suggested_tip_amounts, + provider_data=Space.provider_data, + photo_url=Space.photo_url, + photo_size=Space.photo_size, + photo_width=Space.photo_width, + photo_height=Space.photo_height, + need_name=Space.need_name, + need_phone_number=Space.need_phone_number, + need_email=Space.need_email, + need_shipping_address=Space.need_shipping_address, + send_phone_number_to_provider=Space.send_phone_number_to_provider, + send_email_to_provider=Space.send_email_to_provider, + is_flexible=Space.is_flexible, ) -class TestInputInvoiceMessageContent: +class Space: title = "invoice title" description = "invoice description" payload = "invoice payload" @@ -70,6 +70,8 @@ class TestInputInvoiceMessageContent: send_email_to_provider = True is_flexible = True + +class TestInputInvoiceMessageContentNoReq: def test_slot_behaviour(self, input_invoice_message_content, mro_slots): inst = input_invoice_message_content for attr in inst.__slots__: @@ -77,67 +79,67 @@ def test_slot_behaviour(self, input_invoice_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_invoice_message_content): - assert input_invoice_message_content.title == self.title - assert input_invoice_message_content.description == self.description - assert input_invoice_message_content.payload == self.payload - assert input_invoice_message_content.provider_token == self.provider_token - assert input_invoice_message_content.currency == self.currency - assert input_invoice_message_content.prices == tuple(self.prices) - assert input_invoice_message_content.max_tip_amount == self.max_tip_amount + assert input_invoice_message_content.title == Space.title + assert input_invoice_message_content.description == Space.description + assert input_invoice_message_content.payload == Space.payload + assert input_invoice_message_content.provider_token == Space.provider_token + assert input_invoice_message_content.currency == Space.currency + assert input_invoice_message_content.prices == tuple(Space.prices) + assert input_invoice_message_content.max_tip_amount == Space.max_tip_amount assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in self.suggested_tip_amounts + int(amount) for amount in Space.suggested_tip_amounts ) - assert input_invoice_message_content.provider_data == self.provider_data - assert input_invoice_message_content.photo_url == self.photo_url - assert input_invoice_message_content.photo_size == int(self.photo_size) - assert input_invoice_message_content.photo_width == int(self.photo_width) - assert input_invoice_message_content.photo_height == int(self.photo_height) - assert input_invoice_message_content.need_name == self.need_name - assert input_invoice_message_content.need_phone_number == self.need_phone_number - assert input_invoice_message_content.need_email == self.need_email - assert input_invoice_message_content.need_shipping_address == self.need_shipping_address + assert input_invoice_message_content.provider_data == Space.provider_data + assert input_invoice_message_content.photo_url == Space.photo_url + assert input_invoice_message_content.photo_size == int(Space.photo_size) + assert input_invoice_message_content.photo_width == int(Space.photo_width) + assert input_invoice_message_content.photo_height == int(Space.photo_height) + assert input_invoice_message_content.need_name == Space.need_name + assert input_invoice_message_content.need_phone_number == Space.need_phone_number + assert input_invoice_message_content.need_email == Space.need_email + assert input_invoice_message_content.need_shipping_address == Space.need_shipping_address assert ( input_invoice_message_content.send_phone_number_to_provider - == self.send_phone_number_to_provider + == Space.send_phone_number_to_provider ) - assert input_invoice_message_content.send_email_to_provider == self.send_email_to_provider - assert input_invoice_message_content.is_flexible == self.is_flexible + assert input_invoice_message_content.send_email_to_provider == Space.send_email_to_provider + assert input_invoice_message_content.is_flexible == Space.is_flexible def test_suggested_tip_amonuts_always_tuple(self): input_invoice_message_content = InputInvoiceMessageContent( - title=self.title, - description=self.description, - payload=self.payload, - provider_token=self.provider_token, - currency=self.currency, - prices=self.prices, - max_tip_amount=self.max_tip_amount, - suggested_tip_amounts=self.suggested_tip_amounts, - provider_data=self.provider_data, - photo_url=self.photo_url, - photo_size=self.photo_size, - photo_width=self.photo_width, - photo_height=self.photo_height, - need_name=self.need_name, - need_phone_number=self.need_phone_number, - need_email=self.need_email, - need_shipping_address=self.need_shipping_address, - send_phone_number_to_provider=self.send_phone_number_to_provider, - send_email_to_provider=self.send_email_to_provider, - is_flexible=self.is_flexible, + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=Space.provider_token, + currency=Space.currency, + prices=Space.prices, + max_tip_amount=Space.max_tip_amount, + suggested_tip_amounts=Space.suggested_tip_amounts, + provider_data=Space.provider_data, + photo_url=Space.photo_url, + photo_size=Space.photo_size, + photo_width=Space.photo_width, + photo_height=Space.photo_height, + need_name=Space.need_name, + need_phone_number=Space.need_phone_number, + need_email=Space.need_email, + need_shipping_address=Space.need_shipping_address, + send_phone_number_to_provider=Space.send_phone_number_to_provider, + send_email_to_provider=Space.send_email_to_provider, + is_flexible=Space.is_flexible, ) assert isinstance(input_invoice_message_content.suggested_tip_amounts, tuple) assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in self.suggested_tip_amounts + int(amount) for amount in Space.suggested_tip_amounts ) input_invoice_message_content = InputInvoiceMessageContent( - title=self.title, - description=self.description, - payload=self.payload, - provider_token=self.provider_token, - currency=self.currency, - prices=self.prices, + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=Space.provider_token, + currency=Space.currency, + prices=Space.prices, ) assert input_invoice_message_content.suggested_tip_amounts == tuple() @@ -224,92 +226,92 @@ def test_de_json(self, bot): assert InputInvoiceMessageContent.de_json({}, bot=bot) is None json_dict = { - "title": self.title, - "description": self.description, - "payload": self.payload, - "provider_token": self.provider_token, - "currency": self.currency, - "prices": [price.to_dict() for price in self.prices], - "max_tip_amount": self.max_tip_amount, - "suggested_tip_amounts": self.suggested_tip_amounts, - "provider_data": self.provider_data, - "photo_url": self.photo_url, - "photo_size": self.photo_size, - "photo_width": self.photo_width, - "photo_height": self.photo_height, - "need_name": self.need_name, - "need_phone_number": self.need_phone_number, - "need_email": self.need_email, - "need_shipping_address": self.need_shipping_address, - "send_phone_number_to_provider": self.send_phone_number_to_provider, - "send_email_to_provider": self.send_email_to_provider, - "is_flexible": self.is_flexible, + "title": Space.title, + "description": Space.description, + "payload": Space.payload, + "provider_token": Space.provider_token, + "currency": Space.currency, + "prices": [price.to_dict() for price in Space.prices], + "max_tip_amount": Space.max_tip_amount, + "suggested_tip_amounts": Space.suggested_tip_amounts, + "provider_data": Space.provider_data, + "photo_url": Space.photo_url, + "photo_size": Space.photo_size, + "photo_width": Space.photo_width, + "photo_height": Space.photo_height, + "need_name": Space.need_name, + "need_phone_number": Space.need_phone_number, + "need_email": Space.need_email, + "need_shipping_address": Space.need_shipping_address, + "send_phone_number_to_provider": Space.send_phone_number_to_provider, + "send_email_to_provider": Space.send_email_to_provider, + "is_flexible": Space.is_flexible, } input_invoice_message_content = InputInvoiceMessageContent.de_json(json_dict, bot=bot) assert input_invoice_message_content.api_kwargs == {} - assert input_invoice_message_content.title == self.title - assert input_invoice_message_content.description == self.description - assert input_invoice_message_content.payload == self.payload - assert input_invoice_message_content.provider_token == self.provider_token - assert input_invoice_message_content.currency == self.currency - assert input_invoice_message_content.prices == tuple(self.prices) - assert input_invoice_message_content.max_tip_amount == self.max_tip_amount + assert input_invoice_message_content.title == Space.title + assert input_invoice_message_content.description == Space.description + assert input_invoice_message_content.payload == Space.payload + assert input_invoice_message_content.provider_token == Space.provider_token + assert input_invoice_message_content.currency == Space.currency + assert input_invoice_message_content.prices == tuple(Space.prices) + assert input_invoice_message_content.max_tip_amount == Space.max_tip_amount assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in self.suggested_tip_amounts + int(amount) for amount in Space.suggested_tip_amounts ) - assert input_invoice_message_content.provider_data == self.provider_data - assert input_invoice_message_content.photo_url == self.photo_url - assert input_invoice_message_content.photo_size == int(self.photo_size) - assert input_invoice_message_content.photo_width == int(self.photo_width) - assert input_invoice_message_content.photo_height == int(self.photo_height) - assert input_invoice_message_content.need_name == self.need_name - assert input_invoice_message_content.need_phone_number == self.need_phone_number - assert input_invoice_message_content.need_email == self.need_email - assert input_invoice_message_content.need_shipping_address == self.need_shipping_address + assert input_invoice_message_content.provider_data == Space.provider_data + assert input_invoice_message_content.photo_url == Space.photo_url + assert input_invoice_message_content.photo_size == int(Space.photo_size) + assert input_invoice_message_content.photo_width == int(Space.photo_width) + assert input_invoice_message_content.photo_height == int(Space.photo_height) + assert input_invoice_message_content.need_name == Space.need_name + assert input_invoice_message_content.need_phone_number == Space.need_phone_number + assert input_invoice_message_content.need_email == Space.need_email + assert input_invoice_message_content.need_shipping_address == Space.need_shipping_address assert ( input_invoice_message_content.send_phone_number_to_provider - == self.send_phone_number_to_provider + == Space.send_phone_number_to_provider ) - assert input_invoice_message_content.send_email_to_provider == self.send_email_to_provider - assert input_invoice_message_content.is_flexible == self.is_flexible + assert input_invoice_message_content.send_email_to_provider == Space.send_email_to_provider + assert input_invoice_message_content.is_flexible == Space.is_flexible def test_equality(self): a = InputInvoiceMessageContent( - self.title, - self.description, - self.payload, - self.provider_token, - self.currency, - self.prices, + Space.title, + Space.description, + Space.payload, + Space.provider_token, + Space.currency, + Space.prices, ) b = InputInvoiceMessageContent( - self.title, - self.description, - self.payload, - self.provider_token, - self.currency, - self.prices, + Space.title, + Space.description, + Space.payload, + Space.provider_token, + Space.currency, + Space.prices, max_tip_amount=100, provider_data="foobar", ) c = InputInvoiceMessageContent( - self.title, - self.description, - self.payload, - self.provider_token, - self.currency, + Space.title, + Space.description, + Space.payload, + Space.provider_token, + Space.currency, # the first prices amount & the second lebal changed [LabeledPrice("label1", 24), LabeledPrice("label22", 314)], ) d = InputInvoiceMessageContent( - self.title, - self.description, + Space.title, + Space.description, "different_payload", - self.provider_token, - self.currency, - self.prices, + Space.provider_token, + Space.currency, + Space.prices, ) e = InputTextMessageContent("text") diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index 6c7249ac96c..06aef05d915 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -21,19 +21,19 @@ from telegram import InputLocationMessageContent, Location -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_location_message_content(): return InputLocationMessageContent( - TestInputLocationMessageContent.latitude, - TestInputLocationMessageContent.longitude, - live_period=TestInputLocationMessageContent.live_period, - horizontal_accuracy=TestInputLocationMessageContent.horizontal_accuracy, - heading=TestInputLocationMessageContent.heading, - proximity_alert_radius=TestInputLocationMessageContent.proximity_alert_radius, + Space.latitude, + Space.longitude, + live_period=Space.live_period, + horizontal_accuracy=Space.horizontal_accuracy, + heading=Space.heading, + proximity_alert_radius=Space.proximity_alert_radius, ) -class TestInputLocationMessageContent: +class Space: latitude = -23.691288 longitude = -46.788279 live_period = 80 @@ -41,6 +41,8 @@ class TestInputLocationMessageContent: heading = 90 proximity_alert_radius = 999 + +class TestInputLocationMessageContentNoReq: def test_slot_behaviour(self, input_location_message_content, mro_slots): inst = input_location_message_content for attr in inst.__slots__: @@ -48,12 +50,14 @@ def test_slot_behaviour(self, input_location_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_location_message_content): - assert input_location_message_content.longitude == self.longitude - assert input_location_message_content.latitude == self.latitude - assert input_location_message_content.live_period == self.live_period - assert input_location_message_content.horizontal_accuracy == self.horizontal_accuracy - assert input_location_message_content.heading == self.heading - assert input_location_message_content.proximity_alert_radius == self.proximity_alert_radius + assert input_location_message_content.longitude == Space.longitude + assert input_location_message_content.latitude == Space.latitude + assert input_location_message_content.live_period == Space.live_period + assert input_location_message_content.horizontal_accuracy == Space.horizontal_accuracy + assert input_location_message_content.heading == Space.heading + assert ( + input_location_message_content.proximity_alert_radius == Space.proximity_alert_radius + ) def test_to_dict(self, input_location_message_content): input_location_message_content_dict = input_location_message_content.to_dict() diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index d7f0e96789d..dcad5f18c37 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -55,72 +55,72 @@ from .test_video import video, video_file # noqa: F401 -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_media_video(class_thumb_file): return InputMediaVideo( - media=TestInputMediaVideo.media, - caption=TestInputMediaVideo.caption, - width=TestInputMediaVideo.width, - height=TestInputMediaVideo.height, - duration=TestInputMediaVideo.duration, - parse_mode=TestInputMediaVideo.parse_mode, - caption_entities=TestInputMediaVideo.caption_entities, + media=VideoSpace.media, + caption=VideoSpace.caption, + width=VideoSpace.width, + height=VideoSpace.height, + duration=VideoSpace.duration, + parse_mode=VideoSpace.parse_mode, + caption_entities=VideoSpace.caption_entities, thumb=class_thumb_file, - supports_streaming=TestInputMediaVideo.supports_streaming, + supports_streaming=VideoSpace.supports_streaming, ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_media_photo(class_thumb_file): return InputMediaPhoto( - media=TestInputMediaPhoto.media, - caption=TestInputMediaPhoto.caption, - parse_mode=TestInputMediaPhoto.parse_mode, - caption_entities=TestInputMediaPhoto.caption_entities, + media=PhotoSpace.media, + caption=PhotoSpace.caption, + parse_mode=PhotoSpace.parse_mode, + caption_entities=PhotoSpace.caption_entities, ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_media_animation(class_thumb_file): return InputMediaAnimation( - media=TestInputMediaAnimation.media, - caption=TestInputMediaAnimation.caption, - parse_mode=TestInputMediaAnimation.parse_mode, - caption_entities=TestInputMediaAnimation.caption_entities, - width=TestInputMediaAnimation.width, - height=TestInputMediaAnimation.height, + media=AnimationSpace.media, + caption=AnimationSpace.caption, + parse_mode=AnimationSpace.parse_mode, + caption_entities=AnimationSpace.caption_entities, + width=AnimationSpace.width, + height=AnimationSpace.height, thumb=class_thumb_file, - duration=TestInputMediaAnimation.duration, + duration=AnimationSpace.duration, ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_media_audio(class_thumb_file): return InputMediaAudio( - media=TestInputMediaAudio.media, - caption=TestInputMediaAudio.caption, - duration=TestInputMediaAudio.duration, - performer=TestInputMediaAudio.performer, - title=TestInputMediaAudio.title, + media=AudioSpace.media, + caption=AudioSpace.caption, + duration=AudioSpace.duration, + performer=AudioSpace.performer, + title=AudioSpace.title, thumb=class_thumb_file, - parse_mode=TestInputMediaAudio.parse_mode, - caption_entities=TestInputMediaAudio.caption_entities, + parse_mode=AudioSpace.parse_mode, + caption_entities=AudioSpace.caption_entities, ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_media_document(class_thumb_file): return InputMediaDocument( - media=TestInputMediaDocument.media, - caption=TestInputMediaDocument.caption, + media=DocumentSpace.media, + caption=DocumentSpace.caption, thumb=class_thumb_file, - parse_mode=TestInputMediaDocument.parse_mode, - caption_entities=TestInputMediaDocument.caption_entities, - disable_content_type_detection=TestInputMediaDocument.disable_content_type_detection, + parse_mode=DocumentSpace.parse_mode, + caption_entities=DocumentSpace.caption_entities, + disable_content_type_detection=DocumentSpace.disable_content_type_detection, ) -class TestInputMediaVideo: +class VideoSpace: type_ = "video" media = "NOTAREALFILEID" caption = "My Caption" @@ -131,6 +131,8 @@ class TestInputMediaVideo: supports_streaming = True caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] + +class TestInputMediaVideoNoReq: def test_slot_behaviour(self, input_media_video, mro_slots): inst = input_media_video for attr in inst.__slots__: @@ -138,19 +140,19 @@ def test_slot_behaviour(self, input_media_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_video): - assert input_media_video.type == self.type_ - assert input_media_video.media == self.media - assert input_media_video.caption == self.caption - assert input_media_video.width == self.width - assert input_media_video.height == self.height - assert input_media_video.duration == self.duration - assert input_media_video.parse_mode == self.parse_mode - assert input_media_video.caption_entities == tuple(self.caption_entities) - assert input_media_video.supports_streaming == self.supports_streaming + assert input_media_video.type == VideoSpace.type_ + assert input_media_video.media == VideoSpace.media + assert input_media_video.caption == VideoSpace.caption + assert input_media_video.width == VideoSpace.width + assert input_media_video.height == VideoSpace.height + assert input_media_video.duration == VideoSpace.duration + assert input_media_video.parse_mode == VideoSpace.parse_mode + assert input_media_video.caption_entities == tuple(VideoSpace.caption_entities) + assert input_media_video.supports_streaming == VideoSpace.supports_streaming assert isinstance(input_media_video.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_video = InputMediaVideo(self.media) + input_media_video = InputMediaVideo(VideoSpace.media) assert input_media_video.caption_entities == () def test_to_dict(self, input_media_video): @@ -170,7 +172,7 @@ def test_to_dict(self, input_media_video): def test_with_video(self, video): # noqa: F811 # fixture found in test_video input_media_video = InputMediaVideo(video, caption="test 3") - assert input_media_video.type == self.type_ + assert input_media_video.type == VideoSpace.type_ assert input_media_video.media == video.file_id assert input_media_video.width == video.width assert input_media_video.height == video.height @@ -180,7 +182,7 @@ def test_with_video(self, video): # noqa: F811 def test_with_video_file(self, video_file): # noqa: F811 # fixture found in test_video input_media_video = InputMediaVideo(video_file, caption="test 3") - assert input_media_video.type == self.type_ + assert input_media_video.type == VideoSpace.type_ assert isinstance(input_media_video.media, InputFile) assert input_media_video.caption == "test 3" @@ -192,13 +194,15 @@ def test_with_local_files(self): assert input_media_video.thumb == data_file("telegram.jpg").as_uri() -class TestInputMediaPhoto: +class PhotoSpace: type_ = "photo" media = "NOTAREALFILEID" caption = "My Caption" parse_mode = "Markdown" caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] + +class TestInputMediaPhotoNoReq: def test_slot_behaviour(self, input_media_photo, mro_slots): inst = input_media_photo for attr in inst.__slots__: @@ -206,14 +210,14 @@ def test_slot_behaviour(self, input_media_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_photo): - assert input_media_photo.type == self.type_ - assert input_media_photo.media == self.media - assert input_media_photo.caption == self.caption - assert input_media_photo.parse_mode == self.parse_mode - assert input_media_photo.caption_entities == tuple(self.caption_entities) + assert input_media_photo.type == PhotoSpace.type_ + assert input_media_photo.media == PhotoSpace.media + assert input_media_photo.caption == PhotoSpace.caption + assert input_media_photo.parse_mode == PhotoSpace.parse_mode + assert input_media_photo.caption_entities == tuple(PhotoSpace.caption_entities) def test_caption_entities_always_tuple(self): - input_media_photo = InputMediaPhoto(self.media) + input_media_photo = InputMediaPhoto(PhotoSpace.media) assert input_media_photo.caption_entities == () def test_to_dict(self, input_media_photo): @@ -229,14 +233,14 @@ def test_to_dict(self, input_media_photo): def test_with_photo(self, photo): # noqa: F811 # fixture found in test_photo input_media_photo = InputMediaPhoto(photo, caption="test 2") - assert input_media_photo.type == self.type_ + assert input_media_photo.type == PhotoSpace.type_ assert input_media_photo.media == photo.file_id assert input_media_photo.caption == "test 2" def test_with_photo_file(self, photo_file): # noqa: F811 # fixture found in test_photo input_media_photo = InputMediaPhoto(photo_file, caption="test 2") - assert input_media_photo.type == self.type_ + assert input_media_photo.type == PhotoSpace.type_ assert isinstance(input_media_photo.media, InputFile) assert input_media_photo.caption == "test 2" @@ -245,7 +249,7 @@ def test_with_local_files(self): assert input_media_photo.media == data_file("telegram.mp4").as_uri() -class TestInputMediaAnimation: +class AnimationSpace: type_ = "animation" media = "NOTAREALFILEID" caption = "My Caption" @@ -255,6 +259,8 @@ class TestInputMediaAnimation: height = 30 duration = 1 + +class TestInputMediaAnimationNoReq: def test_slot_behaviour(self, input_media_animation, mro_slots): inst = input_media_animation for attr in inst.__slots__: @@ -262,15 +268,15 @@ def test_slot_behaviour(self, input_media_animation, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_animation): - assert input_media_animation.type == self.type_ - assert input_media_animation.media == self.media - assert input_media_animation.caption == self.caption - assert input_media_animation.parse_mode == self.parse_mode - assert input_media_animation.caption_entities == tuple(self.caption_entities) + assert input_media_animation.type == AnimationSpace.type_ + assert input_media_animation.media == AnimationSpace.media + assert input_media_animation.caption == AnimationSpace.caption + assert input_media_animation.parse_mode == AnimationSpace.parse_mode + assert input_media_animation.caption_entities == tuple(AnimationSpace.caption_entities) assert isinstance(input_media_animation.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_animation = InputMediaAnimation(self.media) + input_media_animation = InputMediaAnimation(AnimationSpace.media) assert input_media_animation.caption_entities == () def test_to_dict(self, input_media_animation): @@ -289,14 +295,14 @@ def test_to_dict(self, input_media_animation): def test_with_animation(self, animation): # noqa: F811 # fixture found in test_animation input_media_animation = InputMediaAnimation(animation, caption="test 2") - assert input_media_animation.type == self.type_ + assert input_media_animation.type == AnimationSpace.type_ assert input_media_animation.media == animation.file_id assert input_media_animation.caption == "test 2" def test_with_animation_file(self, animation_file): # noqa: F811 # fixture found in test_animation input_media_animation = InputMediaAnimation(animation_file, caption="test 2") - assert input_media_animation.type == self.type_ + assert input_media_animation.type == AnimationSpace.type_ assert isinstance(input_media_animation.media, InputFile) assert input_media_animation.caption == "test 2" @@ -308,7 +314,7 @@ def test_with_local_files(self): assert input_media_animation.thumb == data_file("telegram.jpg").as_uri() -class TestInputMediaAudio: +class AudioSpace: type_ = "audio" media = "NOTAREALFILEID" caption = "My Caption" @@ -318,6 +324,8 @@ class TestInputMediaAudio: parse_mode = "HTML" caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] + +class TestInputMediaAudioNoReq: def test_slot_behaviour(self, input_media_audio, mro_slots): inst = input_media_audio for attr in inst.__slots__: @@ -325,18 +333,18 @@ def test_slot_behaviour(self, input_media_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_audio): - assert input_media_audio.type == self.type_ - assert input_media_audio.media == self.media - assert input_media_audio.caption == self.caption - assert input_media_audio.duration == self.duration - assert input_media_audio.performer == self.performer - assert input_media_audio.title == self.title - assert input_media_audio.parse_mode == self.parse_mode - assert input_media_audio.caption_entities == tuple(self.caption_entities) + assert input_media_audio.type == AudioSpace.type_ + assert input_media_audio.media == AudioSpace.media + assert input_media_audio.caption == AudioSpace.caption + assert input_media_audio.duration == AudioSpace.duration + assert input_media_audio.performer == AudioSpace.performer + assert input_media_audio.title == AudioSpace.title + assert input_media_audio.parse_mode == AudioSpace.parse_mode + assert input_media_audio.caption_entities == tuple(AudioSpace.caption_entities) assert isinstance(input_media_audio.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_audio = InputMediaAudio(self.media) + input_media_audio = InputMediaAudio(AudioSpace.media) assert input_media_audio.caption_entities == () def test_to_dict(self, input_media_audio): @@ -355,7 +363,7 @@ def test_to_dict(self, input_media_audio): def test_with_audio(self, audio): # noqa: F811 # fixture found in test_audio input_media_audio = InputMediaAudio(audio, caption="test 3") - assert input_media_audio.type == self.type_ + assert input_media_audio.type == AudioSpace.type_ assert input_media_audio.media == audio.file_id assert input_media_audio.duration == audio.duration assert input_media_audio.performer == audio.performer @@ -365,7 +373,7 @@ def test_with_audio(self, audio): # noqa: F811 def test_with_audio_file(self, audio_file): # noqa: F811 # fixture found in test_audio input_media_audio = InputMediaAudio(audio_file, caption="test 3") - assert input_media_audio.type == self.type_ + assert input_media_audio.type == AudioSpace.type_ assert isinstance(input_media_audio.media, InputFile) assert input_media_audio.caption == "test 3" @@ -377,7 +385,7 @@ def test_with_local_files(self): assert input_media_audio.thumb == data_file("telegram.jpg").as_uri() -class TestInputMediaDocument: +class DocumentSpace: type_ = "document" media = "NOTAREALFILEID" caption = "My Caption" @@ -385,6 +393,8 @@ class TestInputMediaDocument: caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] disable_content_type_detection = True + +class TestInputMediaDocumentNoReq: def test_slot_behaviour(self, input_media_document, mro_slots): inst = input_media_document for attr in inst.__slots__: @@ -392,19 +402,19 @@ def test_slot_behaviour(self, input_media_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_document): - assert input_media_document.type == self.type_ - assert input_media_document.media == self.media - assert input_media_document.caption == self.caption - assert input_media_document.parse_mode == self.parse_mode - assert input_media_document.caption_entities == tuple(self.caption_entities) + assert input_media_document.type == DocumentSpace.type_ + assert input_media_document.media == DocumentSpace.media + assert input_media_document.caption == DocumentSpace.caption + assert input_media_document.parse_mode == DocumentSpace.parse_mode + assert input_media_document.caption_entities == tuple(DocumentSpace.caption_entities) assert ( input_media_document.disable_content_type_detection - == self.disable_content_type_detection + == DocumentSpace.disable_content_type_detection ) assert isinstance(input_media_document.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_document = InputMediaDocument(self.media) + input_media_document = InputMediaDocument(DocumentSpace.media) assert input_media_document.caption_entities == () def test_to_dict(self, input_media_document): @@ -424,14 +434,14 @@ def test_to_dict(self, input_media_document): def test_with_document(self, document): # noqa: F811 # fixture found in test_document input_media_document = InputMediaDocument(document, caption="test 3") - assert input_media_document.type == self.type_ + assert input_media_document.type == DocumentSpace.type_ assert input_media_document.media == document.file_id assert input_media_document.caption == "test 3" def test_with_document_file(self, document_file): # noqa: F811 # fixture found in test_document input_media_document = InputMediaDocument(document_file, caption="test 3") - assert input_media_document.type == self.type_ + assert input_media_document.type == DocumentSpace.type_ assert isinstance(input_media_document.media, InputFile) assert input_media_document.caption == "test 3" @@ -443,7 +453,7 @@ def test_with_local_files(self): assert input_media_document.thumb == data_file("telegram.jpg").as_uri() -@pytest.fixture(scope="function") # noqa: F811 +@pytest.fixture(scope="module") # noqa: F811 def media_group(photo, thumb): # noqa: F811 return [ InputMediaPhoto(photo, caption="*photo* 1", parse_mode="Markdown"), @@ -454,12 +464,12 @@ def media_group(photo, thumb): # noqa: F811 ] -@pytest.fixture(scope="function") # noqa: F811 +@pytest.fixture(scope="module") # noqa: F811 def media_group_no_caption_args(photo, thumb): # noqa: F811 return [InputMediaPhoto(photo), InputMediaPhoto(thumb), InputMediaPhoto(photo)] -@pytest.fixture(scope="function") # noqa: F811 +@pytest.fixture(scope="module") # noqa: F811 def media_group_no_caption_only_caption_entities(photo, thumb): # noqa: F811 return [ InputMediaPhoto(photo, caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)]), @@ -467,7 +477,7 @@ def media_group_no_caption_only_caption_entities(photo, thumb): # noqa: F811 ] -@pytest.fixture(scope="function") # noqa: F811 +@pytest.fixture(scope="module") # noqa: F811 def media_group_no_caption_only_parse_mode(photo, thumb): # noqa: F811 return [ InputMediaPhoto(photo, parse_mode="Markdown"), @@ -475,8 +485,90 @@ def media_group_no_caption_only_parse_mode(photo, thumb): # noqa: F811 ] -class TestSendMediaGroup: - @pytest.mark.flaky(3, 1) +class TestSendMediaGroupNoReq: + async def test_send_media_group_throws_error_with_group_caption_and_individual_captions( + self, + bot, + chat_id, + media_group, + media_group_no_caption_only_caption_entities, + media_group_no_caption_only_parse_mode, + ): + for group in ( + media_group, + media_group_no_caption_only_caption_entities, + media_group_no_caption_only_parse_mode, + ): + with pytest.raises( + ValueError, + match="You can only supply either group caption or media with captions.", + ): + await bot.send_media_group(chat_id, group, caption="foo") + + async def test_send_media_group_custom_filename( + self, + bot, + chat_id, + photo_file, # noqa: F811 + animation_file, # noqa: F811 + audio_file, # noqa: F811 + video_file, # noqa: F811 + monkeypatch, + ): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + result = all( + field_tuple[0] == "custom_filename" + for field_tuple in request_data.multipart_data.values() + ) + if result is True: + raise Exception("Test was successful") + + monkeypatch.setattr(bot.request, "post", make_assertion) + + media = [ + InputMediaAnimation(animation_file, filename="custom_filename"), + InputMediaAudio(audio_file, filename="custom_filename"), + InputMediaPhoto(photo_file, filename="custom_filename"), + InputMediaVideo(video_file, filename="custom_filename"), + ] + + with pytest.raises(Exception, match="Test was successful"): + await bot.send_media_group(chat_id, media) + + async def test_send_media_group_with_thumbs( + self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 + ): + async def make_assertion(method, url, request_data: RequestData, *args, **kwargs): + files = request_data.multipart_data + video_check = files[input_video.media.attach_name] == input_video.media.field_tuple + thumb_check = files[input_video.thumb.attach_name] == input_video.thumb.field_tuple + result = video_check and thumb_check + raise Exception(f"Test was {'successful' if result else 'failing'}") + + monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) + input_video = InputMediaVideo(video_file, thumb=photo_file) + with pytest.raises(Exception, match="Test was successful"): + await bot.send_media_group(chat_id, [input_video, input_video]) + + async def test_edit_message_media_with_thumb( + self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 + ): + async def make_assertion( + method: str, url: str, request_data: RequestData = None, *args, **kwargs + ): + files = request_data.multipart_data + video_check = files[input_video.media.attach_name] == input_video.media.field_tuple + thumb_check = files[input_video.thumb.attach_name] == input_video.thumb.field_tuple + result = video_check and thumb_check + raise Exception(f"Test was {'successful' if result else 'failing'}") + + monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) + input_video = InputMediaVideo(video_file, thumb=photo_file) + with pytest.raises(Exception, match="Test was successful"): + await bot.edit_message_media(chat_id=chat_id, message_id=123, media=input_video) + + +class TestSendMediaGroupReq: async def test_send_media_group_photo(self, bot, chat_id, media_group): messages = await bot.send_media_group(chat_id, media_group) assert isinstance(messages, tuple) @@ -488,6 +580,33 @@ async def test_send_media_group_photo(self, bot, chat_id, media_group): mes.caption_entities == (MessageEntity(MessageEntity.BOLD, 0, 5),) for mes in messages ) + async def test_send_media_group_new_files( + self, + bot, + chat_id, + video_file, # noqa: F811 + photo_file, # noqa: F811 + animation_file, # noqa: F811 + ): + async def func(): + return await bot.send_media_group( + chat_id, + [ + InputMediaVideo(video_file), + InputMediaPhoto(photo_file), + InputMediaPhoto(data_file("telegram.jpg").read_bytes()), + ], + ) + + messages = await expect_bad_request( + func, "Type of file mismatch", "Telegram did not accept the file." + ) + + assert isinstance(messages, tuple) + assert len(messages) == 3 + assert all(isinstance(mes, Message) for mes in messages) + assert all(mes.media_group_id == messages[0].media_group_id for mes in messages) + async def test_send_media_group_with_message_thread_id( self, bot, real_topic, forum_group_id, media_group # noqa: F811 ): @@ -501,25 +620,6 @@ async def test_send_media_group_with_message_thread_id( assert all(isinstance(mes, Message) for mes in messages) assert all(i.message_thread_id == real_topic.message_thread_id for i in messages) - async def test_send_media_group_throws_error_with_group_caption_and_individual_captions( - self, - bot, - chat_id, - media_group, - media_group_no_caption_only_caption_entities, - media_group_no_caption_only_parse_mode, - ): - for group in ( - media_group, - media_group_no_caption_only_caption_entities, - media_group_no_caption_only_parse_mode, - ): - with pytest.raises( - ValueError, - match="You can only supply either group caption or media with captions.", - ): - await bot.send_media_group(chat_id, group, caption="foo") - @pytest.mark.parametrize( "caption, parse_mode, caption_entities", [ @@ -529,7 +629,6 @@ async def test_send_media_group_throws_error_with_group_caption_and_individual_c ("photo 1", None, [MessageEntity(MessageEntity.BOLD, 0, 5)]), ], ) - @pytest.mark.flaky(3, 1) async def test_send_media_group_with_group_caption( self, bot, @@ -574,7 +673,6 @@ async def test_send_media_group_with_group_caption( assert all(mes.caption is None for mes in other_messages) assert not any(mes.caption_entities for mes in other_messages) - @pytest.mark.flaky(3, 1) async def test_send_media_group_all_args(self, bot, raw_bot, chat_id, media_group): ext_bot = bot for bot in (ext_bot, raw_bot): @@ -609,81 +707,6 @@ async def test_send_media_group_all_args(self, bot, raw_bot, chat_id, media_grou ) assert all(mes.has_protected_content for mes in messages) - @pytest.mark.flaky(3, 1) - async def test_send_media_group_custom_filename( - self, - bot, - chat_id, - photo_file, # noqa: F811 - animation_file, # noqa: F811 - audio_file, # noqa: F811 - video_file, # noqa: F811 - monkeypatch, - ): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - result = all( - field_tuple[0] == "custom_filename" - for field_tuple in request_data.multipart_data.values() - ) - if result is True: - raise Exception("Test was successful") - - monkeypatch.setattr(bot.request, "post", make_assertion) - - media = [ - InputMediaAnimation(animation_file, filename="custom_filename"), - InputMediaAudio(audio_file, filename="custom_filename"), - InputMediaPhoto(photo_file, filename="custom_filename"), - InputMediaVideo(video_file, filename="custom_filename"), - ] - - with pytest.raises(Exception, match="Test was successful"): - await bot.send_media_group(chat_id, media) - - async def test_send_media_group_with_thumbs( - self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 - ): - async def make_assertion(method, url, request_data: RequestData, *args, **kwargs): - files = request_data.multipart_data - video_check = files[input_video.media.attach_name] == input_video.media.field_tuple - thumb_check = files[input_video.thumb.attach_name] == input_video.thumb.field_tuple - result = video_check and thumb_check - raise Exception(f"Test was {'successful' if result else 'failing'}") - - monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) - input_video = InputMediaVideo(video_file, thumb=photo_file) - with pytest.raises(Exception, match="Test was successful"): - await bot.send_media_group(chat_id, [input_video, input_video]) - - @pytest.mark.flaky(3, 1) # noqa: F811 - async def test_send_media_group_new_files( - self, - bot, - chat_id, - video_file, # noqa: F811 - photo_file, # noqa: F811 - animation_file, # noqa: F811 - ): - async def func(): - return await bot.send_media_group( - chat_id, - [ - InputMediaVideo(video_file), - InputMediaPhoto(photo_file), - InputMediaPhoto(data_file("telegram.jpg").read_bytes()), - ], - ) - - messages = await expect_bad_request( - func, "Type of file mismatch", "Telegram did not accept the file." - ) - - assert isinstance(messages, tuple) - assert len(messages) == 3 - assert all(isinstance(mes, Message) for mes in messages) - assert all(mes.media_group_id == messages[0].media_group_id for mes in messages) - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -717,7 +740,6 @@ async def test_send_media_group_default_allow_sending_without_reply( chat_id, media_group, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_media_group_default_protect_content( self, chat_id, media_group, default_bot @@ -729,7 +751,6 @@ async def test_send_media_group_default_protect_content( ) assert not all(msg.has_protected_content for msg in unprotected) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": ParseMode.HTML}], indirect=True) async def test_send_media_group_default_parse_mode( self, chat_id, media_group_no_caption_args, default_bot @@ -774,7 +795,6 @@ async def test_send_media_group_default_parse_mode( assert all(mes.caption is None for mes in other_messages) assert not any(mes.caption_entities for mes in other_messages) - @pytest.mark.flaky(3, 1) async def test_edit_message_media(self, bot, raw_bot, chat_id, media_group): ext_bot = bot for bot in (ext_bot, raw_bot): @@ -793,7 +813,6 @@ async def test_edit_message_media(self, bot, raw_bot, chat_id, media_group): # make sure that the media was not modified assert media_group[0].parse_mode == copied_media.parse_mode - @pytest.mark.flaky(3, 1) async def test_edit_message_media_new_file(self, bot, chat_id, media_group, thumb_file): messages = await bot.send_media_group(chat_id, media_group) cid = messages[-1].chat.id @@ -803,24 +822,6 @@ async def test_edit_message_media_new_file(self, bot, chat_id, media_group, thum ) assert isinstance(new_message, Message) - async def test_edit_message_media_with_thumb( - self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 - ): - async def make_assertion( - method: str, url: str, request_data: RequestData = None, *args, **kwargs - ): - files = request_data.multipart_data - video_check = files[input_video.media.attach_name] == input_video.media.field_tuple - thumb_check = files[input_video.thumb.attach_name] == input_video.thumb.field_tuple - result = video_check and thumb_check - raise Exception(f"Test was {'successful' if result else 'failing'}") - - monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) - input_video = InputMediaVideo(video_file, thumb=photo_file) - with pytest.raises(Exception, match="Test was successful"): - await bot.edit_message_media(chat_id=chat_id, message_id=123, media=input_video) - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot", [{"parse_mode": ParseMode.HTML}], indirect=True, ids=["HTML-Bot"] ) diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 6f288deebe2..cf2d5cc4e4d 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -22,22 +22,24 @@ from telegram.constants import ParseMode -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_text_message_content(): return InputTextMessageContent( - TestInputTextMessageContent.message_text, - parse_mode=TestInputTextMessageContent.parse_mode, - entities=TestInputTextMessageContent.entities, - disable_web_page_preview=TestInputTextMessageContent.disable_web_page_preview, + Space.message_text, + parse_mode=Space.parse_mode, + entities=Space.entities, + disable_web_page_preview=Space.disable_web_page_preview, ) -class TestInputTextMessageContent: +class Space: message_text = "*message text*" parse_mode = ParseMode.MARKDOWN entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] disable_web_page_preview = True + +class TestInputTextMessageContentNoReq: def test_slot_behaviour(self, input_text_message_content, mro_slots): inst = input_text_message_content for attr in inst.__slots__: @@ -45,10 +47,12 @@ def test_slot_behaviour(self, input_text_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_text_message_content): - assert input_text_message_content.parse_mode == self.parse_mode - assert input_text_message_content.message_text == self.message_text - assert input_text_message_content.disable_web_page_preview == self.disable_web_page_preview - assert input_text_message_content.entities == tuple(self.entities) + assert input_text_message_content.parse_mode == Space.parse_mode + assert input_text_message_content.message_text == Space.message_text + assert ( + input_text_message_content.disable_web_page_preview == Space.disable_web_page_preview + ) + assert input_text_message_content.entities == tuple(Space.entities) def test_entities_always_tuple(self): input_text_message_content = InputTextMessageContent("text") diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index c29edaa5814..00006c1bfbf 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -21,21 +21,21 @@ from telegram import InputVenueMessageContent, Location -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def input_venue_message_content(): return InputVenueMessageContent( - TestInputVenueMessageContent.latitude, - TestInputVenueMessageContent.longitude, - TestInputVenueMessageContent.title, - TestInputVenueMessageContent.address, - foursquare_id=TestInputVenueMessageContent.foursquare_id, - foursquare_type=TestInputVenueMessageContent.foursquare_type, - google_place_id=TestInputVenueMessageContent.google_place_id, - google_place_type=TestInputVenueMessageContent.google_place_type, + Space.latitude, + Space.longitude, + Space.title, + Space.address, + foursquare_id=Space.foursquare_id, + foursquare_type=Space.foursquare_type, + google_place_id=Space.google_place_id, + google_place_type=Space.google_place_type, ) -class TestInputVenueMessageContent: +class Space: latitude = 1.0 longitude = 2.0 title = "title" @@ -45,6 +45,8 @@ class TestInputVenueMessageContent: google_place_id = "google place id" google_place_type = "google place type" + +class TestInputVenueMessageContentNoReq: def test_slot_behaviour(self, input_venue_message_content, mro_slots): inst = input_venue_message_content for attr in inst.__slots__: @@ -52,14 +54,14 @@ def test_slot_behaviour(self, input_venue_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_venue_message_content): - assert input_venue_message_content.longitude == self.longitude - assert input_venue_message_content.latitude == self.latitude - assert input_venue_message_content.title == self.title - assert input_venue_message_content.address == self.address - assert input_venue_message_content.foursquare_id == self.foursquare_id - assert input_venue_message_content.foursquare_type == self.foursquare_type - assert input_venue_message_content.google_place_id == self.google_place_id - assert input_venue_message_content.google_place_type == self.google_place_type + assert input_venue_message_content.longitude == Space.longitude + assert input_venue_message_content.latitude == Space.latitude + assert input_venue_message_content.title == Space.title + assert input_venue_message_content.address == Space.address + assert input_venue_message_content.foursquare_id == Space.foursquare_id + assert input_venue_message_content.foursquare_type == Space.foursquare_type + assert input_venue_message_content.google_place_id == Space.google_place_id + assert input_venue_message_content.google_place_type == Space.google_place_type def test_to_dict(self, input_venue_message_content): input_venue_message_content_dict = input_venue_message_content.to_dict() diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 299afc59591..47bfc78b856 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -23,18 +23,18 @@ from telegram.request import RequestData -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def invoice(): return Invoice( - TestInvoice.title, - TestInvoice.description, - TestInvoice.start_parameter, - TestInvoice.currency, - TestInvoice.total_amount, + Space.title, + Space.description, + Space.start_parameter, + Space.currency, + Space.total_amount, ) -class TestInvoice: +class Space: payload = "payload" prices = [LabeledPrice("Fish", 100), LabeledPrice("Fish Tax", 1000)] provider_data = """{"test":"test"}""" @@ -46,6 +46,8 @@ class TestInvoice: max_tip_amount = 42 suggested_tip_amounts = [13, 42] + +class TestInvoiceNoReq: def test_slot_behaviour(self, invoice, mro_slots): for attr in invoice.__slots__: assert getattr(invoice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -54,21 +56,21 @@ def test_slot_behaviour(self, invoice, mro_slots): 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, + "title": Space.title, + "description": Space.description, + "start_parameter": Space.start_parameter, + "currency": Space.currency, + "total_amount": Space.total_amount, }, bot, ) assert invoice_json.api_kwargs == {} - 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 + assert invoice_json.title == Space.title + assert invoice_json.description == Space.description + assert invoice_json.start_parameter == Space.start_parameter + assert invoice_json.currency == Space.currency + assert invoice_json.total_amount == Space.total_amount def test_to_dict(self, invoice): invoice_dict = invoice.to_dict() @@ -80,129 +82,6 @@ def test_to_dict(self, invoice): assert invoice_dict["currency"] == invoice.currency assert invoice_dict["total_amount"] == invoice.total_amount - @pytest.mark.flaky(3, 1) - async def test_send_required_args_only(self, bot, chat_id, provider_token): - message = await bot.send_invoice( - chat_id=chat_id, - title=self.title, - description=self.description, - payload=self.payload, - provider_token=provider_token, - currency=self.currency, - prices=self.prices, - ) - - assert message.invoice.currency == self.currency - assert message.invoice.start_parameter == "" - assert message.invoice.description == self.description - assert message.invoice.title == self.title - assert message.invoice.total_amount == self.total_amount - - link = await bot.create_invoice_link( - title=self.title, - description=self.description, - payload=self.payload, - provider_token=provider_token, - currency=self.currency, - prices=self.prices, - ) - assert isinstance(link, str) - assert link != "" - - async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token, monkeypatch): - message = await bot.send_invoice( - chat_id, - self.title, - self.description, - self.payload, - provider_token, - self.currency, - self.prices, - max_tip_amount=self.max_tip_amount, - suggested_tip_amounts=self.suggested_tip_amounts, - start_parameter=self.start_parameter, - provider_data=self.provider_data, - photo_url="https://raw.githubusercontent.com/" - "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, - send_phone_number_to_provider=True, - send_email_to_provider=True, - is_flexible=True, - disable_notification=True, - protect_content=True, - ) - - 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 - assert message.has_protected_content - - # We do this next one as safety guard to make sure that we pass all of the optional - # parameters correctly because #2526 went unnoticed for 3 years … - async def make_assertion(*args, **_): - kwargs = args[1] - return ( - kwargs["chat_id"] == "chat_id" - and kwargs["title"] == "title" - and kwargs["description"] == "description" - and kwargs["payload"] == "payload" - and kwargs["provider_token"] == "provider_token" - and kwargs["currency"] == "currency" - and kwargs["prices"] == self.prices - and kwargs["max_tip_amount"] == "max_tip_amount" - and kwargs["suggested_tip_amounts"] == "suggested_tip_amounts" - and kwargs["start_parameter"] == "start_parameter" - and kwargs["provider_data"] == "provider_data" - and kwargs["photo_url"] == "photo_url" - and kwargs["photo_size"] == "photo_size" - and kwargs["photo_width"] == "photo_width" - and kwargs["photo_height"] == "photo_height" - and kwargs["need_name"] == "need_name" - and kwargs["need_phone_number"] == "need_phone_number" - and kwargs["need_email"] == "need_email" - and kwargs["need_shipping_address"] == "need_shipping_address" - and kwargs["send_phone_number_to_provider"] == "send_phone_number_to_provider" - and kwargs["send_email_to_provider"] == "send_email_to_provider" - and kwargs["is_flexible"] == "is_flexible" - ) - - monkeypatch.setattr(bot, "_send_message", make_assertion) - assert await bot.send_invoice( - chat_id="chat_id", - title="title", - description="description", - payload="payload", - provider_token="provider_token", - currency="currency", - prices=self.prices, - max_tip_amount="max_tip_amount", - suggested_tip_amounts="suggested_tip_amounts", - start_parameter="start_parameter", - provider_data="provider_data", - photo_url="photo_url", - photo_size="photo_size", - photo_width="photo_width", - photo_height="photo_height", - need_name="need_name", - need_phone_number="need_phone_number", - need_email="need_email", - need_shipping_address="need_shipping_address", - send_phone_number_to_provider="send_phone_number_to_provider", - send_email_to_provider="send_email_to_provider", - is_flexible="is_flexible", - disable_notification=True, - protect_content=True, - ) - async def test_send_all_args_create_invoice_link( self, bot, chat_id, provider_token, monkeypatch ): @@ -214,7 +93,7 @@ async def make_assertion(*args, **_): and kwargs["payload"] == "payload" and kwargs["provider_token"] == "provider_token" and kwargs["currency"] == "currency" - and kwargs["prices"] == self.prices + and kwargs["prices"] == Space.prices and kwargs["max_tip_amount"] == "max_tip_amount" and kwargs["suggested_tip_amounts"] == "suggested_tip_amounts" and kwargs["provider_data"] == "provider_data" @@ -238,7 +117,7 @@ async def make_assertion(*args, **_): payload="payload", provider_token="provider_token", currency="currency", - prices=self.prices, + prices=Space.prices, max_tip_amount="max_tip_amount", suggested_tip_amounts="suggested_tip_amounts", provider_data="provider_data", @@ -263,17 +142,87 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.send_invoice( chat_id, - self.title, - self.description, - self.payload, + Space.title, + Space.description, + Space.payload, provider_token, - self.currency, - self.prices, + Space.currency, + Space.prices, provider_data={"test_data": 123456789}, - start_parameter=self.start_parameter, + start_parameter=Space.start_parameter, + ) + + def test_equality(self): + a = Invoice("invoice", "desc", "start", "EUR", 7) + b = Invoice("invoice", "desc", "start", "EUR", 7) + c = Invoice("invoices", "description", "stop", "USD", 8) + d = LabeledPrice("label", 5) + + assert a == b + assert hash(a) == hash(b) + + assert a != c + assert hash(a) != hash(c) + + assert a != d + assert hash(a) != hash(d) + + +class TestInvoiceReq: + async def test_send_required_args_only(self, bot, chat_id, provider_token): + message = await bot.send_invoice( + chat_id=chat_id, + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=provider_token, + currency=Space.currency, + prices=Space.prices, + ) + + assert message.invoice.currency == Space.currency + assert message.invoice.start_parameter == "" + assert message.invoice.description == Space.description + assert message.invoice.title == Space.title + assert message.invoice.total_amount == Space.total_amount + + link = await bot.create_invoice_link( + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=provider_token, + currency=Space.currency, + prices=Space.prices, + ) + assert isinstance(link, str) + assert link != "" + + @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) + async def test_send_invoice_default_protect_content( + self, chat_id, default_bot, provider_token + ): + protected = await default_bot.send_invoice( + chat_id, + Space.title, + Space.description, + Space.payload, + provider_token, + Space.currency, + Space.prices, ) + assert protected.has_protected_content + unprotected = await default_bot.send_invoice( + chat_id, + Space.title, + Space.description, + Space.payload, + provider_token, + Space.currency, + Space.prices, + protect_content=False, + ) + assert not unprotected.has_protected_content - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -291,12 +240,12 @@ async def test_send_invoice_default_allow_sending_without_reply( if custom is not None: message = await default_bot.send_invoice( chat_id, - self.title, - self.description, - self.payload, + Space.title, + Space.description, + Space.payload, provider_token, - self.currency, - self.prices, + Space.currency, + Space.prices, allow_sending_without_reply=custom, reply_to_message_id=reply_to_message.message_id, ) @@ -304,12 +253,12 @@ async def test_send_invoice_default_allow_sending_without_reply( elif default_bot.defaults.allow_sending_without_reply: message = await default_bot.send_invoice( chat_id, - self.title, - self.description, - self.payload, + Space.title, + Space.description, + Space.payload, provider_token, - self.currency, - self.prices, + Space.currency, + Space.prices, reply_to_message_id=reply_to_message.message_id, ) assert message.reply_to_message is None @@ -317,53 +266,105 @@ async def test_send_invoice_default_allow_sending_without_reply( with pytest.raises(BadRequest, match="message not found"): await default_bot.send_invoice( chat_id, - self.title, - self.description, - self.payload, + Space.title, + Space.description, + Space.payload, provider_token, - self.currency, - self.prices, + Space.currency, + Space.prices, reply_to_message_id=reply_to_message.message_id, ) - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) - async def test_send_invoice_default_protect_content( - self, chat_id, default_bot, provider_token - ): - protected = await default_bot.send_invoice( - chat_id, - self.title, - self.description, - self.payload, - provider_token, - self.currency, - self.prices, - ) - assert protected.has_protected_content - unprotected = await default_bot.send_invoice( + async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token, monkeypatch): + message = await bot.send_invoice( chat_id, - self.title, - self.description, - self.payload, + Space.title, + Space.description, + Space.payload, provider_token, - self.currency, - self.prices, - protect_content=False, + Space.currency, + Space.prices, + max_tip_amount=Space.max_tip_amount, + suggested_tip_amounts=Space.suggested_tip_amounts, + start_parameter=Space.start_parameter, + provider_data=Space.provider_data, + photo_url="https://raw.githubusercontent.com/" + "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, + send_phone_number_to_provider=True, + send_email_to_provider=True, + is_flexible=True, + disable_notification=True, + protect_content=True, ) - assert not unprotected.has_protected_content - - def test_equality(self): - a = Invoice("invoice", "desc", "start", "EUR", 7) - b = Invoice("invoice", "desc", "start", "EUR", 7) - c = Invoice("invoices", "description", "stop", "USD", 8) - d = LabeledPrice("label", 5) - assert a == b - assert hash(a) == hash(b) + assert message.invoice.currency == Space.currency + assert message.invoice.start_parameter == Space.start_parameter + assert message.invoice.description == Space.description + assert message.invoice.title == Space.title + assert message.invoice.total_amount == Space.total_amount + assert message.has_protected_content - assert a != c - assert hash(a) != hash(c) + # We do this next one as safety guard to make sure that we pass all of the optional + # parameters correctly because #2526 went unnoticed for 3 years … + async def make_assertion(*args, **_): + kwargs = args[1] + return ( + kwargs["chat_id"] == "chat_id" + and kwargs["title"] == "title" + and kwargs["description"] == "description" + and kwargs["payload"] == "payload" + and kwargs["provider_token"] == "provider_token" + and kwargs["currency"] == "currency" + and kwargs["prices"] == Space.prices + and kwargs["max_tip_amount"] == "max_tip_amount" + and kwargs["suggested_tip_amounts"] == "suggested_tip_amounts" + and kwargs["start_parameter"] == "start_parameter" + and kwargs["provider_data"] == "provider_data" + and kwargs["photo_url"] == "photo_url" + and kwargs["photo_size"] == "photo_size" + and kwargs["photo_width"] == "photo_width" + and kwargs["photo_height"] == "photo_height" + and kwargs["need_name"] == "need_name" + and kwargs["need_phone_number"] == "need_phone_number" + and kwargs["need_email"] == "need_email" + and kwargs["need_shipping_address"] == "need_shipping_address" + and kwargs["send_phone_number_to_provider"] == "send_phone_number_to_provider" + and kwargs["send_email_to_provider"] == "send_email_to_provider" + and kwargs["is_flexible"] == "is_flexible" + ) - assert a != d - assert hash(a) != hash(d) + monkeypatch.setattr(bot, "_send_message", make_assertion) + assert await bot.send_invoice( + chat_id="chat_id", + title="title", + description="description", + payload="payload", + provider_token="provider_token", + currency="currency", + prices=Space.prices, + max_tip_amount="max_tip_amount", + suggested_tip_amounts="suggested_tip_amounts", + start_parameter="start_parameter", + provider_data="provider_data", + photo_url="photo_url", + photo_size="photo_size", + photo_width="photo_width", + photo_height="photo_height", + need_name="need_name", + need_phone_number="need_phone_number", + need_email="need_email", + need_shipping_address="need_shipping_address", + send_phone_number_to_provider="send_phone_number_to_provider", + send_email_to_provider="send_email_to_provider", + is_flexible="is_flexible", + disable_notification=True, + protect_content=True, + ) diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index 87673b87412..d9f14126213 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -21,24 +21,26 @@ from telegram import InlineKeyboardButton, KeyboardButton, KeyboardButtonPollType, WebAppInfo -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def keyboard_button(): return KeyboardButton( - TestKeyboardButton.text, - request_location=TestKeyboardButton.request_location, - request_contact=TestKeyboardButton.request_contact, - request_poll=TestKeyboardButton.request_poll, - web_app=TestKeyboardButton.web_app, + Space.text, + request_location=Space.request_location, + request_contact=Space.request_contact, + request_poll=Space.request_poll, + web_app=Space.web_app, ) -class TestKeyboardButton: +class Space: text = "text" request_location = True request_contact = True request_poll = KeyboardButtonPollType("quiz") web_app = WebAppInfo(url="https://example.com") + +class TestKeyboardButtonNoReq: def test_slot_behaviour(self, keyboard_button, mro_slots): inst = keyboard_button for attr in inst.__slots__: @@ -46,11 +48,11 @@ def test_slot_behaviour(self, keyboard_button, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" 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 - assert keyboard_button.request_poll == self.request_poll - assert keyboard_button.web_app == self.web_app + assert keyboard_button.text == Space.text + assert keyboard_button.request_location == Space.request_location + assert keyboard_button.request_contact == Space.request_contact + assert keyboard_button.request_poll == Space.request_poll + assert keyboard_button.web_app == Space.web_app def test_to_dict(self, keyboard_button): keyboard_button_dict = keyboard_button.to_dict() @@ -64,20 +66,20 @@ def test_to_dict(self, keyboard_button): def test_de_json(self, bot): json_dict = { - "text": self.text, - "request_location": self.request_location, - "request_contact": self.request_contact, - "request_poll": self.request_poll.to_dict(), - "web_app": self.web_app.to_dict(), + "text": Space.text, + "request_location": Space.request_location, + "request_contact": Space.request_contact, + "request_poll": Space.request_poll.to_dict(), + "web_app": Space.web_app.to_dict(), } inline_keyboard_button = KeyboardButton.de_json(json_dict, None) assert inline_keyboard_button.api_kwargs == {} - assert inline_keyboard_button.text == self.text - assert inline_keyboard_button.request_location == self.request_location - assert inline_keyboard_button.request_contact == self.request_contact - assert inline_keyboard_button.request_poll == self.request_poll - assert inline_keyboard_button.web_app == self.web_app + assert inline_keyboard_button.text == Space.text + assert inline_keyboard_button.request_location == Space.request_location + assert inline_keyboard_button.request_contact == Space.request_contact + assert inline_keyboard_button.request_poll == Space.request_poll + assert inline_keyboard_button.web_app == Space.web_app none = KeyboardButton.de_json({}, None) assert none is None diff --git a/tests/test_keyboardbuttonpolltype.py b/tests/test_keyboardbuttonpolltype.py index 41d2f4fbc3b..978670d6264 100644 --- a/tests/test_keyboardbuttonpolltype.py +++ b/tests/test_keyboardbuttonpolltype.py @@ -21,14 +21,16 @@ from telegram import KeyboardButtonPollType, Poll -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def keyboard_button_poll_type(): - return KeyboardButtonPollType(TestKeyboardButtonPollType.type) + return KeyboardButtonPollType(Space.type) -class TestKeyboardButtonPollType: +class Space: type = Poll.QUIZ + +class TestKeyboardButtonPollTypeNoReq: def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): inst = keyboard_button_poll_type for attr in inst.__slots__: @@ -38,7 +40,7 @@ def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): def test_to_dict(self, keyboard_button_poll_type): keyboard_button_poll_type_dict = keyboard_button_poll_type.to_dict() assert isinstance(keyboard_button_poll_type_dict, dict) - assert keyboard_button_poll_type_dict["type"] == self.type + assert keyboard_button_poll_type_dict["type"] == Space.type def test_equality(self): a = KeyboardButtonPollType(Poll.QUIZ) diff --git a/tests/test_labeledprice.py b/tests/test_labeledprice.py index 0586c3788fb..346d5bb69b8 100644 --- a/tests/test_labeledprice.py +++ b/tests/test_labeledprice.py @@ -21,15 +21,17 @@ from telegram import LabeledPrice, Location -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def labeled_price(): - return LabeledPrice(TestLabeledPrice.label, TestLabeledPrice.amount) + return LabeledPrice(Space.label, Space.amount) -class TestLabeledPrice: +class Space: label = "label" amount = 100 + +class TestLabeledPriceNoReq: def test_slot_behaviour(self, labeled_price, mro_slots): inst = labeled_price for attr in inst.__slots__: @@ -37,8 +39,8 @@ def test_slot_behaviour(self, labeled_price, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, labeled_price): - assert labeled_price.label == self.label - assert labeled_price.amount == self.amount + assert labeled_price.label == Space.label + assert labeled_price.amount == Space.amount def test_to_dict(self, labeled_price): labeled_price_dict = labeled_price.to_dict() diff --git a/tests/test_location.py b/tests/test_location.py index a33eb0fbc7e..ae038262a2e 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -23,19 +23,19 @@ from telegram.request import RequestData -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def location(): return Location( - latitude=TestLocation.latitude, - longitude=TestLocation.longitude, - horizontal_accuracy=TestLocation.horizontal_accuracy, - live_period=TestLocation.live_period, - heading=TestLocation.live_period, - proximity_alert_radius=TestLocation.proximity_alert_radius, + latitude=Space.latitude, + longitude=Space.longitude, + horizontal_accuracy=Space.horizontal_accuracy, + live_period=Space.live_period, + heading=Space.live_period, + proximity_alert_radius=Space.proximity_alert_radius, ) -class TestLocation: +class Space: latitude = -23.691288 longitude = -46.788279 horizontal_accuracy = 999 @@ -43,6 +43,8 @@ class TestLocation: heading = 90 proximity_alert_radius = 50 + +class TestLocationNoReq: def test_slot_behaviour(self, location, mro_slots): for attr in location.__slots__: assert getattr(location, attr, "err") != "err", f"got extra slot '{attr}'" @@ -50,66 +52,22 @@ def test_slot_behaviour(self, location, mro_slots): def test_de_json(self, bot): json_dict = { - "latitude": TestLocation.latitude, - "longitude": TestLocation.longitude, - "horizontal_accuracy": TestLocation.horizontal_accuracy, - "live_period": TestLocation.live_period, - "heading": TestLocation.heading, - "proximity_alert_radius": TestLocation.proximity_alert_radius, + "latitude": Space.latitude, + "longitude": Space.longitude, + "horizontal_accuracy": Space.horizontal_accuracy, + "live_period": Space.live_period, + "heading": Space.heading, + "proximity_alert_radius": Space.proximity_alert_radius, } location = Location.de_json(json_dict, bot) assert location.api_kwargs == {} - assert location.latitude == self.latitude - assert location.longitude == self.longitude - assert location.horizontal_accuracy == self.horizontal_accuracy - assert location.live_period == self.live_period - assert location.heading == self.heading - assert location.proximity_alert_radius == self.proximity_alert_radius - - @pytest.mark.flaky(3, 1) - @pytest.mark.xfail - async def test_send_live_location(self, bot, chat_id): - message = await bot.send_location( - chat_id=chat_id, - latitude=52.223880, - longitude=5.166146, - live_period=80, - horizontal_accuracy=50, - heading=90, - proximity_alert_radius=1000, - protect_content=True, - ) - assert message.location - assert 52.223880 == pytest.approx(message.location.latitude, rel=1e-5) - assert 5.166146 == pytest.approx(message.location.longitude, rel=1e-5) - assert message.location.live_period == 80 - assert message.location.horizontal_accuracy == 50 - assert message.location.heading == 90 - assert message.location.proximity_alert_radius == 1000 - assert message.has_protected_content - - message2 = await bot.edit_message_live_location( - message.chat_id, - message.message_id, - latitude=52.223098, - longitude=5.164306, - horizontal_accuracy=30, - heading=10, - proximity_alert_radius=500, - ) - - assert 52.223098 == pytest.approx(message2.location.latitude, rel=1e-5) - assert 5.164306 == pytest.approx(message2.location.longitude, rel=1e-5) - assert message2.location.horizontal_accuracy == 30 - assert message2.location.heading == 10 - assert message2.location.proximity_alert_radius == 500 - - await bot.stop_message_live_location(message.chat_id, message.message_id) - with pytest.raises(BadRequest, match="Message can't be edited"): - await bot.edit_message_live_location( - message.chat_id, message.message_id, latitude=52.223880, longitude=5.164306 - ) + assert location.latitude == Space.latitude + assert location.longitude == Space.longitude + assert location.horizontal_accuracy == Space.horizontal_accuracy + assert location.live_period == Space.live_period + assert location.heading == Space.heading + assert location.proximity_alert_radius == Space.proximity_alert_radius # TODO: Needs improvement with in inline sent live location. async def test_edit_live_inline_message(self, monkeypatch, bot, location): @@ -150,7 +108,57 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.setattr(bot.request, "post", make_assertion) assert await bot.send_location(location=location, chat_id=chat_id) - @pytest.mark.flaky(3, 1) + async def test_edit_live_location_with_location(self, monkeypatch, bot, location): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + lat = request_data.json_parameters["latitude"] == str(location.latitude) + lon = request_data.json_parameters["longitude"] == str(location.longitude) + return lat and lon + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.edit_message_live_location(None, None, location=location) + + async def test_send_location_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match="Either location or latitude and longitude"): + await bot.send_location(chat_id=chat_id) + + async def test_edit_location_without_required(self, bot): + with pytest.raises(ValueError, match="Either location or latitude and longitude"): + await bot.edit_message_live_location(chat_id=2, message_id=3) + + async def test_send_location_with_all_args(self, bot, location): + with pytest.raises(ValueError, match="Not both"): + await bot.send_location(chat_id=1, latitude=2.5, longitude=4.6, location=location) + + async def test_edit_location_with_all_args(self, bot, location): + with pytest.raises(ValueError, match="Not both"): + await bot.edit_message_live_location( + chat_id=1, message_id=7, latitude=2.5, longitude=4.6, location=location + ) + + def test_to_dict(self, location): + location_dict = location.to_dict() + + assert location_dict["latitude"] == location.latitude + assert location_dict["longitude"] == location.longitude + assert location_dict["horizontal_accuracy"] == location.horizontal_accuracy + assert location_dict["live_period"] == location.live_period + assert location["heading"] == location.heading + assert location["proximity_alert_radius"] == location.proximity_alert_radius + + def test_equality(self): + a = Location(Space.longitude, Space.latitude) + b = Location(Space.longitude, Space.latitude) + d = Location(0, Space.latitude) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != d + assert hash(a) != hash(d) + + +class TestLocationReq: @pytest.mark.parametrize( "default_bot,custom", [ @@ -184,7 +192,6 @@ async def test_send_location_default_allow_sending_without_reply( chat_id, location=location, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_location_default_protect_content(self, chat_id, default_bot, location): protected = await default_bot.send_location(chat_id, location=location) @@ -194,51 +201,45 @@ async def test_send_location_default_protect_content(self, chat_id, default_bot, ) assert not unprotected.has_protected_content - async def test_edit_live_location_with_location(self, monkeypatch, bot, location): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - lat = request_data.json_parameters["latitude"] == str(location.latitude) - lon = request_data.json_parameters["longitude"] == str(location.longitude) - return lat and lon - - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.edit_message_live_location(None, None, location=location) - - async def test_send_location_without_required(self, bot, chat_id): - with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.send_location(chat_id=chat_id) + @pytest.mark.xfail + async def test_send_live_location(self, bot, chat_id): + message = await bot.send_location( + chat_id=chat_id, + latitude=52.223880, + longitude=5.166146, + live_period=80, + horizontal_accuracy=50, + heading=90, + proximity_alert_radius=1000, + protect_content=True, + ) + assert message.location + assert 52.223880 == pytest.approx(message.location.latitude, rel=1e-5) + assert 5.166146 == pytest.approx(message.location.longitude, rel=1e-5) + assert message.location.live_period == 80 + assert message.location.horizontal_accuracy == 50 + assert message.location.heading == 90 + assert message.location.proximity_alert_radius == 1000 + assert message.has_protected_content - async def test_edit_location_without_required(self, bot): - with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.edit_message_live_location(chat_id=2, message_id=3) + message2 = await bot.edit_message_live_location( + message.chat_id, + message.message_id, + latitude=52.223098, + longitude=5.164306, + horizontal_accuracy=30, + heading=10, + proximity_alert_radius=500, + ) - async def test_send_location_with_all_args(self, bot, location): - with pytest.raises(ValueError, match="Not both"): - await bot.send_location(chat_id=1, latitude=2.5, longitude=4.6, location=location) + assert 52.223098 == pytest.approx(message2.location.latitude, rel=1e-5) + assert 5.164306 == pytest.approx(message2.location.longitude, rel=1e-5) + assert message2.location.horizontal_accuracy == 30 + assert message2.location.heading == 10 + assert message2.location.proximity_alert_radius == 500 - async def test_edit_location_with_all_args(self, bot, location): - with pytest.raises(ValueError, match="Not both"): + await bot.stop_message_live_location(message.chat_id, message.message_id) + with pytest.raises(BadRequest, match="Message can't be edited"): await bot.edit_message_live_location( - chat_id=1, message_id=7, latitude=2.5, longitude=4.6, location=location + message.chat_id, message.message_id, latitude=52.223880, longitude=5.164306 ) - - def test_to_dict(self, location): - location_dict = location.to_dict() - - assert location_dict["latitude"] == location.latitude - assert location_dict["longitude"] == location.longitude - assert location_dict["horizontal_accuracy"] == location.horizontal_accuracy - assert location_dict["live_period"] == location.live_period - assert location["heading"] == location.heading - assert location["proximity_alert_radius"] == location.proximity_alert_radius - - def test_equality(self): - a = Location(self.longitude, self.latitude) - b = Location(self.longitude, self.latitude) - d = Location(0, self.latitude) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != d - assert hash(a) != hash(d) diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index 42550900025..4c796d9f949 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -21,22 +21,24 @@ from telegram import LoginUrl -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def login_url(): return LoginUrl( - url=TestLoginUrl.url, - forward_text=TestLoginUrl.forward_text, - bot_username=TestLoginUrl.bot_username, - request_write_access=TestLoginUrl.request_write_access, + url=Space.url, + forward_text=Space.forward_text, + bot_username=Space.bot_username, + request_write_access=Space.request_write_access, ) -class TestLoginUrl: +class Space: url = "http://www.google.com" forward_text = "Send me forward!" bot_username = "botname" request_write_access = True + +class TestLoginUrlNoReq: def test_slot_behaviour(self, login_url, mro_slots): for attr in login_url.__slots__: assert getattr(login_url, attr, "err") != "err", f"got extra slot '{attr}'" @@ -46,16 +48,18 @@ def test_to_dict(self, login_url): login_url_dict = login_url.to_dict() assert isinstance(login_url_dict, dict) - assert login_url_dict["url"] == self.url - assert login_url_dict["forward_text"] == self.forward_text - assert login_url_dict["bot_username"] == self.bot_username - assert login_url_dict["request_write_access"] == self.request_write_access + assert login_url_dict["url"] == Space.url + assert login_url_dict["forward_text"] == Space.forward_text + assert login_url_dict["bot_username"] == Space.bot_username + assert login_url_dict["request_write_access"] == Space.request_write_access def test_equality(self): - a = LoginUrl(self.url, self.forward_text, self.bot_username, self.request_write_access) - b = LoginUrl(self.url, self.forward_text, self.bot_username, self.request_write_access) - c = LoginUrl(self.url) - d = LoginUrl("text.com", self.forward_text, self.bot_username, self.request_write_access) + a = LoginUrl(Space.url, Space.forward_text, Space.bot_username, Space.request_write_access) + b = LoginUrl(Space.url, Space.forward_text, Space.bot_username, Space.request_write_access) + c = LoginUrl(Space.url) + d = LoginUrl( + "text.com", Space.forward_text, Space.bot_username, Space.request_write_access + ) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_menubutton.py b/tests/test_menubutton.py index ec95ed325b1..8b0fb037aa2 100644 --- a/tests/test_menubutton.py +++ b/tests/test_menubutton.py @@ -31,7 +31,7 @@ @pytest.fixture( - scope="class", + scope="module", params=[ MenuButton.DEFAULT, MenuButton.WEB_APP, @@ -43,7 +43,7 @@ def scope_type(request): @pytest.fixture( - scope="class", + scope="module", params=[ MenuButtonDefault, MenuButtonCommands, @@ -60,7 +60,7 @@ def scope_class(request): @pytest.fixture( - scope="class", + scope="module", params=[ (MenuButtonDefault, MenuButton.DEFAULT), (MenuButtonCommands, MenuButton.COMMANDS), @@ -76,24 +76,26 @@ def scope_class_and_type(request): return request.param -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def menu_button(scope_class_and_type): # We use de_json here so that we don't have to worry about which class gets which arguments return scope_class_and_type[0].de_json( dict( type=scope_class_and_type[1], - text=TestMenuButton.text, - web_app=TestMenuButton.web_app.to_dict(), + text=Space.text, + web_app=Space.web_app.to_dict(), ), bot=None, ) -# All the scope types are very similar, so we test everything via parametrization -class TestMenuButton: +class Space: text = "button_text" web_app = WebAppInfo(url="https://python-telegram-bot.org/web_app") + +# All the scope types are very similar, so we test everything via parametrization +class TestMenuButtonNoReq: def test_slot_behaviour(self, menu_button, mro_slots): for attr in menu_button.__slots__: assert getattr(menu_button, attr, "err") != "err", f"got extra slot '{attr}'" @@ -103,7 +105,7 @@ def test_de_json(self, bot, scope_class_and_type): cls = scope_class_and_type[0] type_ = scope_class_and_type[1] - json_dict = {"type": type_, "text": self.text, "web_app": self.web_app.to_dict()} + json_dict = {"type": type_, "text": Space.text, "web_app": Space.web_app.to_dict()} menu_button = MenuButton.de_json(json_dict, bot) assert set(menu_button.api_kwargs.keys()) == {"text", "web_app"} - set(cls.__slots__) @@ -111,17 +113,17 @@ def test_de_json(self, bot, scope_class_and_type): assert type(menu_button) is cls assert menu_button.type == type_ if "web_app" in cls.__slots__: - assert menu_button.web_app == self.web_app + assert menu_button.web_app == Space.web_app if "text" in cls.__slots__: - assert menu_button.text == self.text + assert menu_button.text == Space.text assert cls.de_json(None, bot) is None assert MenuButton.de_json({}, bot) is None def test_de_json_invalid_type(self, bot): - json_dict = {"type": "invalid", "text": self.text, "web_app": self.web_app.to_dict()} + json_dict = {"type": "invalid", "text": Space.text, "web_app": Space.web_app.to_dict()} menu_button = MenuButton.de_json(json_dict, bot) - assert menu_button.api_kwargs == {"text": self.text, "web_app": self.web_app.to_dict()} + assert menu_button.api_kwargs == {"text": Space.text, "web_app": Space.web_app.to_dict()} assert type(menu_button) is MenuButton assert menu_button.type == "invalid" @@ -129,7 +131,7 @@ def test_de_json_invalid_type(self, bot): def test_de_json_subclass(self, scope_class, bot): """This makes sure that e.g. MenuButtonDefault(data) never returns a MenuButtonChat instance.""" - json_dict = {"type": "invalid", "text": self.text, "web_app": self.web_app.to_dict()} + json_dict = {"type": "invalid", "text": Space.text, "web_app": Space.web_app.to_dict()} assert type(scope_class.de_json(json_dict, bot)) is scope_class def test_to_dict(self, menu_button): diff --git a/tests/test_message.py b/tests/test_message.py index 7891d1e43ea..fd474ea1bde 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -64,13 +64,13 @@ from tests.test_passport import RAW_PASSPORT_DATA -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def message(bot): message = Message( - message_id=TestMessage.id_, - date=TestMessage.date, - chat=copy(TestMessage.chat), - from_user=copy(TestMessage.from_user), + message_id=Space.id_, + date=Space.date, + chat=copy(Space.chat), + from_user=copy(Space.from_user), ) message.set_bot(bot) message._unfreeze() @@ -265,17 +265,17 @@ def message(bot): ) def message_params(bot, request): message = Message( - message_id=TestMessage.id_, - from_user=TestMessage.from_user, - date=TestMessage.date, - chat=TestMessage.chat, + message_id=Space.id_, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, **request.param, ) message.set_bot(bot) return message -class TestMessage: +class Space: id_ = 1 from_user = User(2, "testuser", False) date = datetime.utcnow() @@ -341,6 +341,8 @@ class TestMessage: caption_entities=[MessageEntity(**e) for e in test_entities_v2], ) + +class TestMessageNoReq: def test_all_possibilities_de_json_and_to_dict(self, bot, message_params): new = Message.de_json(message_params.to_dict(), bot) assert new.api_kwargs == {} @@ -365,16 +367,16 @@ async def test_parse_entity(self): entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, text=text, entities=[entity], ) assert message.parse_entity(entity) == "http://google.com" with pytest.raises(RuntimeError, match="Message has no"): - Message(message_id=1, date=self.date, chat=self.chat).parse_entity(entity) + Message(message_id=1, date=Space.date, chat=Space.chat).parse_entity(entity) async def test_parse_caption_entity(self): caption = ( @@ -384,16 +386,16 @@ async def test_parse_caption_entity(self): entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, caption=caption, caption_entities=[entity], ) assert message.parse_caption_entity(entity) == "http://google.com" with pytest.raises(RuntimeError, match="Message has no"): - Message(message_id=1, date=self.date, chat=self.chat).parse_entity(entity) + Message(message_id=1, date=Space.date, chat=Space.chat).parse_entity(entity) async def test_parse_entities(self): text = ( @@ -404,9 +406,9 @@ async def test_parse_entities(self): entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, text=text, entities=[entity_2, entity], ) @@ -422,9 +424,9 @@ async def test_parse_caption_entities(self): entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, caption=text, caption_entities=[entity_2, entity], ) @@ -445,7 +447,7 @@ def test_text_html_simple(self): '
Python pre
. ' 'Spoiled.' ) - text_html = self.test_message_v2.text_html + text_html = Space.test_message_v2.text_html assert text_html == test_html_string def test_text_html_empty(self, message): @@ -464,7 +466,7 @@ def test_text_html_urled(self): '
Python pre
. ' 'Spoiled.' ) - text_html = self.test_message_v2.text_html_urled + text_html = Space.test_message_v2.text_html_urled assert text_html == test_html_string def test_text_markdown_simple(self): @@ -474,7 +476,7 @@ def test_text_markdown_simple(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " r"http://google.com/ab\_" ) - text_markdown = self.test_message.text_markdown + text_markdown = Space.test_message.text_markdown assert text_markdown == test_md_string def test_text_markdown_v2_simple(self): @@ -485,7 +487,7 @@ def test_text_markdown_v2_simple(self): r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. " "```python\nPython pre```\\. ||Spoiled||\\." ) - text_markdown = self.test_message_v2.text_markdown_v2 + text_markdown = Space.test_message_v2.text_markdown_v2 assert text_markdown == test_md_string def test_text_markdown_new_in_v2(self, message): @@ -524,7 +526,7 @@ def test_text_markdown_urled(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " "[http://google.com/ab_](http://google.com/ab_)" ) - text_markdown = self.test_message.text_markdown_urled + text_markdown = Space.test_message.text_markdown_urled assert text_markdown == test_md_string def test_text_markdown_v2_urled(self): @@ -535,7 +537,7 @@ def test_text_markdown_v2_urled(self): r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ " "nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\." ) - text_markdown = self.test_message_v2.text_markdown_v2_urled + text_markdown = Space.test_message_v2.text_markdown_v2_urled assert text_markdown == test_md_string def test_text_html_emoji(self): @@ -544,9 +546,9 @@ def test_text_html_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, text=text, entities=[bold_entity], ) @@ -557,7 +559,7 @@ def test_text_markdown_emoji(self): 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] + 1, Space.from_user, Space.date, Space.chat, text=text, entities=[bold_entity] ) assert expected == message.text_markdown @@ -583,9 +585,9 @@ def test_text_custom_emoji(self, type_): ) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, text=text, entities=[emoji_entity], ) @@ -602,7 +604,7 @@ def test_caption_html_simple(self): '
Python pre
. ' 'Spoiled.' ) - caption_html = self.test_message_v2.caption_html + caption_html = Space.test_message_v2.caption_html assert caption_html == test_html_string def test_caption_html_empty(self, message): @@ -621,7 +623,7 @@ def test_caption_html_urled(self): '
Python pre
. ' 'Spoiled.' ) - caption_html = self.test_message_v2.caption_html_urled + caption_html = Space.test_message_v2.caption_html_urled assert caption_html == test_html_string def test_caption_markdown_simple(self): @@ -631,7 +633,7 @@ def test_caption_markdown_simple(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " r"http://google.com/ab\_" ) - caption_markdown = self.test_message.caption_markdown + caption_markdown = Space.test_message.caption_markdown assert caption_markdown == test_md_string def test_caption_markdown_v2_simple(self): @@ -642,7 +644,7 @@ def test_caption_markdown_v2_simple(self): r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. " "```python\nPython pre```\\. ||Spoiled||\\." ) - caption_markdown = self.test_message_v2.caption_markdown_v2 + caption_markdown = Space.test_message_v2.caption_markdown_v2 assert caption_markdown == test_md_string def test_caption_markdown_empty(self, message): @@ -658,7 +660,7 @@ def test_caption_markdown_urled(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " "[http://google.com/ab_](http://google.com/ab_)" ) - caption_markdown = self.test_message.caption_markdown_urled + caption_markdown = Space.test_message.caption_markdown_urled assert caption_markdown == test_md_string def test_caption_markdown_v2_urled(self): @@ -669,7 +671,7 @@ def test_caption_markdown_v2_urled(self): r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ " "nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\." ) - caption_markdown = self.test_message_v2.caption_markdown_v2_urled + caption_markdown = Space.test_message_v2.caption_markdown_v2_urled assert caption_markdown == test_md_string def test_caption_html_emoji(self): @@ -678,9 +680,9 @@ def test_caption_html_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, caption=caption, caption_entities=[bold_entity], ) @@ -692,9 +694,9 @@ def test_caption_markdown_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, caption=caption, caption_entities=[bold_entity], ) @@ -722,9 +724,9 @@ def test_caption_custom_emoji(self, type_): ) message = Message( 1, - from_user=self.from_user, - date=self.date, - chat=self.chat, + from_user=Space.from_user, + date=Space.date, + chat=Space.chat, caption=caption, caption_entities=[emoji_entity], ) @@ -735,7 +737,7 @@ async def test_parse_entities_url_emoji(self): text = "some url" link_entity = MessageEntity(type=MessageEntity.URL, offset=0, length=8, url=url) message = Message( - 1, self.from_user, self.date, self.chat, text=text, entities=[link_entity] + 1, Space.from_user, Space.date, Space.chat, text=text, entities=[link_entity] ) assert message.parse_entities() == {link_entity: text} assert next(iter(message.parse_entities())).url == url @@ -855,14 +857,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_markdown = self.test_message.text_markdown + text_markdown = Space.test_message.text_markdown assert text_markdown == test_md_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_markdown(self.test_message.text_markdown) - assert await message.reply_markdown(self.test_message.text_markdown, quote=True) + assert await message.reply_markdown(Space.test_message.text_markdown) + assert await message.reply_markdown(Space.test_message.text_markdown, quote=True) assert await message.reply_markdown( - self.test_message.text_markdown, reply_to_message_id=message.message_id, quote=True + Space.test_message.text_markdown, reply_to_message_id=message.message_id, quote=True ) async def test_reply_markdown_v2(self, monkeypatch, message): @@ -890,14 +892,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_markdown = self.test_message_v2.text_markdown_v2 + text_markdown = Space.test_message_v2.text_markdown_v2 assert text_markdown == test_md_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_markdown_v2(self.test_message_v2.text_markdown_v2) - assert await message.reply_markdown_v2(self.test_message_v2.text_markdown_v2, quote=True) + assert await message.reply_markdown_v2(Space.test_message_v2.text_markdown_v2) + assert await message.reply_markdown_v2(Space.test_message_v2.text_markdown_v2, quote=True) assert await message.reply_markdown_v2( - self.test_message_v2.text_markdown_v2, + Space.test_message_v2.text_markdown_v2, reply_to_message_id=message.message_id, quote=True, ) @@ -930,14 +932,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_html = self.test_message_v2.text_html + text_html = Space.test_message_v2.text_html assert text_html == test_html_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_html(self.test_message_v2.text_html) - assert await message.reply_html(self.test_message_v2.text_html, quote=True) + assert await message.reply_html(Space.test_message_v2.text_html) + assert await message.reply_html(Space.test_message_v2.text_html, quote=True) assert await message.reply_html( - self.test_message_v2.text_html, reply_to_message_id=message.message_id, quote=True + Space.test_message_v2.text_html, reply_to_message_id=message.message_id, quote=True ) async def test_reply_media_group(self, monkeypatch, message): @@ -1825,18 +1827,18 @@ def test_equality(self): id_ = 1 a = Message( id_, - self.date, - self.chat, - from_user=self.from_user, + Space.date, + Space.chat, + from_user=Space.from_user, ) b = Message( id_, - self.date, - self.chat, - from_user=self.from_user, + Space.date, + Space.chat, + from_user=Space.from_user, ) - c = Message(id_, self.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) - d = Message(0, self.date, self.chat, from_user=self.from_user) + c = Message(id_, Space.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) + d = Message(0, Space.date, Space.chat, from_user=Space.from_user) e = Update(id_) assert a == b diff --git a/tests/test_messageautodeletetimerchanged.py b/tests/test_messageautodeletetimerchanged.py index ee8e6c4c06b..5d2eaa05190 100644 --- a/tests/test_messageautodeletetimerchanged.py +++ b/tests/test_messageautodeletetimerchanged.py @@ -19,7 +19,7 @@ from telegram import MessageAutoDeleteTimerChanged, VideoChatEnded -class TestMessageAutoDeleteTimerChanged: +class TestMessageAutoDeleteTimerChangedNoReq: message_auto_delete_time = 100 def test_slot_behaviour(self, mro_slots): diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 116d5263788..ce178c59463 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -22,7 +22,7 @@ from telegram.constants import MessageEntityType -@pytest.fixture(scope="class", params=MessageEntity.ALL_TYPES) +@pytest.fixture(scope="module", params=MessageEntity.ALL_TYPES) def message_entity(request): type_ = request.param url = None @@ -37,12 +37,14 @@ def message_entity(request): return MessageEntity(type_, 1, 3, url=url, user=user, language=language) -class TestMessageEntity: +class Space: type_ = "url" offset = 1 length = 2 url = "url" + +class TestMessageEntityNoReq: def test_slot_behaviour(self, message_entity, mro_slots): inst = message_entity for attr in inst.__slots__: @@ -50,13 +52,13 @@ def test_slot_behaviour(self, message_entity, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json(self, bot): - json_dict = {"type": self.type_, "offset": self.offset, "length": self.length} + json_dict = {"type": Space.type_, "offset": Space.offset, "length": Space.length} entity = MessageEntity.de_json(json_dict, bot) assert entity.api_kwargs == {} - assert entity.type == self.type_ - assert entity.offset == self.offset - assert entity.length == self.length + assert entity.type == Space.type_ + assert entity.offset == Space.offset + assert entity.length == Space.length def test_to_dict(self, message_entity): entity_dict = message_entity.to_dict() diff --git a/tests/test_messageid.py b/tests/test_messageid.py index 3ae10efe9eb..90c3a8e782f 100644 --- a/tests/test_messageid.py +++ b/tests/test_messageid.py @@ -20,12 +20,12 @@ from telegram import MessageId, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def message_id(): - return MessageId(message_id=TestMessageId.m_id) + return MessageId(message_id=TestMessageIdNoReq.m_id) -class TestMessageId: +class TestMessageIdNoReq: m_id = 1234 def test_slot_behaviour(self, message_id, mro_slots): diff --git a/tests/test_no_passport.py b/tests/test_no_passport.py index 071e29c5306..366995fe856 100644 --- a/tests/test_no_passport.py +++ b/tests/test_no_passport.py @@ -40,7 +40,7 @@ @pytest.mark.skipif( TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed" ) -class TestNoPassport: +class TestNoPassportNoReq: def test_bot_init(self, bot_info, monkeypatch): with pytest.raises(RuntimeError, match="passport"): bot.Bot(bot_info["token"], private_key=1, private_key_password=2) diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index ab402d468e5..a569b4e1884 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -21,22 +21,24 @@ from telegram import OrderInfo, ShippingAddress -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def order_info(): return OrderInfo( - TestOrderInfo.name, - TestOrderInfo.phone_number, - TestOrderInfo.email, - TestOrderInfo.shipping_address, + Space.name, + Space.phone_number, + Space.email, + Space.shipping_address, ) -class TestOrderInfo: +class Space: name = "name" phone_number = "phone_number" email = "email" shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") + +class TestOrderInfoNoReq: def test_slot_behaviour(self, order_info, mro_slots): for attr in order_info.__slots__: assert getattr(order_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -44,18 +46,18 @@ def test_slot_behaviour(self, order_info, mro_slots): 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(), + "name": Space.name, + "phone_number": Space.phone_number, + "email": Space.email, + "shipping_address": Space.shipping_address.to_dict(), } order_info = OrderInfo.de_json(json_dict, bot) assert order_info.api_kwargs == {} - 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 + assert order_info.name == Space.name + assert order_info.phone_number == Space.phone_number + assert order_info.email == Space.email + assert order_info.shipping_address == Space.shipping_address def test_to_dict(self, order_info): order_info_dict = order_info.to_dict() diff --git a/tests/test_passport.py b/tests/test_passport.py index 77f9a0c91ea..0d229e3aaba 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -128,7 +128,7 @@ } -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def all_passport_data(): return [ { @@ -214,12 +214,12 @@ def all_passport_data(): ] -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def passport_data(bot): return PassportData.de_json(RAW_PASSPORT_DATA, bot=bot) -class TestPassport: +class Space: driver_license_selfie_file_id = "DgADBAADEQQAAkopgFNr6oi-wISRtAI" driver_license_selfie_file_unique_id = "d4e390cca57b4da5a65322b304762a12" driver_license_front_side_file_id = "DgADBAADxwMAApnQgVPK2-ckL2eXVAI" @@ -241,6 +241,8 @@ class TestPassport: driver_license_selfie_credentials_file_hash = "Cila/qLXSBH7DpZFbb5bRZIRxeFW2uv/ulL0u0JNsYI=" driver_license_selfie_credentials_secret = "tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E=" + +class TestPassportNoReq: def test_slot_behaviour(self, passport_data, mro_slots): inst = passport_data for attr in inst.__slots__: @@ -259,58 +261,58 @@ def test_expected_encrypted_values(self, passport_data): assert driver_license.type == "driver_license" assert driver_license.data == RAW_PASSPORT_DATA["data"][1]["data"] assert isinstance(driver_license.selfie, PassportFile) - assert driver_license.selfie.file_id == self.driver_license_selfie_file_id - assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id + assert driver_license.selfie.file_id == Space.driver_license_selfie_file_id + assert driver_license.selfie.file_unique_id == Space.driver_license_selfie_file_unique_id assert isinstance(driver_license.front_side, PassportFile) - assert driver_license.front_side.file_id == self.driver_license_front_side_file_id + assert driver_license.front_side.file_id == Space.driver_license_front_side_file_id assert ( driver_license.front_side.file_unique_id - == self.driver_license_front_side_file_unique_id + == Space.driver_license_front_side_file_unique_id ) assert isinstance(driver_license.reverse_side, PassportFile) - assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id + assert driver_license.reverse_side.file_id == Space.driver_license_reverse_side_file_id assert ( driver_license.reverse_side.file_unique_id - == self.driver_license_reverse_side_file_unique_id + == Space.driver_license_reverse_side_file_unique_id ) assert isinstance(driver_license.translation[0], PassportFile) - assert driver_license.translation[0].file_id == self.driver_license_translation_1_file_id + assert driver_license.translation[0].file_id == Space.driver_license_translation_1_file_id assert ( driver_license.translation[0].file_unique_id - == self.driver_license_translation_1_file_unique_id + == Space.driver_license_translation_1_file_unique_id ) assert isinstance(driver_license.translation[1], PassportFile) - assert driver_license.translation[1].file_id == self.driver_license_translation_2_file_id + assert driver_license.translation[1].file_id == Space.driver_license_translation_2_file_id assert ( driver_license.translation[1].file_unique_id - == self.driver_license_translation_2_file_unique_id + == Space.driver_license_translation_2_file_unique_id ) assert utility_bill.type == "utility_bill" assert isinstance(utility_bill.files[0], PassportFile) - assert utility_bill.files[0].file_id == self.utility_bill_1_file_id - assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id + assert utility_bill.files[0].file_id == Space.utility_bill_1_file_id + assert utility_bill.files[0].file_unique_id == Space.utility_bill_1_file_unique_id assert isinstance(utility_bill.files[1], PassportFile) - assert utility_bill.files[1].file_id == self.utility_bill_2_file_id - assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id + assert utility_bill.files[1].file_id == Space.utility_bill_2_file_id + assert utility_bill.files[1].file_unique_id == Space.utility_bill_2_file_unique_id assert isinstance(utility_bill.translation[0], PassportFile) - assert utility_bill.translation[0].file_id == self.utility_bill_translation_1_file_id + assert utility_bill.translation[0].file_id == Space.utility_bill_translation_1_file_id assert ( utility_bill.translation[0].file_unique_id - == self.utility_bill_translation_1_file_unique_id + == Space.utility_bill_translation_1_file_unique_id ) assert isinstance(utility_bill.translation[1], PassportFile) - assert utility_bill.translation[1].file_id == self.utility_bill_translation_2_file_id + assert utility_bill.translation[1].file_id == Space.utility_bill_translation_2_file_id assert ( utility_bill.translation[1].file_unique_id - == self.utility_bill_translation_2_file_unique_id + == Space.utility_bill_translation_2_file_unique_id ) assert address.type == "address" @@ -348,21 +350,21 @@ def test_expected_decrypted_values(self, passport_data): "document_no": "DOCUMENT_NO", } assert isinstance(driver_license.selfie, PassportFile) - assert driver_license.selfie.file_id == self.driver_license_selfie_file_id - assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id + assert driver_license.selfie.file_id == Space.driver_license_selfie_file_id + assert driver_license.selfie.file_unique_id == Space.driver_license_selfie_file_unique_id assert isinstance(driver_license.front_side, PassportFile) - assert driver_license.front_side.file_id == self.driver_license_front_side_file_id + assert driver_license.front_side.file_id == Space.driver_license_front_side_file_id assert ( driver_license.front_side.file_unique_id - == self.driver_license_front_side_file_unique_id + == Space.driver_license_front_side_file_unique_id ) assert isinstance(driver_license.reverse_side, PassportFile) - assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id + assert driver_license.reverse_side.file_id == Space.driver_license_reverse_side_file_id assert ( driver_license.reverse_side.file_unique_id - == self.driver_license_reverse_side_file_unique_id + == Space.driver_license_reverse_side_file_unique_id ) assert address.type == "address" @@ -377,12 +379,12 @@ def test_expected_decrypted_values(self, passport_data): assert utility_bill.type == "utility_bill" assert isinstance(utility_bill.files[0], PassportFile) - assert utility_bill.files[0].file_id == self.utility_bill_1_file_id - assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id + assert utility_bill.files[0].file_id == Space.utility_bill_1_file_id + assert utility_bill.files[0].file_unique_id == Space.utility_bill_1_file_unique_id assert isinstance(utility_bill.files[1], PassportFile) - assert utility_bill.files[1].file_id == self.utility_bill_2_file_id - assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id + assert utility_bill.files[1].file_id == Space.utility_bill_2_file_id + assert utility_bill.files[1].file_unique_id == Space.utility_bill_2_file_unique_id assert email.type == "email" assert email.email == "fb3e3i47zt@dispostable.com" @@ -468,8 +470,8 @@ async def get_file(*_, **kwargs): file = await selfie.get_file() assert file.file_id == selfie.file_id assert file.file_unique_id == selfie.file_unique_id - assert file._credentials.file_hash == self.driver_license_selfie_credentials_file_hash - assert file._credentials.secret == self.driver_license_selfie_credentials_secret + assert file._credentials.file_hash == Space.driver_license_selfie_credentials_file_hash + assert file._credentials.secret == Space.driver_license_selfie_credentials_secret async def test_mocked_set_passport_data_errors(self, monkeypatch, bot, chat_id, passport_data): async def make_assertion(url, request_data: RequestData, *args, **kwargs): diff --git a/tests/test_passportelementerrordatafield.py b/tests/test_passportelementerrordatafield.py index ca2d3b2186e..d76dd5ef134 100644 --- a/tests/test_passportelementerrordatafield.py +++ b/tests/test_passportelementerrordatafield.py @@ -21,23 +21,25 @@ from telegram import PassportElementErrorDataField, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_data_field(): return PassportElementErrorDataField( - TestPassportElementErrorDataField.type_, - TestPassportElementErrorDataField.field_name, - TestPassportElementErrorDataField.data_hash, - TestPassportElementErrorDataField.message, + Space.type_, + Space.field_name, + Space.data_hash, + Space.message, ) -class TestPassportElementErrorDataField: +class Space: source = "data" type_ = "test_type" field_name = "test_field" data_hash = "data_hash" message = "Error message" + +class TestPassportElementErrorDataFieldNoReq: def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): inst = passport_element_error_data_field for attr in inst.__slots__: @@ -45,11 +47,11 @@ def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_data_field): - assert passport_element_error_data_field.source == self.source - assert passport_element_error_data_field.type == self.type_ - assert passport_element_error_data_field.field_name == self.field_name - assert passport_element_error_data_field.data_hash == self.data_hash - assert passport_element_error_data_field.message == self.message + assert passport_element_error_data_field.source == Space.source + assert passport_element_error_data_field.type == Space.type_ + assert passport_element_error_data_field.field_name == Space.field_name + assert passport_element_error_data_field.data_hash == Space.data_hash + assert passport_element_error_data_field.message == Space.message def test_to_dict(self, passport_element_error_data_field): passport_element_error_data_field_dict = passport_element_error_data_field.to_dict() @@ -78,16 +80,16 @@ def test_to_dict(self, passport_element_error_data_field): def test_equality(self): a = PassportElementErrorDataField( - self.type_, self.field_name, self.data_hash, self.message + Space.type_, Space.field_name, Space.data_hash, Space.message ) b = PassportElementErrorDataField( - self.type_, self.field_name, self.data_hash, self.message + Space.type_, Space.field_name, Space.data_hash, Space.message ) - c = PassportElementErrorDataField(self.type_, "", "", "") - d = PassportElementErrorDataField("", self.field_name, "", "") - e = PassportElementErrorDataField("", "", self.data_hash, "") - f = PassportElementErrorDataField("", "", "", self.message) - g = PassportElementErrorSelfie(self.type_, "", self.message) + c = PassportElementErrorDataField(Space.type_, "", "", "") + d = PassportElementErrorDataField("", Space.field_name, "", "") + e = PassportElementErrorDataField("", "", Space.data_hash, "") + f = PassportElementErrorDataField("", "", "", Space.message) + g = PassportElementErrorSelfie(Space.type_, "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfile.py b/tests/test_passportelementerrorfile.py index c7fc752e979..7d6d887e277 100644 --- a/tests/test_passportelementerrorfile.py +++ b/tests/test_passportelementerrorfile.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorFile, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_file(): - return PassportElementErrorFile( - TestPassportElementErrorFile.type_, - TestPassportElementErrorFile.file_hash, - TestPassportElementErrorFile.message, - ) + return PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) -class TestPassportElementErrorFile: +class Space: source = "file" type_ = "test_type" file_hash = "file_hash" message = "Error message" + +class TestPassportElementErrorFileNoReq: def test_slot_behaviour(self, passport_element_error_file, mro_slots): inst = passport_element_error_file for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_file, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_file): - assert passport_element_error_file.source == self.source - assert passport_element_error_file.type == self.type_ - assert passport_element_error_file.file_hash == self.file_hash - assert passport_element_error_file.message == self.message + assert passport_element_error_file.source == Space.source + assert passport_element_error_file.type == Space.type_ + assert passport_element_error_file.file_hash == Space.file_hash + assert passport_element_error_file.message == Space.message def test_to_dict(self, passport_element_error_file): passport_element_error_file_dict = passport_element_error_file.to_dict() @@ -60,12 +58,12 @@ def test_to_dict(self, passport_element_error_file): assert passport_element_error_file_dict["message"] == passport_element_error_file.message def test_equality(self): - a = PassportElementErrorFile(self.type_, self.file_hash, self.message) - b = PassportElementErrorFile(self.type_, self.file_hash, self.message) - c = PassportElementErrorFile(self.type_, "", "") - d = PassportElementErrorFile("", self.file_hash, "") - e = PassportElementErrorFile("", "", self.message) - f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) + a = PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) + b = PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) + c = PassportElementErrorFile(Space.type_, "", "") + d = PassportElementErrorFile("", Space.file_hash, "") + e = PassportElementErrorFile("", "", Space.message) + f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfiles.py b/tests/test_passportelementerrorfiles.py index ea7c6a9086f..74a9160c639 100644 --- a/tests/test_passportelementerrorfiles.py +++ b/tests/test_passportelementerrorfiles.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorFiles, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_files(): - return PassportElementErrorFiles( - TestPassportElementErrorFiles.type_, - TestPassportElementErrorFiles.file_hashes, - TestPassportElementErrorFiles.message, - ) + return PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) -class TestPassportElementErrorFiles: +class Space: source = "files" type_ = "test_type" file_hashes = ["hash1", "hash2"] message = "Error message" + +class TestPassportElementErrorFilesNoReq: def test_slot_behaviour(self, passport_element_error_files, mro_slots): inst = passport_element_error_files for attr in inst.__slots__: @@ -43,11 +41,11 @@ def test_slot_behaviour(self, passport_element_error_files, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_files): - assert passport_element_error_files.source == self.source - assert passport_element_error_files.type == self.type_ + assert passport_element_error_files.source == Space.source + assert passport_element_error_files.type == Space.type_ assert isinstance(passport_element_error_files.file_hashes, list) - assert passport_element_error_files.file_hashes == self.file_hashes - assert passport_element_error_files.message == self.message + assert passport_element_error_files.file_hashes == Space.file_hashes + assert passport_element_error_files.message == Space.message def test_to_dict(self, passport_element_error_files): passport_element_error_files_dict = passport_element_error_files.to_dict() @@ -62,12 +60,12 @@ def test_to_dict(self, passport_element_error_files): assert passport_element_error_files_dict["message"] == passport_element_error_files.message def test_equality(self): - a = PassportElementErrorFiles(self.type_, self.file_hashes, self.message) - b = PassportElementErrorFiles(self.type_, self.file_hashes, self.message) - c = PassportElementErrorFiles(self.type_, "", "") - d = PassportElementErrorFiles("", self.file_hashes, "") - e = PassportElementErrorFiles("", "", self.message) - f = PassportElementErrorSelfie(self.type_, "", self.message) + a = PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) + b = PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) + c = PassportElementErrorFiles(Space.type_, "", "") + d = PassportElementErrorFiles("", Space.file_hashes, "") + e = PassportElementErrorFiles("", "", Space.message) + f = PassportElementErrorSelfie(Space.type_, "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfrontside.py b/tests/test_passportelementerrorfrontside.py index b8389eac246..728ec8d5d7b 100644 --- a/tests/test_passportelementerrorfrontside.py +++ b/tests/test_passportelementerrorfrontside.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorFrontSide, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_front_side(): - return PassportElementErrorFrontSide( - TestPassportElementErrorFrontSide.type_, - TestPassportElementErrorFrontSide.file_hash, - TestPassportElementErrorFrontSide.message, - ) + return PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) -class TestPassportElementErrorFrontSide: +class Space: source = "front_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" + +class TestPassportElementErrorFrontSideNoReq: def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): inst = passport_element_error_front_side for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_front_side): - assert passport_element_error_front_side.source == self.source - assert passport_element_error_front_side.type == self.type_ - assert passport_element_error_front_side.file_hash == self.file_hash - assert passport_element_error_front_side.message == self.message + assert passport_element_error_front_side.source == Space.source + assert passport_element_error_front_side.type == Space.type_ + assert passport_element_error_front_side.file_hash == Space.file_hash + assert passport_element_error_front_side.message == Space.message def test_to_dict(self, passport_element_error_front_side): passport_element_error_front_side_dict = passport_element_error_front_side.to_dict() @@ -70,12 +68,12 @@ def test_to_dict(self, passport_element_error_front_side): ) def test_equality(self): - a = PassportElementErrorFrontSide(self.type_, self.file_hash, self.message) - b = PassportElementErrorFrontSide(self.type_, self.file_hash, self.message) - c = PassportElementErrorFrontSide(self.type_, "", "") - d = PassportElementErrorFrontSide("", self.file_hash, "") - e = PassportElementErrorFrontSide("", "", self.message) - f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) + a = PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) + b = PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) + c = PassportElementErrorFrontSide(Space.type_, "", "") + d = PassportElementErrorFrontSide("", Space.file_hash, "") + e = PassportElementErrorFrontSide("", "", Space.message) + f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorreverseside.py b/tests/test_passportelementerrorreverseside.py index 80cb3acab90..32cd0e01585 100644 --- a/tests/test_passportelementerrorreverseside.py +++ b/tests/test_passportelementerrorreverseside.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorReverseSide, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_reverse_side(): - return PassportElementErrorReverseSide( - TestPassportElementErrorReverseSide.type_, - TestPassportElementErrorReverseSide.file_hash, - TestPassportElementErrorReverseSide.message, - ) + return PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) -class TestPassportElementErrorReverseSide: +class Space: source = "reverse_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" + +class TestPassportElementErrorReverseSideNoReq: def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): inst = passport_element_error_reverse_side for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_reverse_side): - assert passport_element_error_reverse_side.source == self.source - assert passport_element_error_reverse_side.type == self.type_ - assert passport_element_error_reverse_side.file_hash == self.file_hash - assert passport_element_error_reverse_side.message == self.message + assert passport_element_error_reverse_side.source == Space.source + assert passport_element_error_reverse_side.type == Space.type_ + assert passport_element_error_reverse_side.file_hash == Space.file_hash + assert passport_element_error_reverse_side.message == Space.message def test_to_dict(self, passport_element_error_reverse_side): passport_element_error_reverse_side_dict = passport_element_error_reverse_side.to_dict() @@ -70,12 +68,12 @@ def test_to_dict(self, passport_element_error_reverse_side): ) def test_equality(self): - a = PassportElementErrorReverseSide(self.type_, self.file_hash, self.message) - b = PassportElementErrorReverseSide(self.type_, self.file_hash, self.message) - c = PassportElementErrorReverseSide(self.type_, "", "") - d = PassportElementErrorReverseSide("", self.file_hash, "") - e = PassportElementErrorReverseSide("", "", self.message) - f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) + a = PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) + b = PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) + c = PassportElementErrorReverseSide(Space.type_, "", "") + d = PassportElementErrorReverseSide("", Space.file_hash, "") + e = PassportElementErrorReverseSide("", "", Space.message) + f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorselfie.py b/tests/test_passportelementerrorselfie.py index 993dc34f178..d15d92c120d 100644 --- a/tests/test_passportelementerrorselfie.py +++ b/tests/test_passportelementerrorselfie.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorDataField, PassportElementErrorSelfie -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_selfie(): - return PassportElementErrorSelfie( - TestPassportElementErrorSelfie.type_, - TestPassportElementErrorSelfie.file_hash, - TestPassportElementErrorSelfie.message, - ) + return PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) -class TestPassportElementErrorSelfie: +class Space: source = "selfie" type_ = "test_type" file_hash = "file_hash" message = "Error message" + +class TestPassportElementErrorSelfieNoReq: def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): inst = passport_element_error_selfie for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_selfie): - assert passport_element_error_selfie.source == self.source - assert passport_element_error_selfie.type == self.type_ - assert passport_element_error_selfie.file_hash == self.file_hash - assert passport_element_error_selfie.message == self.message + assert passport_element_error_selfie.source == Space.source + assert passport_element_error_selfie.type == Space.type_ + assert passport_element_error_selfie.file_hash == Space.file_hash + assert passport_element_error_selfie.message == Space.message def test_to_dict(self, passport_element_error_selfie): passport_element_error_selfie_dict = passport_element_error_selfie.to_dict() @@ -63,12 +61,12 @@ def test_to_dict(self, passport_element_error_selfie): ) def test_equality(self): - a = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) - b = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) - c = PassportElementErrorSelfie(self.type_, "", "") - d = PassportElementErrorSelfie("", self.file_hash, "") - e = PassportElementErrorSelfie("", "", self.message) - f = PassportElementErrorDataField(self.type_, "", "", self.message) + a = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + b = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + c = PassportElementErrorSelfie(Space.type_, "", "") + d = PassportElementErrorSelfie("", Space.file_hash, "") + e = PassportElementErrorSelfie("", "", Space.message) + f = PassportElementErrorDataField(Space.type_, "", "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrortranslationfile.py b/tests/test_passportelementerrortranslationfile.py index 79e886e080b..c93855343ba 100644 --- a/tests/test_passportelementerrortranslationfile.py +++ b/tests/test_passportelementerrortranslationfile.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorDataField, PassportElementErrorTranslationFile -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_translation_file(): - return PassportElementErrorTranslationFile( - TestPassportElementErrorTranslationFile.type_, - TestPassportElementErrorTranslationFile.file_hash, - TestPassportElementErrorTranslationFile.message, - ) + return PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) -class TestPassportElementErrorTranslationFile: +class Space: source = "translation_file" type_ = "test_type" file_hash = "file_hash" message = "Error message" + +class TestPassportElementErrorTranslationFileNoReq: def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots): inst = passport_element_error_translation_file for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_translation_file): - assert passport_element_error_translation_file.source == self.source - assert passport_element_error_translation_file.type == self.type_ - assert passport_element_error_translation_file.file_hash == self.file_hash - assert passport_element_error_translation_file.message == self.message + assert passport_element_error_translation_file.source == Space.source + assert passport_element_error_translation_file.type == Space.type_ + assert passport_element_error_translation_file.file_hash == Space.file_hash + assert passport_element_error_translation_file.message == Space.message def test_to_dict(self, passport_element_error_translation_file): passport_element_error_translation_file_dict = ( @@ -72,12 +70,12 @@ def test_to_dict(self, passport_element_error_translation_file): ) def test_equality(self): - a = PassportElementErrorTranslationFile(self.type_, self.file_hash, self.message) - b = PassportElementErrorTranslationFile(self.type_, self.file_hash, self.message) - c = PassportElementErrorTranslationFile(self.type_, "", "") - d = PassportElementErrorTranslationFile("", self.file_hash, "") - e = PassportElementErrorTranslationFile("", "", self.message) - f = PassportElementErrorDataField(self.type_, "", "", self.message) + a = PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) + b = PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) + c = PassportElementErrorTranslationFile(Space.type_, "", "") + d = PassportElementErrorTranslationFile("", Space.file_hash, "") + e = PassportElementErrorTranslationFile("", "", Space.message) + f = PassportElementErrorDataField(Space.type_, "", "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrortranslationfiles.py b/tests/test_passportelementerrortranslationfiles.py index 69be1a927b2..a301857d303 100644 --- a/tests/test_passportelementerrortranslationfiles.py +++ b/tests/test_passportelementerrortranslationfiles.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorSelfie, PassportElementErrorTranslationFiles -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_translation_files(): - return PassportElementErrorTranslationFiles( - TestPassportElementErrorTranslationFiles.type_, - TestPassportElementErrorTranslationFiles.file_hashes, - TestPassportElementErrorTranslationFiles.message, - ) + return PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) -class TestPassportElementErrorTranslationFiles: +class Space: source = "translation_files" type_ = "test_type" file_hashes = ["hash1", "hash2"] message = "Error message" + +class TestPassportElementErrorTranslationFilesNoReq: def test_slot_behaviour(self, passport_element_error_translation_files, mro_slots): inst = passport_element_error_translation_files for attr in inst.__slots__: @@ -43,11 +41,11 @@ def test_slot_behaviour(self, passport_element_error_translation_files, mro_slot assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_translation_files): - assert passport_element_error_translation_files.source == self.source - assert passport_element_error_translation_files.type == self.type_ + assert passport_element_error_translation_files.source == Space.source + assert passport_element_error_translation_files.type == Space.type_ assert isinstance(passport_element_error_translation_files.file_hashes, list) - assert passport_element_error_translation_files.file_hashes == self.file_hashes - assert passport_element_error_translation_files.message == self.message + assert passport_element_error_translation_files.file_hashes == Space.file_hashes + assert passport_element_error_translation_files.message == Space.message def test_to_dict(self, passport_element_error_translation_files): passport_element_error_translation_files_dict = ( @@ -73,12 +71,12 @@ def test_to_dict(self, passport_element_error_translation_files): ) def test_equality(self): - a = PassportElementErrorTranslationFiles(self.type_, self.file_hashes, self.message) - b = PassportElementErrorTranslationFiles(self.type_, self.file_hashes, self.message) - c = PassportElementErrorTranslationFiles(self.type_, "", "") - d = PassportElementErrorTranslationFiles("", self.file_hashes, "") - e = PassportElementErrorTranslationFiles("", "", self.message) - f = PassportElementErrorSelfie(self.type_, "", self.message) + a = PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) + b = PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) + c = PassportElementErrorTranslationFiles(Space.type_, "", "") + d = PassportElementErrorTranslationFiles("", Space.file_hashes, "") + e = PassportElementErrorTranslationFiles("", "", Space.message) + f = PassportElementErrorSelfie(Space.type_, "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorunspecified.py b/tests/test_passportelementerrorunspecified.py index 5640bb3bd1c..53f27460dab 100644 --- a/tests/test_passportelementerrorunspecified.py +++ b/tests/test_passportelementerrorunspecified.py @@ -21,21 +21,19 @@ from telegram import PassportElementErrorDataField, PassportElementErrorUnspecified -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def passport_element_error_unspecified(): - return PassportElementErrorUnspecified( - TestPassportElementErrorUnspecified.type_, - TestPassportElementErrorUnspecified.element_hash, - TestPassportElementErrorUnspecified.message, - ) + return PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) -class TestPassportElementErrorUnspecified: +class Space: source = "unspecified" type_ = "test_type" element_hash = "element_hash" message = "Error message" + +class TestPassportElementErrorUnspecifiedNoReq: def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): inst = passport_element_error_unspecified for attr in inst.__slots__: @@ -43,10 +41,10 @@ def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_unspecified): - assert passport_element_error_unspecified.source == self.source - assert passport_element_error_unspecified.type == self.type_ - assert passport_element_error_unspecified.element_hash == self.element_hash - assert passport_element_error_unspecified.message == self.message + assert passport_element_error_unspecified.source == Space.source + assert passport_element_error_unspecified.type == Space.type_ + assert passport_element_error_unspecified.element_hash == Space.element_hash + assert passport_element_error_unspecified.message == Space.message def test_to_dict(self, passport_element_error_unspecified): passport_element_error_unspecified_dict = passport_element_error_unspecified.to_dict() @@ -70,12 +68,12 @@ def test_to_dict(self, passport_element_error_unspecified): ) def test_equality(self): - a = PassportElementErrorUnspecified(self.type_, self.element_hash, self.message) - b = PassportElementErrorUnspecified(self.type_, self.element_hash, self.message) - c = PassportElementErrorUnspecified(self.type_, "", "") - d = PassportElementErrorUnspecified("", self.element_hash, "") - e = PassportElementErrorUnspecified("", "", self.message) - f = PassportElementErrorDataField(self.type_, "", "", self.message) + a = PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) + b = PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) + c = PassportElementErrorUnspecified(Space.type_, "", "") + d = PassportElementErrorUnspecified("", Space.element_hash, "") + e = PassportElementErrorUnspecified("", "", Space.message) + f = PassportElementErrorDataField(Space.type_, "", "", Space.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index 4ec365a2266..c39a2ba7aa5 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -29,21 +29,23 @@ @pytest.fixture(scope="class") def passport_file(bot): pf = PassportFile( - file_id=TestPassportFile.file_id, - file_unique_id=TestPassportFile.file_unique_id, - file_size=TestPassportFile.file_size, - file_date=TestPassportFile.file_date, + file_id=Space.file_id, + file_unique_id=Space.file_unique_id, + file_size=Space.file_size, + file_date=Space.file_date, ) pf.set_bot(bot) return pf -class TestPassportFile: +class Space: file_id = "data" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_size = 50 file_date = 1532879128 + +class TestPassportFileNoReq: def test_slot_behaviour(self, passport_file, mro_slots): inst = passport_file for attr in inst.__slots__: @@ -51,10 +53,10 @@ def test_slot_behaviour(self, passport_file, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_file): - assert passport_file.file_id == self.file_id - assert passport_file.file_unique_id == self.file_unique_id - assert passport_file.file_size == self.file_size - assert passport_file.file_date == self.file_date + assert passport_file.file_id == Space.file_id + assert passport_file.file_unique_id == Space.file_unique_id + assert passport_file.file_size == Space.file_size + assert passport_file.file_date == Space.file_date def test_to_dict(self, passport_file): passport_file_dict = passport_file.to_dict() @@ -81,10 +83,10 @@ async def make_assertion(*_, **kwargs): assert (await passport_file.get_file()).file_id == "True" def test_equality(self): - a = PassportFile(self.file_id, self.file_unique_id, self.file_size, self.file_date) - b = PassportFile("", self.file_unique_id, self.file_size, self.file_date) - c = PassportFile(self.file_id, self.file_unique_id, "", "") - d = PassportFile("", "", self.file_size, self.file_date) + a = PassportFile(Space.file_id, Space.file_unique_id, Space.file_size, Space.file_date) + b = PassportFile("", Space.file_unique_id, Space.file_size, Space.file_date) + c = PassportFile(Space.file_id, Space.file_unique_id, "", "") + d = PassportFile("", "", Space.file_size, Space.file_date) e = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_photo.py b/tests/test_photo.py index 4d7baeeec48..6cbdd137acb 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -40,7 +40,7 @@ def photo_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def _photo(bot, chat_id): async def func(): with data_file("telegram.jpg").open("rb") as f: @@ -52,17 +52,17 @@ async def func(): ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def thumb(_photo): return _photo[0] -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def photo(_photo): return _photo[-1] -class TestPhoto: +class Space: width = 800 height = 800 caption = "PhotoTest - *Caption*" @@ -71,6 +71,8 @@ class TestPhoto: # so we accept three different sizes here. Shouldn't be too much file_size = [29176, 27662] + +class TestPhotoNoReq: def test_slot_behaviour(self, photo, mro_slots): for attr in photo.__slots__: assert getattr(photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -91,19 +93,128 @@ def test_creation(self, thumb, photo): assert thumb.file_unique_id != "" def test_expected_values(self, photo, thumb): - assert photo.width == self.width - assert photo.height == self.height - assert photo.file_size in self.file_size + assert photo.width == Space.width + assert photo.height == Space.height + assert photo.file_size in Space.file_size assert thumb.width == 90 assert thumb.height == 90 assert thumb.file_size == 1477 - @pytest.mark.flaky(3, 1) + async def test_send_photo_custom_filename(self, bot, chat_id, photo_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_photo(chat_id, photo_file, filename="custom_filename") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("photo") == expected + else: + test_flag = isinstance(data.get("photo"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_photo(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + + async def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["photo"] == photo.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_photo(photo=photo, chat_id=chat_id) + assert message + + def test_de_json(self, bot, photo): + json_dict = { + "file_id": photo.file_id, + "file_unique_id": photo.file_unique_id, + "width": Space.width, + "height": Space.height, + "file_size": Space.file_size, + } + json_photo = PhotoSize.de_json(json_dict, bot) + assert json_photo.api_kwargs == {} + + assert json_photo.file_id == photo.file_id + assert json_photo.file_unique_id == photo.file_unique_id + assert json_photo.width == Space.width + assert json_photo.height == Space.height + assert json_photo.file_size == Space.file_size + + def test_to_dict(self, photo): + photo_dict = photo.to_dict() + + assert isinstance(photo_dict, dict) + assert photo_dict["file_id"] == photo.file_id + assert photo_dict["file_unique_id"] == photo.file_unique_id + assert photo_dict["width"] == photo.width + assert photo_dict["height"] == photo.height + assert photo_dict["file_size"] == photo.file_size + + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_photo(chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, photo): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == photo.file_id + + assert check_shortcut_signature(PhotoSize.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(photo.get_file, photo.get_bot(), "get_file") + assert await check_defaults_handling(photo.get_file, photo.get_bot()) + + monkeypatch.setattr(photo.get_bot(), "get_file", make_assertion) + assert await photo.get_file() + + def test_equality(self, photo): + a = PhotoSize(photo.file_id, photo.file_unique_id, Space.width, Space.height) + b = PhotoSize("", photo.file_unique_id, Space.width, Space.height) + c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0) + d = PhotoSize("", "", Space.width, Space.height) + e = Sticker( + photo.file_id, + photo.file_unique_id, + Space.width, + Space.height, + False, + False, + Sticker.REGULAR, + ) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + +class TestPhotoReq: async def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo): message = await bot.send_photo( chat_id, photo_file, - caption=self.caption, + caption=Space.caption, disable_notification=False, protect_content=True, parse_mode="Markdown", @@ -121,22 +232,12 @@ async def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo) assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == TestPhoto.caption.replace("*", "") + assert message.caption == Space.caption.replace("*", "") assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_send_photo_custom_filename(self, bot, chat_id, photo_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_photo(chat_id, photo_file, filename="custom_filename") - - @pytest.mark.flaky(3, 1) async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file, thumb, photo): message = await bot.send_photo( - chat_id, photo_file, caption=self.caption, parse_mode="Markdown" + chat_id, photo_file, caption=Space.caption, parse_mode="Markdown" ) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) @@ -150,13 +251,12 @@ async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file, th assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == TestPhoto.caption.replace("*", "") + assert message.caption == Space.caption.replace("*", "") assert len(message.caption_entities) == 1 - @pytest.mark.flaky(3, 1) async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, photo): message = await bot.send_photo( - chat_id, photo_file, caption=self.caption, parse_mode="HTML" + chat_id, photo_file, caption=Space.caption, parse_mode="HTML" ) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) @@ -170,10 +270,9 @@ async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == TestPhoto.caption.replace("", "").replace("", "") + assert message.caption == Space.caption.replace("", "").replace("", "") assert len(message.caption_entities) == 1 - @pytest.mark.flaky(3, 1) async def test_send_photo_caption_entities(self, bot, chat_id, photo_file, thumb, photo): test_string = "Italic Bold Code" entities = [ @@ -188,7 +287,6 @@ async def test_send_photo_caption_entities(self, bot, chat_id, photo_file, thumb assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_photo_default_parse_mode_1( self, default_bot, chat_id, photo_file, thumb, photo @@ -200,7 +298,6 @@ async def test_send_photo_default_parse_mode_1( assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_photo_default_parse_mode_2( self, default_bot, chat_id, photo_file, thumb, photo @@ -213,7 +310,6 @@ async def test_send_photo_default_parse_mode_2( assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_photo_default_parse_mode_3( self, default_bot, chat_id, photo_file, thumb, photo @@ -226,7 +322,6 @@ async def test_send_photo_default_parse_mode_3( assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_photo_default_protect_content(self, chat_id, default_bot, photo): protected = await default_bot.send_photo(chat_id, photo) @@ -234,29 +329,6 @@ async def test_send_photo_default_protect_content(self, chat_id, default_bot, ph unprotected = await default_bot.send_photo(chat_id, photo, protect_content=False) assert not unprotected.has_protected_content - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("photo") == expected - else: - test_flag = isinstance(data.get("photo"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_photo(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -290,7 +362,6 @@ async def test_send_photo_default_allow_sending_without_reply( chat_id, photo_file, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, photo): path = Path("telegram.jpg") if path.is_file(): @@ -306,9 +377,8 @@ async def test_get_and_download(self, bot, photo): assert path.is_file() - @pytest.mark.flaky(3, 1) async def test_send_url_jpg_file(self, bot, chat_id, thumb, photo): - message = await bot.send_photo(chat_id, photo=self.photo_file_url) + message = await bot.send_photo(chat_id, photo=Space.photo_file_url) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) @@ -322,7 +392,6 @@ async def test_send_url_jpg_file(self, bot, chat_id, thumb, photo): assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - @pytest.mark.flaky(3, 1) async def test_send_url_png_file(self, bot, chat_id): message = await bot.send_photo( photo="http://dummyimage.com/600x400/000/fff.png&text=telegram", chat_id=chat_id @@ -336,7 +405,6 @@ async def test_send_url_png_file(self, bot, chat_id): assert photo.file_id != "" assert photo.file_unique_id != "" - @pytest.mark.flaky(3, 1) async def test_send_url_gif_file(self, bot, chat_id): message = await bot.send_photo( photo="http://dummyimage.com/600x400/000/fff.png&text=telegram", chat_id=chat_id @@ -350,7 +418,6 @@ async def test_send_url_gif_file(self, bot, chat_id): assert photo.file_id != "" assert photo.file_unique_id != "" - @pytest.mark.flaky(3, 1) async def test_send_file_unicode_filename(self, bot, chat_id): """ Regression test for https://github.com/python-telegram-bot/python-telegram-bot/issues/1202 @@ -366,7 +433,6 @@ async def test_send_file_unicode_filename(self, bot, chat_id): assert photo.file_id != "" assert photo.file_unique_id != "" - @pytest.mark.flaky(3, 1) async def test_send_bytesio_jpg_file(self, bot, chat_id): filepath = data_file("telegram_no_standard_header.jpg") @@ -394,15 +460,6 @@ async def test_send_bytesio_jpg_file(self, bot, chat_id): assert photo.height == 720 assert photo.file_size == 33372 - async def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["photo"] == photo.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_photo(photo=photo, chat_id=chat_id) - assert message - - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, photo, thumb): message = await bot.send_photo(chat_id=chat_id, photo=photo.file_id) @@ -418,82 +475,10 @@ async def test_resend(self, bot, chat_id, photo, thumb): assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - def test_de_json(self, bot, photo): - json_dict = { - "file_id": photo.file_id, - "file_unique_id": photo.file_unique_id, - "width": self.width, - "height": self.height, - "file_size": self.file_size, - } - json_photo = PhotoSize.de_json(json_dict, bot) - assert json_photo.api_kwargs == {} - - assert json_photo.file_id == photo.file_id - assert json_photo.file_unique_id == photo.file_unique_id - assert json_photo.width == self.width - assert json_photo.height == self.height - assert json_photo.file_size == self.file_size - - def test_to_dict(self, photo): - photo_dict = photo.to_dict() - - assert isinstance(photo_dict, dict) - assert photo_dict["file_id"] == photo.file_id - assert photo_dict["file_unique_id"] == photo.file_unique_id - assert photo_dict["width"] == photo.width - assert photo_dict["height"] == photo.height - assert photo_dict["file_size"] == photo.file_size - - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_photo(chat_id=chat_id, photo=open(os.devnull, "rb")) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_photo(chat_id=chat_id, photo="") - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_photo(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, photo): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == photo.file_id - - assert check_shortcut_signature(PhotoSize.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(photo.get_file, photo.get_bot(), "get_file") - assert await check_defaults_handling(photo.get_file, photo.get_bot()) - - monkeypatch.setattr(photo.get_bot(), "get_file", make_assertion) - assert await photo.get_file() - - def test_equality(self, photo): - a = PhotoSize(photo.file_id, photo.file_unique_id, self.width, self.height) - b = PhotoSize("", photo.file_unique_id, self.width, self.height) - c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0) - d = PhotoSize("", "", self.width, self.height) - e = Sticker( - photo.file_id, - photo.file_unique_id, - self.width, - self.height, - False, - False, - Sticker.REGULAR, - ) - - 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_poll.py b/tests/test_poll.py index 425c4eadf1a..b27ab4327b6 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -24,29 +24,31 @@ from telegram.constants import PollType -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def poll_option(): - out = PollOption(text=TestPollOption.text, voter_count=TestPollOption.voter_count) + out = PollOption(text=PollOptionSpace.text, voter_count=PollOptionSpace.voter_count) out._unfreeze() return out -class TestPollOption: +class PollOptionSpace: text = "test option" voter_count = 3 + +class TestPollOptionNoReq: def test_slot_behaviour(self, poll_option, mro_slots): for attr in poll_option.__slots__: assert getattr(poll_option, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(poll_option)) == len(set(mro_slots(poll_option))), "duplicate slot" def test_de_json(self): - json_dict = {"text": self.text, "voter_count": self.voter_count} + json_dict = {"text": PollOptionSpace.text, "voter_count": PollOptionSpace.voter_count} poll_option = PollOption.de_json(json_dict, None) assert poll_option.api_kwargs == {} - assert poll_option.text == self.text - assert poll_option.voter_count == self.voter_count + assert poll_option.text == PollOptionSpace.text + assert poll_option.voter_count == PollOptionSpace.voter_count def test_to_dict(self, poll_option): poll_option_dict = poll_option.to_dict() @@ -75,30 +77,30 @@ def test_equality(self): assert hash(a) != hash(e) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def poll_answer(): - return PollAnswer( - poll_id=TestPollAnswer.poll_id, user=TestPollAnswer.user, option_ids=TestPollAnswer.poll_id - ) + return PollAnswer(PollAnswerSpace.poll_id, PollAnswerSpace.user, PollAnswerSpace.poll_id) -class TestPollAnswer: +class PollAnswerSpace: poll_id = "id" user = User(1, "", False) option_ids = [2] + +class TestPollAnswerNoReq: def test_de_json(self): json_dict = { - "poll_id": self.poll_id, - "user": self.user.to_dict(), - "option_ids": self.option_ids, + "poll_id": PollAnswerSpace.poll_id, + "user": PollAnswerSpace.user.to_dict(), + "option_ids": PollAnswerSpace.option_ids, } poll_answer = PollAnswer.de_json(json_dict, None) assert poll_answer.api_kwargs == {} - assert poll_answer.poll_id == self.poll_id - assert poll_answer.user == self.user - assert poll_answer.option_ids == tuple(self.option_ids) + assert poll_answer.poll_id == PollAnswerSpace.poll_id + assert poll_answer.user == PollAnswerSpace.user + assert poll_answer.option_ids == tuple(PollAnswerSpace.option_ids) def test_to_dict(self, poll_answer): poll_answer_dict = poll_answer.to_dict() @@ -109,10 +111,10 @@ def test_to_dict(self, poll_answer): assert poll_answer_dict["option_ids"] == list(poll_answer.option_ids) def test_equality(self): - a = PollAnswer(123, self.user, [2]) + a = PollAnswer(123, PollAnswerSpace.user, [2]) b = PollAnswer(123, User(1, "first", False), [2]) - c = PollAnswer(123, self.user, [1, 2]) - d = PollAnswer(456, self.user, [2]) + c = PollAnswer(123, PollAnswerSpace.user, [1, 2]) + d = PollAnswer(456, PollAnswerSpace.user, [2]) e = PollOption("Text", 1) assert a == b @@ -128,27 +130,27 @@ def test_equality(self): assert hash(a) != hash(e) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def poll(): poll = Poll( - TestPoll.id_, - TestPoll.question, - TestPoll.options, - TestPoll.total_voter_count, - TestPoll.is_closed, - TestPoll.is_anonymous, - TestPoll.type, - TestPoll.allows_multiple_answers, - explanation=TestPoll.explanation, - explanation_entities=TestPoll.explanation_entities, - open_period=TestPoll.open_period, - close_date=TestPoll.close_date, + PollSpace.id_, + PollSpace.question, + PollSpace.options, + PollSpace.total_voter_count, + PollSpace.is_closed, + PollSpace.is_anonymous, + PollSpace.type, + PollSpace.allows_multiple_answers, + explanation=PollSpace.explanation, + explanation_entities=PollSpace.explanation_entities, + open_period=PollSpace.open_period, + close_date=PollSpace.close_date, ) poll._unfreeze() return poll -class TestPoll: +class PollSpace: id_ = "id" question = "Test?" options = [PollOption("test", 10), PollOption("test2", 11)] @@ -165,41 +167,43 @@ class TestPoll: open_period = 42 close_date = datetime.now(timezone.utc) + +class TestPollNoReq: def test_de_json(self, bot): json_dict = { - "id": self.id_, - "question": self.question, - "options": [o.to_dict() for o in self.options], - "total_voter_count": self.total_voter_count, - "is_closed": self.is_closed, - "is_anonymous": self.is_anonymous, - "type": self.type, - "allows_multiple_answers": self.allows_multiple_answers, - "explanation": self.explanation, - "explanation_entities": [self.explanation_entities[0].to_dict()], - "open_period": self.open_period, - "close_date": to_timestamp(self.close_date), + "id": PollSpace.id_, + "question": PollSpace.question, + "options": [o.to_dict() for o in PollSpace.options], + "total_voter_count": PollSpace.total_voter_count, + "is_closed": PollSpace.is_closed, + "is_anonymous": PollSpace.is_anonymous, + "type": PollSpace.type, + "allows_multiple_answers": PollSpace.allows_multiple_answers, + "explanation": PollSpace.explanation, + "explanation_entities": [PollSpace.explanation_entities[0].to_dict()], + "open_period": PollSpace.open_period, + "close_date": to_timestamp(PollSpace.close_date), } poll = Poll.de_json(json_dict, bot) assert poll.api_kwargs == {} - assert poll.id == self.id_ - assert poll.question == self.question - assert poll.options == tuple(self.options) - assert poll.options[0].text == self.options[0].text - assert poll.options[0].voter_count == self.options[0].voter_count - assert poll.options[1].text == self.options[1].text - assert poll.options[1].voter_count == self.options[1].voter_count - assert poll.total_voter_count == self.total_voter_count - assert poll.is_closed == self.is_closed - assert poll.is_anonymous == self.is_anonymous - assert poll.type == self.type - assert poll.allows_multiple_answers == self.allows_multiple_answers - assert poll.explanation == self.explanation - assert poll.explanation_entities == tuple(self.explanation_entities) - assert poll.open_period == self.open_period - assert abs(poll.close_date - self.close_date) < timedelta(seconds=1) - assert to_timestamp(poll.close_date) == to_timestamp(self.close_date) + assert poll.id == PollSpace.id_ + assert poll.question == PollSpace.question + assert poll.options == tuple(PollSpace.options) + assert poll.options[0].text == PollSpace.options[0].text + assert poll.options[0].voter_count == PollSpace.options[0].voter_count + assert poll.options[1].text == PollSpace.options[1].text + assert poll.options[1].voter_count == PollSpace.options[1].voter_count + assert poll.total_voter_count == PollSpace.total_voter_count + assert poll.is_closed == PollSpace.is_closed + assert poll.is_anonymous == PollSpace.is_anonymous + assert poll.type == PollSpace.type + assert poll.allows_multiple_answers == PollSpace.allows_multiple_answers + assert poll.explanation == PollSpace.explanation + assert poll.explanation_entities == tuple(PollSpace.explanation_entities) + assert poll.open_period == PollSpace.open_period + assert abs(poll.close_date - PollSpace.close_date) < timedelta(seconds=1) + assert to_timestamp(poll.close_date) == to_timestamp(PollSpace.close_date) def test_to_dict(self, poll): poll_dict = poll.to_dict() diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index 00d4250ef1f..e583b53b84d 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -27,22 +27,22 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def pre_checkout_query(bot): pcq = 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, + Space.id_, + Space.from_user, + Space.currency, + Space.total_amount, + Space.invoice_payload, + shipping_option_id=Space.shipping_option_id, + order_info=Space.order_info, ) pcq.set_bot(bot) return pcq -class TestPreCheckoutQuery: +class Space: id_ = 5 invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" @@ -51,6 +51,8 @@ class TestPreCheckoutQuery: from_user = User(0, "", False) order_info = OrderInfo() + +class TestPreCheckoutQueryNoReq: def test_slot_behaviour(self, pre_checkout_query, mro_slots): inst = pre_checkout_query for attr in inst.__slots__: @@ -59,24 +61,24 @@ def test_slot_behaviour(self, pre_checkout_query, mro_slots): 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, - "total_amount": self.total_amount, - "from": self.from_user.to_dict(), - "order_info": self.order_info.to_dict(), + "id": Space.id_, + "invoice_payload": Space.invoice_payload, + "shipping_option_id": Space.shipping_option_id, + "currency": Space.currency, + "total_amount": Space.total_amount, + "from": Space.from_user.to_dict(), + "order_info": Space.order_info.to_dict(), } pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot) assert pre_checkout_query.api_kwargs == {} assert pre_checkout_query.get_bot() is 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 + assert pre_checkout_query.id == Space.id_ + assert pre_checkout_query.invoice_payload == Space.invoice_payload + assert pre_checkout_query.shipping_option_id == Space.shipping_option_id + assert pre_checkout_query.currency == Space.currency + assert pre_checkout_query.from_user == Space.from_user + assert pre_checkout_query.order_info == Space.order_info def test_to_dict(self, pre_checkout_query): pre_checkout_query_dict = pre_checkout_query.to_dict() @@ -114,16 +116,16 @@ async def make_assertion(*_, **kwargs): def test_equality(self): a = PreCheckoutQuery( - self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload + Space.id_, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload ) b = PreCheckoutQuery( - self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload + Space.id_, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload ) - c = PreCheckoutQuery(self.id_, None, "", 0, "") + c = PreCheckoutQuery(Space.id_, None, "", 0, "") d = PreCheckoutQuery( - 0, self.from_user, self.currency, self.total_amount, self.invoice_payload + 0, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload ) - e = Update(self.id_) + e = Update(Space.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index 0d1fd0ff777..6285d2de55f 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -21,20 +21,22 @@ from telegram import BotCommand, ProximityAlertTriggered, User -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def proximity_alert_triggered(): return ProximityAlertTriggered( - traveler=TestProximityAlertTriggered.traveler, - watcher=TestProximityAlertTriggered.watcher, - distance=TestProximityAlertTriggered.distance, + Space.traveler, + Space.watcher, + Space.distance, ) -class TestProximityAlertTriggered: +class Space: traveler = User(1, "foo", False) watcher = User(2, "bar", False) distance = 42 + +class TestProximityAlertTriggeredNoReq: def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): inst = proximity_alert_triggered for attr in inst.__slots__: @@ -43,18 +45,18 @@ def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): def test_de_json(self, bot): json_dict = { - "traveler": self.traveler.to_dict(), - "watcher": self.watcher.to_dict(), - "distance": self.distance, + "traveler": Space.traveler.to_dict(), + "watcher": Space.watcher.to_dict(), + "distance": Space.distance, } proximity_alert_triggered = ProximityAlertTriggered.de_json(json_dict, bot) assert proximity_alert_triggered.api_kwargs == {} - assert proximity_alert_triggered.traveler == self.traveler - assert proximity_alert_triggered.traveler.first_name == self.traveler.first_name - assert proximity_alert_triggered.watcher == self.watcher - assert proximity_alert_triggered.watcher.first_name == self.watcher.first_name - assert proximity_alert_triggered.distance == self.distance + assert proximity_alert_triggered.traveler == Space.traveler + assert proximity_alert_triggered.traveler.first_name == Space.traveler.first_name + assert proximity_alert_triggered.watcher == Space.watcher + assert proximity_alert_triggered.watcher.first_name == Space.watcher.first_name + assert proximity_alert_triggered.distance == Space.distance def test_to_dict(self, proximity_alert_triggered): proximity_alert_triggered_dict = proximity_alert_triggered.to_dict() diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 56b1366e016..004272c12fa 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -22,44 +22,30 @@ from telegram import InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def reply_keyboard_markup(): return ReplyKeyboardMarkup( - TestReplyKeyboardMarkup.keyboard, - resize_keyboard=TestReplyKeyboardMarkup.resize_keyboard, - one_time_keyboard=TestReplyKeyboardMarkup.one_time_keyboard, - selective=TestReplyKeyboardMarkup.selective, + Space.keyboard, + resize_keyboard=Space.resize_keyboard, + one_time_keyboard=Space.one_time_keyboard, + selective=Space.selective, ) -class TestReplyKeyboardMarkup: +class Space: keyboard = [[KeyboardButton("button1"), KeyboardButton("button2")]] resize_keyboard = True one_time_keyboard = True selective = True + +class TestReplyKeyboardMarkupNoReq: def test_slot_behaviour(self, reply_keyboard_markup, mro_slots): inst = reply_keyboard_markup for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - @pytest.mark.flaky(3, 1) - async def test_send_message_with_reply_keyboard_markup( - self, bot, chat_id, reply_keyboard_markup - ): - message = await bot.send_message(chat_id, "Text", reply_markup=reply_keyboard_markup) - - assert message.text == "Text" - - @pytest.mark.flaky(3, 1) - async def test_send_message_with_data_markup(self, bot, chat_id): - message = await bot.send_message( - chat_id, "text 2", reply_markup={"keyboard": [["1", "2"]]} - ) - - assert message.text == "text 2" - def test_from_button(self): reply_keyboard_markup = ReplyKeyboardMarkup.from_button( KeyboardButton(text="button1") @@ -100,9 +86,9 @@ def test_expected_values(self, reply_keyboard_markup): assert all(isinstance(row, tuple) for row in reply_keyboard_markup.keyboard) 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 + assert reply_keyboard_markup.resize_keyboard == Space.resize_keyboard + assert reply_keyboard_markup.one_time_keyboard == Space.one_time_keyboard + assert reply_keyboard_markup.selective == Space.selective def test_wrong_keyboard_inputs(self): with pytest.raises(ValueError): @@ -159,3 +145,19 @@ def test_equality(self): assert a != f assert hash(a) != hash(f) + + +class TestReplyKeyboardMarkupReq: + async def test_send_message_with_reply_keyboard_markup( + self, bot, chat_id, reply_keyboard_markup + ): + message = await bot.send_message(chat_id, "Text", reply_markup=reply_keyboard_markup) + + assert message.text == "Text" + + async def test_send_message_with_data_markup(self, bot, chat_id): + message = await bot.send_message( + chat_id, "text 2", reply_markup={"keyboard": [["1", "2"]]} + ) + + assert message.text == "text 2" diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index 91937d05e33..08244b9ce42 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -21,32 +21,26 @@ from telegram import ReplyKeyboardRemove -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def reply_keyboard_remove(): - return ReplyKeyboardRemove(selective=TestReplyKeyboardRemove.selective) + return ReplyKeyboardRemove(selective=Space.selective) -class TestReplyKeyboardRemove: +class Space: remove_keyboard = True selective = True + +class TestReplyKeyboardRemoveNoReq: def test_slot_behaviour(self, reply_keyboard_remove, mro_slots): inst = reply_keyboard_remove for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - @pytest.mark.flaky(3, 1) - async def test_send_message_with_reply_keyboard_remove( - self, bot, chat_id, reply_keyboard_remove - ): - message = await 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 + assert reply_keyboard_remove.remove_keyboard == Space.remove_keyboard + assert reply_keyboard_remove.selective == Space.selective def test_to_dict(self, reply_keyboard_remove): reply_keyboard_remove_dict = reply_keyboard_remove.to_dict() @@ -55,3 +49,11 @@ def test_to_dict(self, reply_keyboard_remove): reply_keyboard_remove_dict["remove_keyboard"] == reply_keyboard_remove.remove_keyboard ) assert reply_keyboard_remove_dict["selective"] == reply_keyboard_remove.selective + + +class TestReplyKeyboardRemoveReq: + async def test_send_message_with_reply_keyboard_remove( + self, bot, chat_id, reply_keyboard_remove + ): + message = await bot.send_message(chat_id, "Text", reply_markup=reply_keyboard_remove) + assert message.text == "Text" diff --git a/tests/test_request.py b/tests/test_request.py index 7ab655586cc..d4cd90ac6f4 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -84,7 +84,7 @@ async def test_init(self, bot): HTTPXRequest(proxy_url="socks5://foo") -class TestRequest: +class TestRequestNoReq: test_flag = None @pytest.fixture(autouse=True) @@ -325,7 +325,7 @@ async def make_assertion(*args, **kwargs): assert self.test_flag == (1, 2, 3, 4) -class TestHTTPXRequest: +class TestHTTPXRequestNoReq: test_flag = None @pytest.fixture(autouse=True) @@ -567,7 +567,8 @@ async def request(_, **kwargs): httpx_request.do_request(method="GET", url="URL"), ) - @pytest.mark.flaky(3, 1) + +class TestHTTPXRequestReq: async def test_do_request_wait_for_pool(self, monkeypatch, httpx_request): """The pool logic is buried rather deeply in httpxcore, so we make actual requests here instead of mocking""" diff --git a/tests/test_requestdata.py b/tests/test_requestdata.py index a814d3ed5a4..908cda5db7b 100644 --- a/tests/test_requestdata.py +++ b/tests/test_requestdata.py @@ -108,28 +108,28 @@ def file_rqs(file_params) -> RequestData: ) -@pytest.fixture() +@pytest.fixture(scope="module") def mixed_params(file_params, simple_params) -> Dict[str, Any]: both = file_params.copy() both.update(simple_params) return both -@pytest.fixture() +@pytest.fixture(scope="module") def mixed_jsons(file_jsons, simple_jsons) -> Dict[str, Any]: both = file_jsons.copy() both.update(simple_jsons) return both -@pytest.fixture() +@pytest.fixture(scope="module") def mixed_rqs(mixed_params) -> RequestData: return RequestData( [RequestParameter.from_input(key, value) for key, value in mixed_params.items()] ) -class TestRequestData: +class TestRequestDataNoReq: def test_slot_behaviour(self, simple_rqs, mro_slots): for attr in simple_rqs.__slots__: assert getattr(simple_rqs, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_requestparameter.py b/tests/test_requestparameter.py index f5add3dbfba..49f333a0261 100644 --- a/tests/test_requestparameter.py +++ b/tests/test_requestparameter.py @@ -26,7 +26,7 @@ from tests.conftest import data_file -class TestRequestParameter: +class TestRequestParameterNoReq: def test_init(self): request_parameter = RequestParameter("name", "value", [1, 2]) assert request_parameter.name == "name" diff --git a/tests/test_sentwebappmessage.py b/tests/test_sentwebappmessage.py index 2d3d93da6f7..d513e90e9d8 100644 --- a/tests/test_sentwebappmessage.py +++ b/tests/test_sentwebappmessage.py @@ -22,16 +22,16 @@ from telegram import SentWebAppMessage -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def sent_web_app_message(): - return SentWebAppMessage( - inline_message_id=TestSentWebAppMessage.inline_message_id, - ) + return SentWebAppMessage(inline_message_id=Space.inline_message_id) -class TestSentWebAppMessage: +class Space: inline_message_id = "123" + +class TestSentWebAppMessageNoReq: def test_slot_behaviour(self, sent_web_app_message, mro_slots): inst = sent_web_app_message for attr in inst.__slots__: @@ -42,17 +42,17 @@ def test_to_dict(self, sent_web_app_message): sent_web_app_message_dict = sent_web_app_message.to_dict() assert isinstance(sent_web_app_message_dict, dict) - assert sent_web_app_message_dict["inline_message_id"] == self.inline_message_id + assert sent_web_app_message_dict["inline_message_id"] == Space.inline_message_id def test_de_json(self, bot): - data = {"inline_message_id": self.inline_message_id} + data = {"inline_message_id": Space.inline_message_id} m = SentWebAppMessage.de_json(data, None) assert m.api_kwargs == {} - assert m.inline_message_id == self.inline_message_id + assert m.inline_message_id == Space.inline_message_id def test_equality(self): - a = SentWebAppMessage(self.inline_message_id) - b = SentWebAppMessage(self.inline_message_id) + a = SentWebAppMessage(Space.inline_message_id) + b = SentWebAppMessage(Space.inline_message_id) c = SentWebAppMessage("") d = SentWebAppMessage("not_inline_message_id") diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 1552ebc88dd..5c1db72228b 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -21,19 +21,19 @@ from telegram import ShippingAddress -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def shipping_address(): return ShippingAddress( - TestShippingAddress.country_code, - TestShippingAddress.state, - TestShippingAddress.city, - TestShippingAddress.street_line1, - TestShippingAddress.street_line2, - TestShippingAddress.post_code, + Space.country_code, + Space.state, + Space.city, + Space.street_line1, + Space.street_line2, + Space.post_code, ) -class TestShippingAddress: +class Space: country_code = "GB" state = "state" city = "London" @@ -41,6 +41,8 @@ class TestShippingAddress: street_line2 = "street_line2" post_code = "WC1" + +class TestShippingAddressNoReq: def test_slot_behaviour(self, shipping_address, mro_slots): inst = shipping_address for attr in inst.__slots__: @@ -49,22 +51,22 @@ def test_slot_behaviour(self, shipping_address, mro_slots): def test_de_json(self, bot): json_dict = { - "country_code": self.country_code, - "state": self.state, - "city": self.city, - "street_line1": self.street_line1, - "street_line2": self.street_line2, - "post_code": self.post_code, + "country_code": Space.country_code, + "state": Space.state, + "city": Space.city, + "street_line1": Space.street_line1, + "street_line2": Space.street_line2, + "post_code": Space.post_code, } shipping_address = ShippingAddress.de_json(json_dict, bot) assert shipping_address.api_kwargs == {} - 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 + assert shipping_address.country_code == Space.country_code + assert shipping_address.state == Space.state + assert shipping_address.city == Space.city + assert shipping_address.street_line1 == Space.street_line1 + assert shipping_address.street_line2 == Space.street_line2 + assert shipping_address.post_code == Space.post_code def test_to_dict(self, shipping_address): shipping_address_dict = shipping_address.to_dict() @@ -79,38 +81,48 @@ def test_to_dict(self, shipping_address): def test_equality(self): a = ShippingAddress( - self.country_code, - self.state, - self.city, - self.street_line1, - self.street_line2, - self.post_code, + Space.country_code, + Space.state, + Space.city, + Space.street_line1, + Space.street_line2, + Space.post_code, ) b = ShippingAddress( - self.country_code, - self.state, - self.city, - self.street_line1, - self.street_line2, - self.post_code, + Space.country_code, + Space.state, + Space.city, + Space.street_line1, + Space.street_line2, + Space.post_code, ) d = ShippingAddress( - "", self.state, self.city, self.street_line1, self.street_line2, self.post_code + "", Space.state, Space.city, Space.street_line1, Space.street_line2, Space.post_code ) d2 = ShippingAddress( - self.country_code, "", self.city, self.street_line1, self.street_line2, self.post_code + Space.country_code, + "", + Space.city, + Space.street_line1, + Space.street_line2, + Space.post_code, ) d3 = ShippingAddress( - self.country_code, self.state, "", self.street_line1, self.street_line2, self.post_code + Space.country_code, + Space.state, + "", + Space.street_line1, + Space.street_line2, + Space.post_code, ) d4 = ShippingAddress( - self.country_code, self.state, self.city, "", self.street_line2, self.post_code + Space.country_code, Space.state, Space.city, "", Space.street_line2, Space.post_code ) d5 = ShippingAddress( - self.country_code, self.state, self.city, self.street_line1, "", self.post_code + Space.country_code, Space.state, Space.city, Space.street_line1, "", Space.post_code ) d6 = ShippingAddress( - self.country_code, self.state, self.city, self.street_line1, self.street_line2, "" + Space.country_code, Space.state, Space.city, Space.street_line1, Space.street_line2, "" ) assert a == b diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 663a5ad2712..913228dc551 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -21,18 +21,18 @@ from telegram import LabeledPrice, ShippingOption, Voice -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def shipping_option(): - return ShippingOption( - TestShippingOption.id_, TestShippingOption.title, TestShippingOption.prices - ) + return ShippingOption(Space.id_, Space.title, Space.prices) -class TestShippingOption: +class Space: id_ = "id" title = "title" prices = [LabeledPrice("Fish Container", 100), LabeledPrice("Premium Fish Container", 1000)] + +class TestShippingOptionNoReq: def test_slot_behaviour(self, shipping_option, mro_slots): inst = shipping_option for attr in inst.__slots__: @@ -40,9 +40,9 @@ def test_slot_behaviour(self, shipping_option, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, shipping_option): - assert shipping_option.id == self.id_ - assert shipping_option.title == self.title - assert shipping_option.prices == tuple(self.prices) + assert shipping_option.id == Space.id_ + assert shipping_option.title == Space.title + assert shipping_option.prices == tuple(Space.prices) def test_to_dict(self, shipping_option): shipping_option_dict = shipping_option.to_dict() @@ -54,11 +54,11 @@ def test_to_dict(self, shipping_option): assert shipping_option_dict["prices"][1] == shipping_option.prices[1].to_dict() def test_equality(self): - 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_, "someid", 0) + a = ShippingOption(Space.id_, Space.title, Space.prices) + b = ShippingOption(Space.id_, Space.title, Space.prices) + c = ShippingOption(Space.id_, "", []) + d = ShippingOption(0, Space.title, Space.prices) + e = Voice(Space.id_, "someid", 0) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index e6c857083aa..8f988351af4 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -27,24 +27,21 @@ ) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def shipping_query(bot): - sq = ShippingQuery( - TestShippingQuery.id_, - TestShippingQuery.from_user, - TestShippingQuery.invoice_payload, - TestShippingQuery.shipping_address, - ) + sq = ShippingQuery(Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address) sq.set_bot(bot) return sq -class TestShippingQuery: +class Space: id_ = "5" invoice_payload = "invoice_payload" from_user = User(0, "", False) shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") + +class TestShippingQueryNoReq: def test_slot_behaviour(self, shipping_query, mro_slots): inst = shipping_query for attr in inst.__slots__: @@ -53,18 +50,18 @@ def test_slot_behaviour(self, shipping_query, mro_slots): 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(), + "id": Space.id_, + "invoice_payload": Space.invoice_payload, + "from": Space.from_user.to_dict(), + "shipping_address": Space.shipping_address.to_dict(), } shipping_query = ShippingQuery.de_json(json_dict, bot) assert shipping_query.api_kwargs == {} - 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 + assert shipping_query.id == Space.id_ + assert shipping_query.invoice_payload == Space.invoice_payload + assert shipping_query.from_user == Space.from_user + assert shipping_query.shipping_address == Space.shipping_address assert shipping_query.get_bot() is bot def test_to_dict(self, shipping_query): @@ -92,11 +89,15 @@ async def make_assertion(*_, **kwargs): assert await shipping_query.answer(ok=True) def test_equality(self): - 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_) + a = ShippingQuery( + Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address + ) + b = ShippingQuery( + Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address + ) + c = ShippingQuery(Space.id_, None, "", None) + d = ShippingQuery(0, Space.from_user, Space.invoice_payload, Space.shipping_address) + e = Update(Space.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index fe96bd6ac55..60353b93a5e 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -39,7 +39,7 @@ def sticker_file(): yield file -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def sticker(bot, chat_id): with data_file("telegram.webp").open("rb") as f: return (await bot.send_sticker(chat_id, sticker=f, read_timeout=50)).sticker @@ -51,7 +51,7 @@ def animated_sticker_file(): yield f -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def animated_sticker(bot, chat_id): with data_file("telegram_animated_sticker.tgs").open("rb") as f: return (await bot.send_sticker(chat_id, sticker=f, read_timeout=50)).sticker @@ -63,13 +63,13 @@ def video_sticker_file(): yield f -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def video_sticker(bot, chat_id): with data_file("telegram_video_sticker.webm").open("rb") as f: return bot.send_sticker(chat_id, sticker=f, timeout=50).sticker -class TestSticker: +class StickerSpace: # 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 = ( @@ -94,6 +94,8 @@ class TestSticker: premium_animation = File("this_is_an_id", "this_is_an_unique_id") + +class TestStickerNoReq: def test_slot_behaviour(self, sticker, mro_slots, recwarn): for attr in sticker.__slots__: assert getattr(sticker, attr, "err") != "err", f"got extra slot '{attr}'" @@ -113,19 +115,158 @@ def test_creation(self, sticker): assert sticker.thumb.file_unique_id != "" def test_expected_values(self, sticker): - assert sticker.width == self.width - assert sticker.height == self.height - assert sticker.is_animated == self.is_animated - assert sticker.is_video == self.is_video - assert sticker.file_size == self.file_size - assert sticker.thumb.width == self.thumb_width - assert sticker.thumb.height == self.thumb_height - assert sticker.thumb.file_size == self.thumb_file_size - assert sticker.type == self.type + assert sticker.width == StickerSpace.width + assert sticker.height == StickerSpace.height + assert sticker.is_animated == StickerSpace.is_animated + assert sticker.is_video == StickerSpace.is_video + assert sticker.file_size == StickerSpace.file_size + assert sticker.thumb.width == StickerSpace.thumb_width + assert sticker.thumb.height == StickerSpace.thumb_height + assert sticker.thumb.file_size == StickerSpace.thumb_file_size + assert sticker.type == StickerSpace.type # we need to be a premium TG user to send a premium sticker, so the below is not tested - # assert sticker.premium_animation == self.premium_animation + # assert sticker.premium_animation == StickerSpace.premium_animation + + def test_de_json(self, bot, sticker): + json_dict = { + "file_id": StickerSpace.sticker_file_id, + "file_unique_id": StickerSpace.sticker_file_unique_id, + "width": StickerSpace.width, + "height": StickerSpace.height, + "is_animated": StickerSpace.is_animated, + "is_video": StickerSpace.is_video, + "thumb": sticker.thumb.to_dict(), + "emoji": StickerSpace.emoji, + "file_size": StickerSpace.file_size, + "premium_animation": StickerSpace.premium_animation.to_dict(), + "type": StickerSpace.type, + "custom_emoji_id": StickerSpace.custom_emoji_id, + } + json_sticker = Sticker.de_json(json_dict, bot) + assert json_sticker.api_kwargs == {} + + assert json_sticker.file_id == StickerSpace.sticker_file_id + assert json_sticker.file_unique_id == StickerSpace.sticker_file_unique_id + assert json_sticker.width == StickerSpace.width + assert json_sticker.height == StickerSpace.height + assert json_sticker.is_animated == StickerSpace.is_animated + assert json_sticker.is_video == StickerSpace.is_video + assert json_sticker.emoji == StickerSpace.emoji + assert json_sticker.file_size == StickerSpace.file_size + assert json_sticker.thumb == sticker.thumb + assert json_sticker.premium_animation == StickerSpace.premium_animation + assert json_sticker.type == StickerSpace.type + assert json_sticker.custom_emoji_id == StickerSpace.custom_emoji_id + + async def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["sticker"] == sticker.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_sticker(sticker=sticker, chat_id=chat_id) + assert message + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_sticker_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("sticker") == expected + else: + test_flag = isinstance(data.get("sticker"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_sticker(chat_id, file) + assert test_flag + monkeypatch.delattr(bot, "_post") + finally: + bot._local_mode = False + + def test_to_dict(self, sticker): + sticker_dict = sticker.to_dict() - @pytest.mark.flaky(3, 1) + assert isinstance(sticker_dict, dict) + assert sticker_dict["file_id"] == sticker.file_id + assert sticker_dict["file_unique_id"] == sticker.file_unique_id + assert sticker_dict["width"] == sticker.width + assert sticker_dict["height"] == sticker.height + assert sticker_dict["is_animated"] == sticker.is_animated + assert sticker_dict["is_video"] == sticker.is_video + assert sticker_dict["file_size"] == sticker.file_size + assert sticker_dict["thumb"] == sticker.thumb.to_dict() + assert sticker_dict["type"] == sticker.type + + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_sticker(chat_id) + + def test_equality(self, sticker): + a = Sticker( + sticker.file_id, + sticker.file_unique_id, + StickerSpace.width, + StickerSpace.height, + StickerSpace.is_animated, + StickerSpace.is_video, + StickerSpace.type, + ) + b = Sticker( + "", + sticker.file_unique_id, + StickerSpace.width, + StickerSpace.height, + StickerSpace.is_animated, + StickerSpace.is_video, + StickerSpace.type, + ) + c = Sticker( + sticker.file_id, + sticker.file_unique_id, + 0, + 0, + False, + True, + StickerSpace.type, + ) + d = Sticker( + "", + "", + StickerSpace.width, + StickerSpace.height, + StickerSpace.is_animated, + StickerSpace.is_video, + StickerSpace.type, + ) + e = PhotoSize( + sticker.file_id, + sticker.file_unique_id, + StickerSpace.width, + StickerSpace.height, + StickerSpace.is_animated, + ) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + +class TestStickerReq: async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): message = await bot.send_sticker( chat_id, sticker=sticker_file, disable_notification=False, protect_content=True @@ -155,7 +296,6 @@ async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): assert message.sticker.thumb.height == sticker.thumb.height assert message.sticker.thumb.file_size == sticker.thumb.file_size - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, sticker): path = Path("telegram.webp") if path.is_file(): @@ -172,22 +312,19 @@ async def test_get_and_download(self, bot, sticker): assert path.is_file() - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, sticker): message = await bot.send_sticker(chat_id=chat_id, sticker=sticker.file_id) assert message.sticker == sticker - @pytest.mark.flaky(3, 1) async def test_send_on_server_emoji(self, bot, chat_id): server_file_id = "CAADAQADHAADyIsGAAFZfq1bphjqlgI" message = await bot.send_sticker(chat_id=chat_id, sticker=server_file_id) sticker = message.sticker - assert sticker.emoji == self.emoji + assert sticker.emoji == StickerSpace.emoji - @pytest.mark.flaky(3, 1) async def test_send_from_url(self, bot, chat_id): - message = await bot.send_sticker(chat_id=chat_id, sticker=self.sticker_file_url) + message = await bot.send_sticker(chat_id=chat_id, sticker=StickerSpace.sticker_file_url) sticker = message.sticker assert isinstance(message.sticker, Sticker) @@ -211,69 +348,6 @@ async def test_send_from_url(self, bot, chat_id): assert message.sticker.thumb.height == sticker.thumb.height assert message.sticker.thumb.file_size == sticker.thumb.file_size - def test_de_json(self, bot, sticker): - json_dict = { - "file_id": self.sticker_file_id, - "file_unique_id": self.sticker_file_unique_id, - "width": self.width, - "height": self.height, - "is_animated": self.is_animated, - "is_video": self.is_video, - "thumb": sticker.thumb.to_dict(), - "emoji": self.emoji, - "file_size": self.file_size, - "premium_animation": self.premium_animation.to_dict(), - "type": self.type, - "custom_emoji_id": self.custom_emoji_id, - } - json_sticker = Sticker.de_json(json_dict, bot) - assert json_sticker.api_kwargs == {} - - assert json_sticker.file_id == self.sticker_file_id - assert json_sticker.file_unique_id == self.sticker_file_unique_id - assert json_sticker.width == self.width - assert json_sticker.height == self.height - assert json_sticker.is_animated == self.is_animated - assert json_sticker.is_video == self.is_video - assert json_sticker.emoji == self.emoji - assert json_sticker.file_size == self.file_size - assert json_sticker.thumb == sticker.thumb - assert json_sticker.premium_animation == self.premium_animation - assert json_sticker.type == self.type - assert json_sticker.custom_emoji_id == self.custom_emoji_id - - async def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["sticker"] == sticker.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_sticker(sticker=sticker, chat_id=chat_id) - assert message - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_sticker_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("sticker") == expected - else: - test_flag = isinstance(data.get("sticker"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_sticker(chat_id, file) - assert test_flag - monkeypatch.delattr(bot, "_post") - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -307,7 +381,6 @@ async def test_send_sticker_default_allow_sending_without_reply( chat_id, sticker, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_sticker_default_protect_content(self, chat_id, sticker, default_bot): protected = await default_bot.send_sticker(chat_id, sticker) @@ -315,35 +388,6 @@ async def test_send_sticker_default_protect_content(self, chat_id, sticker, defa unprotected = await default_bot.send_sticker(chat_id, sticker, protect_content=False) assert not unprotected.has_protected_content - 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["file_unique_id"] == sticker.file_unique_id - assert sticker_dict["width"] == sticker.width - assert sticker_dict["height"] == sticker.height - assert sticker_dict["is_animated"] == sticker.is_animated - assert sticker_dict["is_video"] == sticker.is_video - assert sticker_dict["file_size"] == sticker.file_size - assert sticker_dict["thumb"] == sticker.thumb.to_dict() - assert sticker_dict["type"] == sticker.type - - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file(self, bot, chat_id): - with pytest.raises(TelegramError): - await bot.send_sticker(chat_id, open(os.devnull, "rb")) - - @pytest.mark.flaky(3, 1) - async def test_error_send_empty_file_id(self, bot, chat_id): - with pytest.raises(TelegramError): - await bot.send_sticker(chat_id, "") - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_sticker(chat_id) - - @pytest.mark.flaky(3, 1) async def test_premium_animation(self, bot): # testing animation sucks a bit since we can't create a premium sticker. What we can do is # get a sticker set which includes a premium sticker and check that specific one. @@ -361,7 +405,6 @@ async def test_premium_animation(self, bot): } assert premium_sticker.premium_animation.to_dict() == premium_sticker_dict - @pytest.mark.flaky(3, 1) async def test_custom_emoji(self, bot): # testing custom emoji stickers is as much of an annoyance as the premium animation, see # in test_premium_animation @@ -371,63 +414,13 @@ async def test_custom_emoji(self, bot): custom_emoji_sticker = custom_emoji_set.stickers[0] assert custom_emoji_sticker.custom_emoji_id == "6046140249875156202" - def test_equality(self, sticker): - a = Sticker( - sticker.file_id, - sticker.file_unique_id, - self.width, - self.height, - self.is_animated, - self.is_video, - self.type, - ) - b = Sticker( - "", - sticker.file_unique_id, - self.width, - self.height, - self.is_animated, - self.is_video, - self.type, - ) - c = Sticker( - sticker.file_id, - sticker.file_unique_id, - 0, - 0, - False, - True, - self.type, - ) - d = Sticker( - "", - "", - self.width, - self.height, - self.is_animated, - self.is_video, - self.type, - ) - e = PhotoSize( - sticker.file_id, - sticker.file_unique_id, - self.width, - self.height, - self.is_animated, - ) - - 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) + async def test_error_send_empty_file(self, bot, chat_id): + with pytest.raises(TelegramError): + await bot.send_sticker(chat_id, open(os.devnull, "rb")) - assert a != e - assert hash(a) != hash(e) + async def test_error_send_empty_file_id(self, bot, chat_id): + with pytest.raises(TelegramError): + await bot.send_sticker(chat_id, "") @pytest.fixture(scope="function") @@ -478,7 +471,7 @@ def sticker_set_thumb_file(): yield file -class TestStickerSet: +class SetSpace: title = "Test stickers" is_animated = True is_video = True @@ -487,104 +480,30 @@ class TestStickerSet: sticker_type = Sticker.REGULAR contains_masks = True + +class TestStickerSetNoReq: def test_de_json(self, bot, sticker): name = f"test_by_{bot.username}" json_dict = { "name": name, - "title": self.title, - "is_animated": self.is_animated, - "is_video": self.is_video, - "stickers": [x.to_dict() for x in self.stickers], + "title": SetSpace.title, + "is_animated": SetSpace.is_animated, + "is_video": SetSpace.is_video, + "stickers": [x.to_dict() for x in SetSpace.stickers], "thumb": sticker.thumb.to_dict(), - "sticker_type": self.sticker_type, - "contains_masks": self.contains_masks, + "sticker_type": SetSpace.sticker_type, + "contains_masks": SetSpace.contains_masks, } sticker_set = StickerSet.de_json(json_dict, bot) assert sticker_set.name == name - assert sticker_set.title == self.title - assert sticker_set.is_animated == self.is_animated - assert sticker_set.is_video == self.is_video - assert sticker_set.stickers == tuple(self.stickers) + assert sticker_set.title == SetSpace.title + assert sticker_set.is_animated == SetSpace.is_animated + assert sticker_set.is_video == SetSpace.is_video + assert sticker_set.stickers == tuple(SetSpace.stickers) assert sticker_set.thumb == sticker.thumb - assert sticker_set.sticker_type == self.sticker_type - assert sticker_set.api_kwargs == {"contains_masks": self.contains_masks} - - async def test_create_sticker_set( - self, bot, chat_id, sticker_file, animated_sticker_file, video_sticker_file - ): - """Creates the sticker set (if needed) which is required for tests. Make sure that this - test comes before the tests that actually use the sticker sets! - """ - test_by = f"test_by_{bot.username}" - for sticker_set in [test_by, f"animated_{test_by}", f"video_{test_by}"]: - try: - await bot.get_sticker_set(sticker_set) - except BadRequest as e: - if not e.message == "Stickerset_invalid": - raise e - - if sticker_set.startswith(test_by): - s = await bot.create_new_sticker_set( - chat_id, - name=sticker_set, - title="Sticker Test", - png_sticker=sticker_file, - emojis="😄", - ) - assert s - elif sticker_set.startswith("animated"): - a = await bot.create_new_sticker_set( - chat_id, - name=sticker_set, - title="Animated Test", - tgs_sticker=animated_sticker_file, - emojis="😄", - ) - assert a - elif sticker_set.startswith("video"): - v = await bot.create_new_sticker_set( - chat_id, - name=sticker_set, - title="Video Test", - webm_sticker=video_sticker_file, - emojis="🤔", - ) - assert v - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_1_png(self, bot, chat_id, sticker_file): - with data_file("telegram_sticker.png").open("rb") as f: - # chat_id was hardcoded as 95205500 but it stopped working for some reason - file = await bot.upload_sticker_file(chat_id, f) - assert file - assert await bot.add_sticker_to_set( - chat_id, f"test_by_{bot.username}", png_sticker=file.file_id, emojis="😄" - ) - # Also test with file input and mask - assert await bot.add_sticker_to_set( - chat_id, - f"test_by_{bot.username}", - png_sticker=sticker_file, - emojis="😄", - mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2), - ) - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_1_tgs(self, bot, chat_id): - assert await bot.add_sticker_to_set( - chat_id, - f"animated_test_by_{bot.username}", - tgs_sticker=data_file("telegram_animated_sticker.tgs").open("rb"), - emojis="😄", - ) - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_1_webm(self, bot, chat_id): - with data_file("telegram_video_sticker.webm").open("rb") as f: - assert await bot.add_sticker_to_set( - chat_id, f"video_test_by_{bot.username}", webm_sticker=f, emojis="🤔" - ) + assert sticker_set.sticker_type == SetSpace.sticker_type + assert sticker_set.api_kwargs == {"contains_masks": SetSpace.contains_masks} def test_sticker_set_to_dict(self, sticker_set): sticker_set_dict = sticker_set.to_dict() @@ -598,64 +517,6 @@ def test_sticker_set_to_dict(self, sticker_set): assert sticker_set_dict["thumb"] == sticker_set.thumb.to_dict() assert sticker_set_dict["sticker_type"] == sticker_set.sticker_type - @pytest.mark.flaky(3, 1) - async def test_bot_methods_2_png(self, bot, sticker_set): - file_id = sticker_set.stickers[0].file_id - assert await bot.set_sticker_position_in_set(file_id, 1) - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_2_tgs(self, bot, animated_sticker_set): - file_id = animated_sticker_set.stickers[0].file_id - assert await bot.set_sticker_position_in_set(file_id, 1) - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_2_webm(self, bot, video_sticker_set): - file_id = video_sticker_set.stickers[0].file_id - assert await bot.set_sticker_position_in_set(file_id, 1) - - @pytest.mark.flaky(3, 1) - async def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): - assert await bot.set_sticker_set_thumb( - f"test_by_{bot.username}", chat_id, sticker_set_thumb_file - ) - - @pytest.mark.flaky(10, 1) - async def test_bot_methods_3_tgs( - self, bot, chat_id, animated_sticker_file, animated_sticker_set - ): - await asyncio.sleep(1) - animated_test = f"animated_test_by_{bot.username}" - assert await bot.set_sticker_set_thumb(animated_test, chat_id, animated_sticker_file) - file_id = animated_sticker_set.stickers[-1].file_id - # also test with file input and mask - assert await bot.set_sticker_set_thumb(animated_test, chat_id, file_id) - - # TODO: Try the below by creating a custom .webm and not by downloading another pack's thumb - @pytest.mark.skip( - "Skipped for now since Telegram throws a 'File is too big' error " - "regardless of the .webm file size." - ) - def test_bot_methods_3_webm(self, bot, chat_id, video_sticker_file, video_sticker_set): - pass - - @pytest.mark.flaky(10, 1) - async def test_bot_methods_4_png(self, bot, sticker_set): - await asyncio.sleep(1) - file_id = sticker_set.stickers[-1].file_id - assert await bot.delete_sticker_from_set(file_id) - - @pytest.mark.flaky(10, 1) - async def test_bot_methods_4_tgs(self, bot, animated_sticker_set): - await asyncio.sleep(1) - file_id = animated_sticker_set.stickers[-1].file_id - assert await bot.delete_sticker_from_set(file_id) - - @pytest.mark.flaky(10, 1) - async def test_bot_methods_4_webm(self, bot, video_sticker_set): - await asyncio.sleep(1) - file_id = video_sticker_set.stickers[-1].file_id - assert await bot.delete_sticker_from_set(file_id) - @pytest.mark.parametrize("local_mode", [True, False]) async def test_upload_sticker_file_local_files(self, monkeypatch, bot, chat_id, local_mode): try: @@ -809,31 +670,31 @@ async def make_assertion(*_, **kwargs): def test_equality(self): a = StickerSet( - self.name, - self.title, - self.is_animated, - self.stickers, - self.is_video, - self.sticker_type, + SetSpace.name, + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, ) b = StickerSet( - self.name, - self.title, - self.is_animated, - self.stickers, - self.is_video, - self.sticker_type, + SetSpace.name, + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, ) - c = StickerSet(self.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) + c = StickerSet(SetSpace.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) d = StickerSet( "blah", - self.title, - self.is_animated, - self.stickers, - self.is_video, - self.sticker_type, + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, ) - e = Audio(self.name, "", 0, None, None) + e = Audio(SetSpace.name, "", 0, None, None) assert a == b assert hash(a) == hash(b) @@ -849,36 +710,158 @@ def test_equality(self): assert hash(a) != hash(e) -@pytest.fixture(scope="class") -def mask_position(): - return MaskPosition( - TestMaskPosition.point, - TestMaskPosition.x_shift, - TestMaskPosition.y_shift, - TestMaskPosition.scale, +class TestStickerSetReq: + async def test_create_sticker_set( + self, bot, chat_id, sticker_file, animated_sticker_file, video_sticker_file + ): + """Creates the sticker set (if needed) which is required for tests. Make sure that this + test comes before the tests that actually use the sticker sets! + """ + test_by = f"test_by_{bot.username}" + for sticker_set in [test_by, f"animated_{test_by}", f"video_{test_by}"]: + try: + await bot.get_sticker_set(sticker_set) + except BadRequest as e: + if not e.message == "Stickerset_invalid": + raise e + + if sticker_set.startswith(test_by): + s = await bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Sticker Test", + png_sticker=sticker_file, + emojis="😄", + ) + assert s + elif sticker_set.startswith("animated"): + a = await bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Animated Test", + tgs_sticker=animated_sticker_file, + emojis="😄", + ) + assert a + elif sticker_set.startswith("video"): + v = await bot.create_new_sticker_set( + chat_id, + name=sticker_set, + title="Video Test", + webm_sticker=video_sticker_file, + emojis="🤔", + ) + assert v + + async def test_bot_methods_1_png(self, bot, chat_id, sticker_file): + with data_file("telegram_sticker.png").open("rb") as f: + # chat_id was hardcoded as 95205500 but it stopped working for some reason + file = await bot.upload_sticker_file(chat_id, f) + assert file + assert await bot.add_sticker_to_set( + chat_id, f"test_by_{bot.username}", png_sticker=file.file_id, emojis="😄" + ) + # Also test with file input and mask + assert await bot.add_sticker_to_set( + chat_id, + f"test_by_{bot.username}", + png_sticker=sticker_file, + emojis="😄", + mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2), + ) + + async def test_bot_methods_1_tgs(self, bot, chat_id): + assert await bot.add_sticker_to_set( + chat_id, + f"animated_test_by_{bot.username}", + tgs_sticker=data_file("telegram_animated_sticker.tgs").open("rb"), + emojis="😄", + ) + + async def test_bot_methods_1_webm(self, bot, chat_id): + with data_file("telegram_video_sticker.webm").open("rb") as f: + assert await bot.add_sticker_to_set( + chat_id, f"video_test_by_{bot.username}", webm_sticker=f, emojis="🤔" + ) + + async def test_bot_methods_2_png(self, bot, sticker_set): + file_id = sticker_set.stickers[0].file_id + assert await bot.set_sticker_position_in_set(file_id, 1) + + async def test_bot_methods_2_tgs(self, bot, animated_sticker_set): + file_id = animated_sticker_set.stickers[0].file_id + assert await bot.set_sticker_position_in_set(file_id, 1) + + async def test_bot_methods_2_webm(self, bot, video_sticker_set): + file_id = video_sticker_set.stickers[0].file_id + assert await bot.set_sticker_position_in_set(file_id, 1) + + async def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): + assert await bot.set_sticker_set_thumb( + f"test_by_{bot.username}", chat_id, sticker_set_thumb_file + ) + + async def test_bot_methods_3_tgs( + self, bot, chat_id, animated_sticker_file, animated_sticker_set + ): + await asyncio.sleep(1) + animated_test = f"animated_test_by_{bot.username}" + assert await bot.set_sticker_set_thumb(animated_test, chat_id, animated_sticker_file) + file_id = animated_sticker_set.stickers[-1].file_id + # also test with file input and mask + assert await bot.set_sticker_set_thumb(animated_test, chat_id, file_id) + + # TODO: Try the below by creating a custom .webm and not by downloading another pack's thumb + @pytest.mark.skip( + "Skipped for now since Telegram throws a 'File is too big' error " + "regardless of the .webm file size." ) + def test_bot_methods_3_webm(self, bot, chat_id, video_sticker_file, video_sticker_set): + pass + + async def test_bot_methods_4_png(self, bot, sticker_set): + await asyncio.sleep(1) + file_id = sticker_set.stickers[-1].file_id + assert await bot.delete_sticker_from_set(file_id) + + async def test_bot_methods_4_tgs(self, bot, animated_sticker_set): + await asyncio.sleep(1) + file_id = animated_sticker_set.stickers[-1].file_id + assert await bot.delete_sticker_from_set(file_id) + + async def test_bot_methods_4_webm(self, bot, video_sticker_set): + await asyncio.sleep(1) + file_id = video_sticker_set.stickers[-1].file_id + assert await bot.delete_sticker_from_set(file_id) -class TestMaskPosition: +@pytest.fixture(scope="module") +def mask_position(): + return MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) + + +class MaskSpace: point = MaskPosition.EYES x_shift = -1 y_shift = 1 scale = 2 + +class TestMaskPositionNoReq: 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, + "point": MaskSpace.point, + "x_shift": MaskSpace.x_shift, + "y_shift": MaskSpace.y_shift, + "scale": MaskSpace.scale, } mask_position = MaskPosition.de_json(json_dict, bot) assert mask_position.api_kwargs == {} - 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 + assert mask_position.point == MaskSpace.point + assert mask_position.x_shift == MaskSpace.x_shift + assert mask_position.y_shift == MaskSpace.y_shift + assert mask_position.scale == MaskSpace.scale def test_mask_position_to_dict(self, mask_position): mask_position_dict = mask_position.to_dict() @@ -890,10 +873,12 @@ def test_mask_position_to_dict(self, mask_position): assert mask_position_dict["scale"] == mask_position.scale def test_equality(self): - a = MaskPosition(self.point, self.x_shift, self.y_shift, self.scale) - b = MaskPosition(self.point, self.x_shift, self.y_shift, self.scale) - c = MaskPosition(MaskPosition.FOREHEAD, self.x_shift, self.y_shift, self.scale) - d = MaskPosition(self.point, 0, 0, self.scale) + a = MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) + b = MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) + c = MaskPosition( + MaskPosition.FOREHEAD, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale + ) + d = MaskPosition(MaskSpace.point, 0, 0, MaskSpace.scale) e = Audio("", "", 0, None, None) assert a == b @@ -910,7 +895,7 @@ def test_equality(self): assert hash(a) != hash(e) -class TestGetCustomEmojiSticker: +class TestGetCustomEmojiStickerReq: async def test_custom_emoji_sticker(self, bot): # we use the same ID as in test_custom_emoji emoji_sticker_list = await bot.get_custom_emoji_stickers(["6046140249875156202"]) diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index 03cc6e178bc..114253cdca1 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -21,20 +21,20 @@ from telegram import OrderInfo, SuccessfulPayment -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") 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, + Space.currency, + Space.total_amount, + Space.invoice_payload, + Space.telegram_payment_charge_id, + Space.provider_payment_charge_id, + shipping_option_id=Space.shipping_option_id, + order_info=Space.order_info, ) -class TestSuccessfulPayment: +class Space: invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" currency = "EUR" @@ -43,6 +43,8 @@ class TestSuccessfulPayment: telegram_payment_charge_id = "telegram_payment_charge_id" provider_payment_charge_id = "provider_payment_charge_id" + +class TestSuccessfulPaymentNoReq: def test_slot_behaviour(self, successful_payment, mro_slots): inst = successful_payment for attr in inst.__slots__: @@ -51,23 +53,23 @@ def test_slot_behaviour(self, successful_payment, mro_slots): def test_de_json(self, bot): json_dict = { - "invoice_payload": self.invoice_payload, - "shipping_option_id": self.shipping_option_id, - "currency": self.currency, - "total_amount": self.total_amount, - "order_info": self.order_info.to_dict(), - "telegram_payment_charge_id": self.telegram_payment_charge_id, - "provider_payment_charge_id": self.provider_payment_charge_id, + "invoice_payload": Space.invoice_payload, + "shipping_option_id": Space.shipping_option_id, + "currency": Space.currency, + "total_amount": Space.total_amount, + "order_info": Space.order_info.to_dict(), + "telegram_payment_charge_id": Space.telegram_payment_charge_id, + "provider_payment_charge_id": Space.provider_payment_charge_id, } successful_payment = SuccessfulPayment.de_json(json_dict, bot) assert successful_payment.api_kwargs == {} - 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 + assert successful_payment.invoice_payload == Space.invoice_payload + assert successful_payment.shipping_option_id == Space.shipping_option_id + assert successful_payment.currency == Space.currency + assert successful_payment.order_info == Space.order_info + assert successful_payment.telegram_payment_charge_id == Space.telegram_payment_charge_id + assert successful_payment.provider_payment_charge_id == Space.provider_payment_charge_id def test_to_dict(self, successful_payment): successful_payment_dict = successful_payment.to_dict() @@ -90,27 +92,27 @@ def test_to_dict(self, successful_payment): def test_equality(self): a = SuccessfulPayment( - self.currency, - self.total_amount, - self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id, + Space.currency, + Space.total_amount, + Space.invoice_payload, + Space.telegram_payment_charge_id, + Space.provider_payment_charge_id, ) b = SuccessfulPayment( - self.currency, - self.total_amount, - self.invoice_payload, - self.telegram_payment_charge_id, - self.provider_payment_charge_id, + Space.currency, + Space.total_amount, + Space.invoice_payload, + Space.telegram_payment_charge_id, + Space.provider_payment_charge_id, ) c = SuccessfulPayment( - "", 0, "", self.telegram_payment_charge_id, self.provider_payment_charge_id + "", 0, "", Space.telegram_payment_charge_id, Space.provider_payment_charge_id ) d = SuccessfulPayment( - self.currency, - self.total_amount, - self.invoice_payload, - self.telegram_payment_charge_id, + Space.currency, + Space.total_amount, + Space.invoice_payload, + Space.telegram_payment_charge_id, "", ) diff --git a/tests/test_update.py b/tests/test_update.py index 20cce556ed1..cf244ee35de 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -96,14 +96,16 @@ ids = all_types + ("callback_query_without_message",) -@pytest.fixture(params=params, ids=ids) +@pytest.fixture(scope="module", params=params, ids=ids) def update(request): - return Update(update_id=TestUpdate.update_id, **request.param) + return Update(update_id=Space.update_id, **request.param) -class TestUpdate: +class Space: update_id = 868573637 + +class TestUpdateNoReq: def test_slot_behaviour(self, update, mro_slots): for attr in update.__slots__: assert getattr(update, attr, "err") != "err", f"got extra slot '{attr}'" @@ -111,13 +113,13 @@ def test_slot_behaviour(self, update, mro_slots): @pytest.mark.parametrize("paramdict", argvalues=params, ids=ids) def test_de_json(self, bot, paramdict): - json_dict = {"update_id": TestUpdate.update_id} + json_dict = {"update_id": Space.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) assert update.api_kwargs == {} - assert update.update_id == self.update_id + assert update.update_id == Space.update_id # Make sure only one thing in the update (other than update_id) is not None i = 0 @@ -189,11 +191,11 @@ def test_effective_message(self, update): assert eff_message is None def test_equality(self): - a = Update(self.update_id, message=message) - b = Update(self.update_id, message=message) - c = Update(self.update_id) + a = Update(Space.update_id, message=message) + b = Update(Space.update_id, message=message) + c = Update(Space.update_id) d = Update(0, message=message) - e = User(self.update_id, "", False) + e = User(Space.update_id, "", False) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_user.py b/tests/test_user.py index 56c3c6eadf4..c547618b6cc 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -30,41 +30,41 @@ @pytest.fixture(scope="function") def json_dict(): return { - "id": TestUser.id_, - "is_bot": TestUser.is_bot, - "first_name": TestUser.first_name, - "last_name": TestUser.last_name, - "username": TestUser.username, - "language_code": TestUser.language_code, - "can_join_groups": TestUser.can_join_groups, - "can_read_all_group_messages": TestUser.can_read_all_group_messages, - "supports_inline_queries": TestUser.supports_inline_queries, - "is_premium": TestUser.is_premium, - "added_to_attachment_menu": TestUser.added_to_attachment_menu, + "id": Space.id_, + "is_bot": Space.is_bot, + "first_name": Space.first_name, + "last_name": Space.last_name, + "username": Space.username, + "language_code": Space.language_code, + "can_join_groups": Space.can_join_groups, + "can_read_all_group_messages": Space.can_read_all_group_messages, + "supports_inline_queries": Space.supports_inline_queries, + "is_premium": Space.is_premium, + "added_to_attachment_menu": Space.added_to_attachment_menu, } -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def user(bot): user = User( - id=TestUser.id_, - first_name=TestUser.first_name, - is_bot=TestUser.is_bot, - last_name=TestUser.last_name, - username=TestUser.username, - language_code=TestUser.language_code, - can_join_groups=TestUser.can_join_groups, - can_read_all_group_messages=TestUser.can_read_all_group_messages, - supports_inline_queries=TestUser.supports_inline_queries, - is_premium=TestUser.is_premium, - added_to_attachment_menu=TestUser.added_to_attachment_menu, + id=Space.id_, + first_name=Space.first_name, + is_bot=Space.is_bot, + last_name=Space.last_name, + username=Space.username, + language_code=Space.language_code, + can_join_groups=Space.can_join_groups, + can_read_all_group_messages=Space.can_read_all_group_messages, + supports_inline_queries=Space.supports_inline_queries, + is_premium=Space.is_premium, + added_to_attachment_menu=Space.added_to_attachment_menu, ) user.set_bot(bot) user._unfreeze() return user -class TestUser: +class Space: id_ = 1 is_bot = True first_name = "first\u2022name" @@ -77,6 +77,8 @@ class TestUser: is_premium = True added_to_attachment_menu = False + +class TestUserNoReq: def test_slot_behaviour(self, user, mro_slots): for attr in user.__slots__: assert getattr(user, attr, "err") != "err", f"got extra slot '{attr}'" @@ -86,17 +88,17 @@ def test_de_json(self, json_dict, bot): user = User.de_json(json_dict, bot) assert user.api_kwargs == {} - assert user.id == self.id_ - assert user.is_bot == self.is_bot - 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 - assert user.can_join_groups == self.can_join_groups - assert user.can_read_all_group_messages == self.can_read_all_group_messages - assert user.supports_inline_queries == self.supports_inline_queries - assert user.is_premium == self.is_premium - assert user.added_to_attachment_menu == self.added_to_attachment_menu + assert user.id == Space.id_ + assert user.is_bot == Space.is_bot + assert user.first_name == Space.first_name + assert user.last_name == Space.last_name + assert user.username == Space.username + assert user.language_code == Space.language_code + assert user.can_join_groups == Space.can_join_groups + assert user.can_read_all_group_messages == Space.can_read_all_group_messages + assert user.supports_inline_queries == Space.supports_inline_queries + assert user.is_premium == Space.is_premium + assert user.added_to_attachment_menu == Space.added_to_attachment_menu def test_de_json_without_username(self, json_dict, bot): del json_dict["username"] @@ -104,17 +106,17 @@ def test_de_json_without_username(self, json_dict, bot): user = User.de_json(json_dict, bot) assert user.api_kwargs == {} - assert user.id == self.id_ - assert user.is_bot == self.is_bot - assert user.first_name == self.first_name - assert user.last_name == self.last_name + assert user.id == Space.id_ + assert user.is_bot == Space.is_bot + assert user.first_name == Space.first_name + assert user.last_name == Space.last_name assert user.username is None - assert user.language_code == self.language_code - assert user.can_join_groups == self.can_join_groups - assert user.can_read_all_group_messages == self.can_read_all_group_messages - assert user.supports_inline_queries == self.supports_inline_queries - assert user.is_premium == self.is_premium - assert user.added_to_attachment_menu == self.added_to_attachment_menu + assert user.language_code == Space.language_code + assert user.can_join_groups == Space.can_join_groups + assert user.can_read_all_group_messages == Space.can_read_all_group_messages + assert user.supports_inline_queries == Space.supports_inline_queries + assert user.is_premium == Space.is_premium + assert user.added_to_attachment_menu == Space.added_to_attachment_menu def test_de_json_without_username_and_last_name(self, json_dict, bot): del json_dict["username"] @@ -123,17 +125,17 @@ def test_de_json_without_username_and_last_name(self, json_dict, bot): user = User.de_json(json_dict, bot) assert user.api_kwargs == {} - assert user.id == self.id_ - assert user.is_bot == self.is_bot - assert user.first_name == self.first_name + assert user.id == Space.id_ + assert user.is_bot == Space.is_bot + assert user.first_name == Space.first_name assert user.last_name is None assert user.username is None - assert user.language_code == self.language_code - assert user.can_join_groups == self.can_join_groups - assert user.can_read_all_group_messages == self.can_read_all_group_messages - assert user.supports_inline_queries == self.supports_inline_queries - assert user.is_premium == self.is_premium - assert user.added_to_attachment_menu == self.added_to_attachment_menu + assert user.language_code == Space.language_code + assert user.can_join_groups == Space.can_join_groups + assert user.can_read_all_group_messages == Space.can_read_all_group_messages + assert user.supports_inline_queries == Space.supports_inline_queries + assert user.is_premium == Space.is_premium + assert user.added_to_attachment_menu == Space.added_to_attachment_menu def test_name(self, user): assert user.name == "@username" @@ -141,7 +143,7 @@ def test_name(self, user): assert user.name == "first\u2022name last\u2022name" user.last_name = None assert user.name == "first\u2022name" - user.username = self.username + user.username = Space.username assert user.name == "@username" def test_full_name(self, user): @@ -562,11 +564,11 @@ async def test_mention_markdown_v2(self, user): assert user.mention_markdown_v2(user.username) == expected.format(user.username, user.id) def test_equality(self): - a = User(self.id_, self.first_name, self.is_bot, self.last_name) - b = User(self.id_, self.first_name, self.is_bot, self.last_name) - c = User(self.id_, self.first_name, self.is_bot) - d = User(0, self.first_name, self.is_bot, self.last_name) - e = Update(self.id_) + a = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) + b = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) + c = User(Space.id_, Space.first_name, Space.is_bot) + d = User(0, Space.first_name, Space.is_bot, Space.last_name) + e = Update(Space.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index c8edb0daebe..b855e7512dd 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -19,7 +19,7 @@ from telegram import PhotoSize, UserProfilePhotos -class TestUserProfilePhotos: +class Space: total_count = 2 photos = [ [ @@ -32,21 +32,23 @@ class TestUserProfilePhotos: ], ] + +class TestUserProfilePhotosNoReq: def test_slot_behaviour(self, mro_slots): - inst = UserProfilePhotos(self.total_count, self.photos) + inst = UserProfilePhotos(Space.total_count, Space.photos) for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json(self, bot): - json_dict = {"total_count": 2, "photos": [[y.to_dict() for y in x] for x in self.photos]} + json_dict = {"total_count": 2, "photos": [[y.to_dict() for y in x] for x in Space.photos]} user_profile_photos = UserProfilePhotos.de_json(json_dict, bot) assert user_profile_photos.api_kwargs == {} - assert user_profile_photos.total_count == self.total_count - assert user_profile_photos.photos == tuple(tuple(p) for p in self.photos) + assert user_profile_photos.total_count == Space.total_count + assert user_profile_photos.photos == tuple(tuple(p) for p in Space.photos) def test_to_dict(self): - user_profile_photos = UserProfilePhotos(self.total_count, self.photos) + user_profile_photos = UserProfilePhotos(Space.total_count, Space.photos) user_profile_photos_dict = user_profile_photos.to_dict() assert user_profile_photos_dict["total_count"] == user_profile_photos.total_count for ix, x in enumerate(user_profile_photos_dict["photos"]): @@ -54,9 +56,9 @@ def test_to_dict(self): assert y == user_profile_photos.photos[ix][iy].to_dict() def test_equality(self): - a = UserProfilePhotos(2, self.photos) - b = UserProfilePhotos(2, self.photos) - c = UserProfilePhotos(1, [self.photos[0]]) + a = UserProfilePhotos(2, Space.photos) + b = UserProfilePhotos(2, Space.photos) + c = UserProfilePhotos(1, [Space.photos[0]]) d = PhotoSize("file_id1", "unique_id", 512, 512) assert a == b diff --git a/tests/test_venue.py b/tests/test_venue.py index 53aca6f6121..6088bbfcaf6 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -23,20 +23,20 @@ from telegram.request import RequestData -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def venue(): return Venue( - TestVenue.location, - TestVenue.title, - TestVenue.address, - foursquare_id=TestVenue.foursquare_id, - foursquare_type=TestVenue.foursquare_type, - google_place_id=TestVenue.google_place_id, - google_place_type=TestVenue.google_place_type, + Space.location, + Space.title, + Space.address, + foursquare_id=Space.foursquare_id, + foursquare_type=Space.foursquare_type, + google_place_id=Space.google_place_id, + google_place_type=Space.google_place_type, ) -class TestVenue: +class Space: location = Location(longitude=-46.788279, latitude=-23.691288) title = "title" address = "address" @@ -45,6 +45,8 @@ class TestVenue: google_place_id = "google place id" google_place_type = "google place type" + +class TestVenueNoReq: def test_slot_behaviour(self, venue, mro_slots): for attr in venue.__slots__: assert getattr(venue, attr, "err") != "err", f"got extra slot '{attr}'" @@ -52,85 +54,43 @@ def test_slot_behaviour(self, venue, mro_slots): def test_de_json(self, bot): json_dict = { - "location": TestVenue.location.to_dict(), - "title": TestVenue.title, - "address": TestVenue.address, - "foursquare_id": TestVenue.foursquare_id, - "foursquare_type": TestVenue.foursquare_type, - "google_place_id": TestVenue.google_place_id, - "google_place_type": TestVenue.google_place_type, + "location": Space.location.to_dict(), + "title": Space.title, + "address": Space.address, + "foursquare_id": Space.foursquare_id, + "foursquare_type": Space.foursquare_type, + "google_place_id": Space.google_place_id, + "google_place_type": Space.google_place_type, } venue = Venue.de_json(json_dict, bot) assert venue.api_kwargs == {} - assert venue.location == self.location - assert venue.title == self.title - assert venue.address == self.address - assert venue.foursquare_id == self.foursquare_id - assert venue.foursquare_type == self.foursquare_type - assert venue.google_place_id == self.google_place_id - assert venue.google_place_type == self.google_place_type + assert venue.location == Space.location + assert venue.title == Space.title + assert venue.address == Space.address + assert venue.foursquare_id == Space.foursquare_id + assert venue.foursquare_type == Space.foursquare_type + assert venue.google_place_id == Space.google_place_id + assert venue.google_place_type == Space.google_place_type async def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters return ( - data["longitude"] == str(self.location.longitude) - and data["latitude"] == str(self.location.latitude) - and data["title"] == self.title - and data["address"] == self.address - and data["foursquare_id"] == self.foursquare_id - and data["foursquare_type"] == self.foursquare_type - and data["google_place_id"] == self.google_place_id - and data["google_place_type"] == self.google_place_type + data["longitude"] == str(Space.location.longitude) + and data["latitude"] == str(Space.location.latitude) + and data["title"] == Space.title + and data["address"] == Space.address + and data["foursquare_id"] == Space.foursquare_id + and data["foursquare_type"] == Space.foursquare_type + and data["google_place_id"] == Space.google_place_id + and data["google_place_type"] == Space.google_place_type ) monkeypatch.setattr(bot.request, "post", make_assertion) message = await bot.send_venue(chat_id, venue=venue) assert message - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize( - "default_bot,custom", - [ - ({"allow_sending_without_reply": True}, None), - ({"allow_sending_without_reply": False}, None), - ({"allow_sending_without_reply": False}, True), - ], - indirect=["default_bot"], - ) - async def test_send_venue_default_allow_sending_without_reply( - self, default_bot, chat_id, venue, custom - ): - reply_to_message = await default_bot.send_message(chat_id, "test") - await reply_to_message.delete() - if custom is not None: - message = await default_bot.send_venue( - chat_id, - venue=venue, - allow_sending_without_reply=custom, - reply_to_message_id=reply_to_message.message_id, - ) - assert message.reply_to_message is None - elif default_bot.defaults.allow_sending_without_reply: - message = await default_bot.send_venue( - chat_id, venue=venue, reply_to_message_id=reply_to_message.message_id - ) - assert message.reply_to_message is None - else: - with pytest.raises(BadRequest, match="message not found"): - await default_bot.send_venue( - chat_id, venue=venue, reply_to_message_id=reply_to_message.message_id - ) - - @pytest.mark.flaky(3, 1) - @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) - async def test_send_venue_default_protect_content(self, default_bot, chat_id, venue): - protected = await default_bot.send_venue(chat_id, venue=venue) - assert protected.has_protected_content - unprotected = await default_bot.send_venue(chat_id, venue=venue, protect_content=False) - assert not unprotected.has_protected_content - async def test_send_venue_without_required(self, bot, chat_id): with pytest.raises(ValueError, match="Either venue or latitude, longitude, address and"): await bot.send_venue(chat_id=chat_id) @@ -159,11 +119,11 @@ def test_to_dict(self, venue): assert venue_dict["google_place_type"] == venue.google_place_type def test_equality(self): - 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) + a = Venue(Location(0, 0), Space.title, Space.address) + b = Venue(Location(0, 0), Space.title, Space.address) + c = Venue(Location(0, 0), Space.title, "") + d = Venue(Location(0, 1), Space.title, Space.address) + d2 = Venue(Location(0, 0), "", Space.address) assert a == b assert hash(a) == hash(b) @@ -177,3 +137,45 @@ def test_equality(self): assert a != d2 assert hash(a) != hash(d2) + + +class TestVenueReq: + @pytest.mark.parametrize( + "default_bot,custom", + [ + ({"allow_sending_without_reply": True}, None), + ({"allow_sending_without_reply": False}, None), + ({"allow_sending_without_reply": False}, True), + ], + indirect=["default_bot"], + ) + async def test_send_venue_default_allow_sending_without_reply( + self, default_bot, chat_id, venue, custom + ): + reply_to_message = await default_bot.send_message(chat_id, "test") + await reply_to_message.delete() + if custom is not None: + message = await default_bot.send_venue( + chat_id, + venue=venue, + allow_sending_without_reply=custom, + reply_to_message_id=reply_to_message.message_id, + ) + assert message.reply_to_message is None + elif default_bot.defaults.allow_sending_without_reply: + message = await default_bot.send_venue( + chat_id, venue=venue, reply_to_message_id=reply_to_message.message_id + ) + assert message.reply_to_message is None + else: + with pytest.raises(BadRequest, match="message not found"): + await default_bot.send_venue( + chat_id, venue=venue, reply_to_message_id=reply_to_message.message_id + ) + + @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) + async def test_send_venue_default_protect_content(self, default_bot, chat_id, venue): + protected = await default_bot.send_venue(chat_id, venue=venue) + assert protected.has_protected_content + unprotected = await default_bot.send_venue(chat_id, venue=venue, protect_content=False) + assert not unprotected.has_protected_content diff --git a/tests/test_video.py b/tests/test_video.py index 80f68cd57bd..a3b7f5c1471 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -40,13 +40,13 @@ def video_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def video(bot, chat_id): with data_file("telegram.mp4").open("rb") as f: return (await bot.send_video(chat_id, video=f, read_timeout=50)).video -class TestVideo: +class Space: width = 360 height = 640 duration = 5 @@ -54,17 +54,16 @@ class TestVideo: mime_type = "video/mp4" supports_streaming = True file_name = "telegram.mp4" - thumb_width = 180 thumb_height = 320 thumb_file_size = 1767 - caption = "VideoTest - *Caption*" video_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.mp4" - video_file_id = "5a3128a4d2a04750b5b58397f3b5e812" video_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" + +class TestVideoNoReq: def test_slot_behaviour(self, video, mro_slots): for attr in video.__slots__: assert getattr(video, attr, "err") != "err", f"got extra slot '{attr}'" @@ -85,20 +84,132 @@ def test_creation(self, video): assert video.thumb.file_unique_id != "" 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 + assert video.width == Space.width + assert video.height == Space.height + assert video.duration == Space.duration + assert video.file_size == Space.file_size + assert video.mime_type == Space.mime_type + + async def test_send_video_custom_filename(self, bot, chat_id, video_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_video(chat_id, video_file, filename="custom_filename") + + async def test_send_with_video(self, monkeypatch, bot, chat_id, video): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["video"] == video.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_video(chat_id, video=video) + assert message + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_video_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("video") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("video"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_video(chat_id, file, thumb=file) + assert test_flag + finally: + bot._local_mode = False + + def test_de_json(self, bot): + json_dict = { + "file_id": Space.video_file_id, + "file_unique_id": Space.video_file_unique_id, + "width": Space.width, + "height": Space.height, + "duration": Space.duration, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + "file_name": Space.file_name, + } + json_video = Video.de_json(json_dict, bot) + assert json_video.api_kwargs == {} + + assert json_video.file_id == Space.video_file_id + assert json_video.file_unique_id == Space.video_file_unique_id + assert json_video.width == Space.width + assert json_video.height == Space.height + assert json_video.duration == Space.duration + assert json_video.mime_type == Space.mime_type + assert json_video.file_size == Space.file_size + assert json_video.file_name == Space.file_name + + 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["file_unique_id"] == video.file_unique_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 + assert video_dict["file_name"] == video.file_name + + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_video(chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, video): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == video.file_id + + assert check_shortcut_signature(Video.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(video.get_file, video.get_bot(), "get_file") + assert await check_defaults_handling(video.get_file, video.get_bot()) + + monkeypatch.setattr(video.get_bot(), "get_file", make_assertion) + assert await video.get_file() + + def test_equality(self, video): + a = Video(video.file_id, video.file_unique_id, Space.width, Space.height, Space.duration) + b = Video("", video.file_unique_id, Space.width, Space.height, Space.duration) + c = Video(video.file_id, video.file_unique_id, 0, 0, 0) + d = Video("", "", Space.width, Space.height, Space.duration) + e = Voice(video.file_id, video.file_unique_id, Space.duration) + + 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) + - @pytest.mark.flaky(3, 1) +class TestVideoReq: async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): message = await bot.send_video( chat_id, video_file, - duration=self.duration, - caption=self.caption, - supports_streaming=self.supports_streaming, + duration=Space.duration, + caption=Space.caption, + supports_streaming=Space.supports_streaming, disable_notification=False, protect_content=True, width=video.width, @@ -117,25 +228,15 @@ async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): assert message.video.duration == video.duration assert message.video.file_size == video.file_size - assert message.caption == self.caption.replace("*", "") + assert message.caption == Space.caption.replace("*", "") - assert message.video.thumb.file_size == self.thumb_file_size - assert message.video.thumb.width == self.thumb_width - assert message.video.thumb.height == self.thumb_height + assert message.video.thumb.file_size == Space.thumb_file_size + assert message.video.thumb.width == Space.thumb_width + assert message.video.thumb.height == Space.thumb_height - assert message.video.file_name == self.file_name + assert message.video.file_name == Space.file_name assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_send_video_custom_filename(self, bot, chat_id, video_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_video(chat_id, video_file, filename="custom_filename") - - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, video): path = Path("telegram.mp4") if path.is_file(): @@ -143,7 +244,7 @@ async def test_get_and_download(self, bot, video): new_file = await bot.get_file(video.file_id) - assert new_file.file_size == self.file_size + assert new_file.file_size == Space.file_size assert new_file.file_id == video.file_id assert new_file.file_unique_id == video.file_unique_id assert new_file.file_path.startswith("https://") @@ -152,9 +253,8 @@ async def test_get_and_download(self, bot, video): assert path.is_file() - @pytest.mark.flaky(3, 1) async def test_send_mp4_file_url(self, bot, chat_id, video): - message = await bot.send_video(chat_id, self.video_file_url, caption=self.caption) + message = await bot.send_video(chat_id, Space.video_file_url, caption=Space.caption) assert isinstance(message.video, Video) assert isinstance(message.video.file_id, str) @@ -171,13 +271,12 @@ async def test_send_mp4_file_url(self, bot, chat_id, video): assert isinstance(message.video.thumb.file_unique_id, str) assert message.video.thumb.file_id != "" assert message.video.thumb.file_unique_id != "" - assert message.video.thumb.width == 51 # This seems odd that it's not self.thumb_width + assert message.video.thumb.width == 51 # This seems odd that it's not Space.thumb_width assert message.video.thumb.height == 90 # Ditto assert message.video.thumb.file_size == 645 # same - assert message.caption == self.caption + assert message.caption == Space.caption - @pytest.mark.flaky(3, 1) async def test_send_video_caption_entities(self, bot, chat_id, video): test_string = "Italic Bold Code" entities = [ @@ -192,21 +291,10 @@ async def test_send_video_caption_entities(self, bot, chat_id, video): assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, video): message = await bot.send_video(chat_id, video.file_id) - assert message.video == video - async def test_send_with_video(self, monkeypatch, bot, chat_id, video): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["video"] == video.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_video(chat_id, video=video) - assert message - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_video_default_parse_mode_1(self, default_bot, chat_id, video): test_string = "Italic Bold Code" @@ -216,7 +304,6 @@ async def test_send_video_default_parse_mode_1(self, default_bot, chat_id, video assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_video_default_parse_mode_2(self, default_bot, chat_id, video): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -227,7 +314,6 @@ async def test_send_video_default_parse_mode_2(self, default_bot, chat_id, video assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_video_default_parse_mode_3(self, default_bot, chat_id, video): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -238,7 +324,6 @@ async def test_send_video_default_parse_mode_3(self, default_bot, chat_id, video assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_video_default_protect_content(self, chat_id, default_bot, video): protected = await default_bot.send_video(chat_id, video) @@ -246,31 +331,6 @@ async def test_send_video_default_protect_content(self, chat_id, default_bot, vi unprotected = await default_bot.send_video(chat_id, video, protect_content=False) assert not unprotected.has_protected_content - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_video_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("video") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("video"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_video(chat_id, file, thumb=file) - assert test_flag - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -304,83 +364,10 @@ async def test_send_video_default_allow_sending_without_reply( chat_id, video, reply_to_message_id=reply_to_message.message_id ) - def test_de_json(self, bot): - json_dict = { - "file_id": self.video_file_id, - "file_unique_id": self.video_file_unique_id, - "width": self.width, - "height": self.height, - "duration": self.duration, - "mime_type": self.mime_type, - "file_size": self.file_size, - "file_name": self.file_name, - } - json_video = Video.de_json(json_dict, bot) - assert json_video.api_kwargs == {} - - assert json_video.file_id == self.video_file_id - assert json_video.file_unique_id == self.video_file_unique_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 - assert json_video.file_name == self.file_name - - 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["file_unique_id"] == video.file_unique_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 - assert video_dict["file_name"] == video.file_name - - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_video(chat_id, open(os.devnull, "rb")) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_video(chat_id, "") - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_video(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, video): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == video.file_id - - assert check_shortcut_signature(Video.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(video.get_file, video.get_bot(), "get_file") - assert await check_defaults_handling(video.get_file, video.get_bot()) - - monkeypatch.setattr(video.get_bot(), "get_file", make_assertion) - assert await video.get_file() - - def test_equality(self, video): - a = Video(video.file_id, video.file_unique_id, self.width, self.height, self.duration) - b = Video("", video.file_unique_id, self.width, self.height, self.duration) - c = Video(video.file_id, video.file_unique_id, 0, 0, 0) - d = Video("", "", self.width, self.height, self.duration) - e = Voice(video.file_id, video.file_unique_id, self.duration) - - 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_videochat.py b/tests/test_videochat.py index 81b36f9b852..9717bb26df4 100644 --- a/tests/test_videochat.py +++ b/tests/test_videochat.py @@ -30,17 +30,17 @@ from telegram._utils.datetime import to_timestamp -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def user1(): return User(first_name="Misses Test", id=123, is_bot=False) -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def user2(): return User(first_name="Mister Test", id=124, is_bot=False) -class TestVideoChatStarted: +class TestVideoChatStartedNoReq: def test_slot_behaviour(self, mro_slots): action = VideoChatStarted() for attr in action.__slots__: @@ -58,7 +58,7 @@ def test_to_dict(self): assert video_chat_dict == {} -class TestVideoChatEnded: +class TestVideoChatEndedNoReq: duration = 100 def test_slot_behaviour(self, mro_slots): @@ -97,7 +97,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestVideoChatParticipantsInvited: +class TestVideoChatParticipantsInvitedNoReq: def test_slot_behaviour(self, mro_slots, user1): action = VideoChatParticipantsInvited([user1]) for attr in action.__slots__: @@ -148,7 +148,7 @@ def test_equality(self, user1, user2): assert hash(a) != hash(e) -class TestVideoChatScheduled: +class TestVideoChatScheduledNoReq: start_date = dtm.datetime.now(dtm.timezone.utc) def test_slot_behaviour(self, mro_slots): diff --git a/tests/test_videonote.py b/tests/test_videonote.py index 59a62d092d8..b991ffe576f 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -39,25 +39,25 @@ def video_note_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def video_note(bot, chat_id): with data_file("telegram2.mp4").open("rb") as f: return (await bot.send_video_note(chat_id, video_note=f, read_timeout=50)).video_note -class TestVideoNote: +class Space: length = 240 duration = 3 file_size = 132084 - thumb_width = 240 thumb_height = 240 thumb_file_size = 11547 - caption = "VideoNoteTest - Caption" videonote_file_id = "5a3128a4d2a04750b5b58397f3b5e812" videonote_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" + +class TestVideoNoteNoReq: def test_slot_behaviour(self, video_note, mro_slots): for attr in video_note.__slots__: assert getattr(video_note, attr, "err") != "err", f"got extra slot '{attr}'" @@ -78,37 +78,10 @@ def test_creation(self, video_note): assert video_note.thumb.file_unique_id != "" 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 + assert video_note.length == Space.length + assert video_note.duration == Space.duration + assert video_note.file_size == Space.file_size - @pytest.mark.flaky(3, 1) - async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): - message = await bot.send_video_note( - chat_id, - video_note_file, - duration=self.duration, - length=self.length, - disable_notification=False, - protect_content=True, - thumb=thumb_file, - ) - - assert isinstance(message.video_note, VideoNote) - assert isinstance(message.video_note.file_id, str) - assert isinstance(message.video_note.file_unique_id, str) - assert message.video_note.file_id != "" - assert message.video_note.file_unique_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 message.video_note.thumb.file_size == self.thumb_file_size - assert message.video_note.thumb.width == self.thumb_width - assert message.video_note.thumb.height == self.thumb_height - assert message.has_protected_content - - @pytest.mark.flaky(3, 1) async def test_send_video_note_custom_filename( self, bot, chat_id, video_note_file, monkeypatch ): @@ -119,29 +92,6 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.send_video_note(chat_id, video_note_file, filename="custom_filename") - @pytest.mark.flaky(3, 1) - async def test_get_and_download(self, bot, video_note): - path = Path("telegram2.mp4") - if path.is_file(): - path.unlink() - - new_file = await bot.get_file(video_note.file_id) - - assert new_file.file_size == self.file_size - assert new_file.file_id == video_note.file_id - assert new_file.file_unique_id == video_note.file_unique_id - assert new_file.file_path.startswith("https://") - - await new_file.download_to_drive("telegram2.mp4") - - assert path.is_file() - - @pytest.mark.flaky(3, 1) - async def test_resend(self, bot, chat_id, video_note): - message = await bot.send_video_note(chat_id, video_note.file_id) - - assert message.video_note == video_note - async def test_send_with_video_note(self, monkeypatch, bot, chat_id, video_note): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.json_parameters["video_note"] == video_note.file_id @@ -152,20 +102,20 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): def test_de_json(self, bot): json_dict = { - "file_id": self.videonote_file_id, - "file_unique_id": self.videonote_file_unique_id, - "length": self.length, - "duration": self.duration, - "file_size": self.file_size, + "file_id": Space.videonote_file_id, + "file_unique_id": Space.videonote_file_unique_id, + "length": Space.length, + "duration": Space.duration, + "file_size": Space.file_size, } json_video_note = VideoNote.de_json(json_dict, bot) assert json_video_note.api_kwargs == {} - assert json_video_note.file_id == self.videonote_file_id - assert json_video_note.file_unique_id == self.videonote_file_unique_id - assert json_video_note.length == self.length - assert json_video_note.duration == self.duration - assert json_video_note.file_size == self.file_size + assert json_video_note.file_id == Space.videonote_file_id + assert json_video_note.file_unique_id == Space.videonote_file_unique_id + assert json_video_note.length == Space.length + assert json_video_note.duration == Space.duration + assert json_video_note.file_size == Space.file_size def test_to_dict(self, video_note): video_note_dict = video_note.to_dict() @@ -203,7 +153,88 @@ async def make_assertion(_, data, *args, **kwargs): finally: bot._local_mode = False - @pytest.mark.flaky(3, 1) + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_video_note(chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, video_note): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == video_note.file_id + + assert check_shortcut_signature(VideoNote.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(video_note.get_file, video_note.get_bot(), "get_file") + assert await check_defaults_handling(video_note.get_file, video_note.get_bot()) + + monkeypatch.setattr(video_note.get_bot(), "get_file", make_assertion) + assert await video_note.get_file() + + def test_equality(self, video_note): + a = VideoNote(video_note.file_id, video_note.file_unique_id, Space.length, Space.duration) + b = VideoNote("", video_note.file_unique_id, Space.length, Space.duration) + c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0) + d = VideoNote("", "", Space.length, Space.duration) + e = Voice(video_note.file_id, video_note.file_unique_id, Space.duration) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + +class TestVideoNoteReq: + async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): + message = await bot.send_video_note( + chat_id, + video_note_file, + duration=Space.duration, + length=Space.length, + disable_notification=False, + protect_content=True, + thumb=thumb_file, + ) + + assert isinstance(message.video_note, VideoNote) + assert isinstance(message.video_note.file_id, str) + assert isinstance(message.video_note.file_unique_id, str) + assert message.video_note.file_id != "" + assert message.video_note.file_unique_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 message.video_note.thumb.file_size == Space.thumb_file_size + assert message.video_note.thumb.width == Space.thumb_width + assert message.video_note.thumb.height == Space.thumb_height + assert message.has_protected_content + + async def test_get_and_download(self, bot, video_note): + path = Path("telegram2.mp4") + if path.is_file(): + path.unlink() + + new_file = await bot.get_file(video_note.file_id) + + assert new_file.file_size == Space.file_size + assert new_file.file_id == video_note.file_id + assert new_file.file_unique_id == video_note.file_unique_id + assert new_file.file_path.startswith("https://") + + await new_file.download_to_drive("telegram2.mp4") + + assert path.is_file() + + async def test_resend(self, bot, chat_id, video_note): + message = await bot.send_video_note(chat_id, video_note.file_id) + assert message.video_note == video_note + @pytest.mark.parametrize( "default_bot,custom", [ @@ -237,7 +268,6 @@ async def test_send_video_note_default_allow_sending_without_reply( chat_id, video_note, reply_to_message_id=reply_to_message.message_id ) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_video_note_default_protect_content(self, chat_id, default_bot, video_note): protected = await default_bot.send_video_note(chat_id, video_note) @@ -245,47 +275,10 @@ async def test_send_video_note_default_protect_content(self, chat_id, default_bo unprotected = await default_bot.send_video_note(chat_id, video_note, protect_content=False) assert not unprotected.has_protected_content - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_video_note(chat_id, open(os.devnull, "rb")) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_video_note(chat_id, "") - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_video_note(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, video_note): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == video_note.file_id - - assert check_shortcut_signature(VideoNote.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(video_note.get_file, video_note.get_bot(), "get_file") - assert await check_defaults_handling(video_note.get_file, video_note.get_bot()) - - monkeypatch.setattr(video_note.get_bot(), "get_file", make_assertion) - assert await video_note.get_file() - - def test_equality(self, video_note): - a = VideoNote(video_note.file_id, video_note.file_unique_id, self.length, self.duration) - b = VideoNote("", video_note.file_unique_id, self.length, self.duration) - c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0) - d = VideoNote("", "", self.length, self.duration) - e = Voice(video_note.file_id, video_note.file_unique_id, self.duration) - - 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_voice.py b/tests/test_voice.py index 722fdb17593..d765d3fa509 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -40,23 +40,23 @@ def voice_file(): f.close() -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") async def voice(bot, chat_id): with data_file("telegram.ogg").open("rb") as f: return (await bot.send_voice(chat_id, voice=f, read_timeout=50)).voice -class TestVoice: +class Space: duration = 3 mime_type = "audio/ogg" file_size = 9199 - caption = "Test *voice*" voice_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.ogg" - voice_file_id = "5a3128a4d2a04750b5b58397f3b5e812" voice_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" + +class TestVoiceNoReq: def test_slot_behaviour(self, voice, mro_slots): for attr in voice.__slots__: assert getattr(voice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -71,17 +71,118 @@ async def test_creation(self, voice): assert voice.file_unique_id != "" 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 + assert voice.duration == Space.duration + assert voice.mime_type == Space.mime_type + assert voice.file_size == Space.file_size + + async def test_send_voice_custom_filename(self, bot, chat_id, voice_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_voice(chat_id, voice_file, filename="custom_filename") + + async def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["voice"] == voice.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_voice(chat_id, voice=voice) + assert message + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_voice_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("voice") == expected + else: + test_flag = isinstance(data.get("voice"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_voice(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + + def test_de_json(self, bot): + json_dict = { + "file_id": Space.voice_file_id, + "file_unique_id": Space.voice_file_unique_id, + "duration": Space.duration, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + } + json_voice = Voice.de_json(json_dict, bot) + assert json_voice.api_kwargs == {} + + assert json_voice.file_id == Space.voice_file_id + assert json_voice.file_unique_id == Space.voice_file_unique_id + assert json_voice.duration == Space.duration + assert json_voice.mime_type == Space.mime_type + assert json_voice.file_size == Space.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["file_unique_id"] == voice.file_unique_id + assert voice_dict["duration"] == voice.duration + assert voice_dict["mime_type"] == voice.mime_type + assert voice_dict["file_size"] == voice.file_size + + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.sendVoice(chat_id) + + async def test_get_file_instance_method(self, monkeypatch, voice): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == voice.file_id + + assert check_shortcut_signature(Voice.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(voice.get_file, voice.get_bot(), "get_file") + assert await check_defaults_handling(voice.get_file, voice.get_bot()) + + monkeypatch.setattr(voice.get_bot(), "get_file", make_assertion) + assert await voice.get_file() + + def test_equality(self, voice): + a = Voice(voice.file_id, voice.file_unique_id, Space.duration) + b = Voice("", voice.file_unique_id, Space.duration) + c = Voice(voice.file_id, voice.file_unique_id, 0) + d = Voice("", "", Space.duration) + e = Audio(voice.file_id, voice.file_unique_id, Space.duration) + + 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) + - @pytest.mark.flaky(3, 1) +class TestVoiceReq: async def test_send_all_args(self, bot, chat_id, voice_file, voice): message = await bot.send_voice( chat_id, voice_file, - duration=self.duration, - caption=self.caption, + duration=Space.duration, + caption=Space.caption, disable_notification=False, protect_content=True, parse_mode="Markdown", @@ -95,19 +196,9 @@ async def test_send_all_args(self, bot, chat_id, voice_file, voice): 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.replace("*", "") + assert message.caption == Space.caption.replace("*", "") assert message.has_protected_content - @pytest.mark.flaky(3, 1) - async def test_send_voice_custom_filename(self, bot, chat_id, voice_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_voice(chat_id, voice_file, filename="custom_filename") - - @pytest.mark.flaky(3, 1) async def test_get_and_download(self, bot, voice): path = Path("telegram.ogg") if path.is_file(): @@ -124,9 +215,8 @@ async def test_get_and_download(self, bot, voice): assert path.is_file() - @pytest.mark.flaky(3, 1) async def test_send_ogg_url_file(self, bot, chat_id, voice): - message = await bot.sendVoice(chat_id, self.voice_file_url, duration=self.duration) + message = await bot.sendVoice(chat_id, Space.voice_file_url, duration=Space.duration) assert isinstance(message.voice, Voice) assert isinstance(message.voice.file_id, str) @@ -137,21 +227,11 @@ async def test_send_ogg_url_file(self, bot, chat_id, voice): assert message.voice.mime_type == voice.mime_type assert message.voice.file_size == voice.file_size - @pytest.mark.flaky(3, 1) async def test_resend(self, bot, chat_id, voice): message = await bot.sendVoice(chat_id, voice.file_id) assert message.voice == voice - async def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["voice"] == voice.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_voice(chat_id, voice=voice) - assert message - - @pytest.mark.flaky(3, 1) async def test_send_voice_caption_entities(self, bot, chat_id, voice_file): test_string = "Italic Bold Code" entities = [ @@ -166,7 +246,6 @@ async def test_send_voice_caption_entities(self, bot, chat_id, voice_file): assert message.caption == test_string assert message.caption_entities == tuple(entities) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_voice_default_parse_mode_1(self, default_bot, chat_id, voice): test_string = "Italic Bold Code" @@ -176,7 +255,6 @@ async def test_send_voice_default_parse_mode_1(self, default_bot, chat_id, voice assert message.caption_markdown == test_markdown_string assert message.caption == test_string - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_voice_default_parse_mode_2(self, default_bot, chat_id, voice): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -187,7 +265,6 @@ async def test_send_voice_default_parse_mode_2(self, default_bot, chat_id, voice assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) async def test_send_voice_default_parse_mode_3(self, default_bot, chat_id, voice): test_markdown_string = "_Italic_ *Bold* `Code`" @@ -198,7 +275,6 @@ async def test_send_voice_default_parse_mode_3(self, default_bot, chat_id, voice assert message.caption == test_markdown_string assert message.caption_markdown == escape_markdown(test_markdown_string) - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_voice_default_protect_content(self, chat_id, default_bot, voice): protected = await default_bot.send_voice(chat_id, voice) @@ -206,29 +282,6 @@ async def test_send_voice_default_protect_content(self, chat_id, default_bot, vo unprotected = await default_bot.send_voice(chat_id, voice, protect_content=False) assert not unprotected.has_protected_content - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_voice_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("voice") == expected - else: - test_flag = isinstance(data.get("voice"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_voice(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - - @pytest.mark.flaky(3, 1) @pytest.mark.parametrize( "default_bot,custom", [ @@ -262,74 +315,10 @@ async def test_send_voice_default_allow_sending_without_reply( chat_id, voice, reply_to_message_id=reply_to_message.message_id ) - def test_de_json(self, bot): - json_dict = { - "file_id": self.voice_file_id, - "file_unique_id": self.voice_file_unique_id, - "duration": self.duration, - "mime_type": self.mime_type, - "file_size": self.file_size, - } - json_voice = Voice.de_json(json_dict, bot) - assert json_voice.api_kwargs == {} - - assert json_voice.file_id == self.voice_file_id - assert json_voice.file_unique_id == self.voice_file_unique_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["file_unique_id"] == voice.file_unique_id - assert voice_dict["duration"] == voice.duration - assert voice_dict["mime_type"] == voice.mime_type - assert voice_dict["file_size"] == voice.file_size - - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file(self, bot, chat_id): with pytest.raises(TelegramError): await bot.sendVoice(chat_id, open(os.devnull, "rb")) - @pytest.mark.flaky(3, 1) async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.sendVoice(chat_id, "") - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.sendVoice(chat_id) - - async def test_get_file_instance_method(self, monkeypatch, voice): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == voice.file_id - - assert check_shortcut_signature(Voice.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(voice.get_file, voice.get_bot(), "get_file") - assert await check_defaults_handling(voice.get_file, voice.get_bot()) - - monkeypatch.setattr(voice.get_bot(), "get_file", make_assertion) - assert await voice.get_file() - - def test_equality(self, voice): - a = Voice(voice.file_id, voice.file_unique_id, self.duration) - b = Voice("", voice.file_unique_id, self.duration) - c = Voice(voice.file_id, voice.file_unique_id, 0) - d = Voice("", "", self.duration) - e = Audio(voice.file_id, voice.file_unique_id, self.duration) - - 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_webappdata.py b/tests/test_webappdata.py index 618d8e53a58..7f13d6c7d43 100644 --- a/tests/test_webappdata.py +++ b/tests/test_webappdata.py @@ -22,18 +22,17 @@ from telegram import WebAppData -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def web_app_data(): - return WebAppData( - data=TestWebAppData.data, - button_text=TestWebAppData.button_text, - ) + return WebAppData(data=Space.data, button_text=Space.button_text) -class TestWebAppData: +class Space: data = "data" button_text = "button_text" + +class TestWebAppDataNoReq: def test_slot_behaviour(self, web_app_data, mro_slots): for attr in web_app_data.__slots__: assert getattr(web_app_data, attr, "err") != "err", f"got extra slot '{attr}'" @@ -43,20 +42,20 @@ def test_to_dict(self, web_app_data): web_app_data_dict = web_app_data.to_dict() assert isinstance(web_app_data_dict, dict) - assert web_app_data_dict["data"] == self.data - assert web_app_data_dict["button_text"] == self.button_text + assert web_app_data_dict["data"] == Space.data + assert web_app_data_dict["button_text"] == Space.button_text def test_de_json(self, bot): - json_dict = {"data": self.data, "button_text": self.button_text} + json_dict = {"data": Space.data, "button_text": Space.button_text} web_app_data = WebAppData.de_json(json_dict, bot) assert web_app_data.api_kwargs == {} - assert web_app_data.data == self.data - assert web_app_data.button_text == self.button_text + assert web_app_data.data == Space.data + assert web_app_data.button_text == Space.button_text def test_equality(self): - a = WebAppData(self.data, self.button_text) - b = WebAppData(self.data, self.button_text) + a = WebAppData(Space.data, Space.button_text) + b = WebAppData(Space.data, Space.button_text) c = WebAppData("", "") d = WebAppData("not_data", "not_button_text") diff --git a/tests/test_webappinfo.py b/tests/test_webappinfo.py index 42fb0c48e69..96c49a50c9a 100644 --- a/tests/test_webappinfo.py +++ b/tests/test_webappinfo.py @@ -22,14 +22,16 @@ from telegram import WebAppInfo -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def web_app_info(): - return WebAppInfo(url=TestWebAppInfo.url) + return WebAppInfo(url=Space.url) -class TestWebAppInfo: +class Space: url = "https://www.example.com" + +class TestWebAppInfoNoReq: def test_slot_behaviour(self, web_app_info, mro_slots): for attr in web_app_info.__slots__: assert getattr(web_app_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -39,18 +41,18 @@ def test_to_dict(self, web_app_info): web_app_info_dict = web_app_info.to_dict() assert isinstance(web_app_info_dict, dict) - assert web_app_info_dict["url"] == self.url + assert web_app_info_dict["url"] == Space.url def test_de_json(self, bot): - json_dict = {"url": self.url} + json_dict = {"url": Space.url} web_app_info = WebAppInfo.de_json(json_dict, bot) assert web_app_info.api_kwargs == {} - assert web_app_info.url == self.url + assert web_app_info.url == Space.url def test_equality(self): - a = WebAppInfo(self.url) - b = WebAppInfo(self.url) + a = WebAppInfo(Space.url) + b = WebAppInfo(Space.url) c = WebAppInfo("") d = WebAppInfo("not_url") diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index 575f11abfb9..2c28c1361e1 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -25,21 +25,21 @@ from telegram._utils.datetime import from_timestamp -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def webhook_info(): return WebhookInfo( - url=TestWebhookInfo.url, - has_custom_certificate=TestWebhookInfo.has_custom_certificate, - pending_update_count=TestWebhookInfo.pending_update_count, - ip_address=TestWebhookInfo.ip_address, - last_error_date=TestWebhookInfo.last_error_date, - max_connections=TestWebhookInfo.max_connections, - allowed_updates=TestWebhookInfo.allowed_updates, - last_synchronization_error_date=TestWebhookInfo.last_synchronization_error_date, + url=Space.url, + has_custom_certificate=Space.has_custom_certificate, + pending_update_count=Space.pending_update_count, + ip_address=Space.ip_address, + last_error_date=Space.last_error_date, + max_connections=Space.max_connections, + allowed_updates=Space.allowed_updates, + last_synchronization_error_date=Space.last_synchronization_error_date, ) -class TestWebhookInfo: +class Space: url = "http://www.google.com" has_custom_certificate = False pending_update_count = 5 @@ -49,6 +49,8 @@ class TestWebhookInfo: allowed_updates = ["type1", "type2"] last_synchronization_error_date = time.time() + +class TestWebhookInfoNoReq: def test_slot_behaviour(self, webhook_info, mro_slots): for attr in webhook_info.__slots__: assert getattr(webhook_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -58,42 +60,42 @@ def test_to_dict(self, webhook_info): webhook_info_dict = webhook_info.to_dict() assert isinstance(webhook_info_dict, dict) - assert webhook_info_dict["url"] == self.url - assert webhook_info_dict["pending_update_count"] == self.pending_update_count - assert webhook_info_dict["last_error_date"] == self.last_error_date - assert webhook_info_dict["max_connections"] == self.max_connections - assert webhook_info_dict["allowed_updates"] == self.allowed_updates - assert webhook_info_dict["ip_address"] == self.ip_address + assert webhook_info_dict["url"] == Space.url + assert webhook_info_dict["pending_update_count"] == Space.pending_update_count + assert webhook_info_dict["last_error_date"] == Space.last_error_date + assert webhook_info_dict["max_connections"] == Space.max_connections + assert webhook_info_dict["allowed_updates"] == Space.allowed_updates + assert webhook_info_dict["ip_address"] == Space.ip_address assert ( webhook_info_dict["last_synchronization_error_date"] - == self.last_synchronization_error_date + == Space.last_synchronization_error_date ) def test_de_json(self, bot): json_dict = { - "url": self.url, - "has_custom_certificate": self.has_custom_certificate, - "pending_update_count": self.pending_update_count, - "last_error_date": self.last_error_date, - "max_connections": self.max_connections, - "allowed_updates": self.allowed_updates, - "ip_address": self.ip_address, - "last_synchronization_error_date": self.last_synchronization_error_date, + "url": Space.url, + "has_custom_certificate": Space.has_custom_certificate, + "pending_update_count": Space.pending_update_count, + "last_error_date": Space.last_error_date, + "max_connections": Space.max_connections, + "allowed_updates": Space.allowed_updates, + "ip_address": Space.ip_address, + "last_synchronization_error_date": Space.last_synchronization_error_date, } webhook_info = WebhookInfo.de_json(json_dict, bot) assert webhook_info.api_kwargs == {} - assert webhook_info.url == self.url - assert webhook_info.has_custom_certificate == self.has_custom_certificate - assert webhook_info.pending_update_count == self.pending_update_count + assert webhook_info.url == Space.url + assert webhook_info.has_custom_certificate == Space.has_custom_certificate + assert webhook_info.pending_update_count == Space.pending_update_count assert isinstance(webhook_info.last_error_date, datetime) - assert webhook_info.last_error_date == from_timestamp(self.last_error_date) - assert webhook_info.max_connections == self.max_connections - assert webhook_info.allowed_updates == tuple(self.allowed_updates) - assert webhook_info.ip_address == self.ip_address + assert webhook_info.last_error_date == from_timestamp(Space.last_error_date) + assert webhook_info.max_connections == Space.max_connections + assert webhook_info.allowed_updates == tuple(Space.allowed_updates) + assert webhook_info.ip_address == Space.ip_address assert isinstance(webhook_info.last_synchronization_error_date, datetime) assert webhook_info.last_synchronization_error_date == from_timestamp( - self.last_synchronization_error_date + Space.last_synchronization_error_date ) none = WebhookInfo.de_json(None, bot) @@ -101,24 +103,24 @@ def test_de_json(self, bot): def test_always_tuple_allowed_updates(self): webhook_info = WebhookInfo( - self.url, self.has_custom_certificate, self.pending_update_count + Space.url, Space.has_custom_certificate, Space.pending_update_count ) assert webhook_info.allowed_updates == () def test_equality(self): a = WebhookInfo( - url=self.url, - has_custom_certificate=self.has_custom_certificate, - pending_update_count=self.pending_update_count, - last_error_date=self.last_error_date, - max_connections=self.max_connections, + url=Space.url, + has_custom_certificate=Space.has_custom_certificate, + pending_update_count=Space.pending_update_count, + last_error_date=Space.last_error_date, + max_connections=Space.max_connections, ) b = WebhookInfo( - url=self.url, - has_custom_certificate=self.has_custom_certificate, - pending_update_count=self.pending_update_count, - last_error_date=self.last_error_date, - max_connections=self.max_connections, + url=Space.url, + has_custom_certificate=Space.has_custom_certificate, + pending_update_count=Space.pending_update_count, + last_error_date=Space.last_error_date, + max_connections=Space.max_connections, ) c = WebhookInfo( url="http://github.com", From 77ecda18b6e21caf883234ca6bbfbf2196df0e0d Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 9 Dec 2022 18:50:39 +0530 Subject: [PATCH 02/77] Override get_me in tests to return cached User() object Also adapt the bot tests for this change + removes debug prints + fix few tests --- tests/conftest.py | 32 +++++++++++++++++++++++++++++--- tests/test_bot.py | 30 ++++++++++++++++++++---------- tests/test_user.py | 2 +- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 168c0d529b9..3ee5dbeeb41 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -113,8 +113,6 @@ def bot_info(): # Below classes are used to monkeypatch attributes since parent classes don't have __dict__ - - class TestHttpxRequest(HTTPXRequest): async def _request_wrapper( self, @@ -148,6 +146,12 @@ def __init__(self, *args, **kwargs): # Makes it easier to work with the bot in tests self._unfreeze() + # Here we override get_me for caching because we don't want to call the API repeatedly in tests + async def get_me(self, *args, **kwargs): + if self._bot_user is None: + self._bot_user = make_mock_user(self.token) + return self._bot_user + class DictBot(Bot): def __init__(self, *args, **kwargs): @@ -155,16 +159,38 @@ def __init__(self, *args, **kwargs): # Makes it easier to work with the bot in tests self._unfreeze() + # Here we override get_me for caching because we don't want to call the API repeatedly in tests + async def get_me(self, *args, **kwargs): + if self._bot_user is None: + self._bot_user = make_mock_user(self.token) + return self._bot_user + class DictApplication(Application): pass +def make_mock_user(token: str) -> User: + """Used to return a mock user in bot.get_me(). This saves API calls on every init.""" + bot_info = get_bot() + user_id = int(token.split(":")[0] or bot_info["token"].split(":")[0]) + first_name = bot_info.get("bot_name") or bot_info.get("name") + username = (bot_info.get("bot_username") or bot_info.get("username")).strip("@") + return User( + user_id, + first_name, + is_bot=True, + username=username, + can_join_groups=True, + can_read_all_group_messages=False, + supports_inline_queries=True, + ) + + @pytest.fixture(scope="session") async def bot(bot_info): """Makes an ExtBot instance with the given bot_info""" async with make_bot(bot_info) as _bot: - print("making new bot") yield _bot diff --git a/tests/test_bot.py b/tests/test_bot.py index d4b7d6f275d..a543e6386b8 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -95,7 +95,7 @@ def to_camel_case(snake_str): return components[0] + "".join(x.title() for x in components[1:]) -@pytest.fixture(scope="module") +@pytest.fixture(scope="class") async def message(bot, chat_id): to_reply_to = await bot.send_message( chat_id, "Text", disable_web_page_preview=True, disable_notification=True @@ -210,7 +210,7 @@ def test_slot_behaviour(self, bot_class, bot, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - async def test_initialize_and_shutdown(self, bot, monkeypatch): + async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): async def initialize(*args, **kwargs): self.test_flag = ["initialize"] @@ -295,10 +295,10 @@ async def shutdown(): assert self.test_flag == "stop" - async def test_log_decorator(self, bot, caplog): + async def test_log_decorator(self, bot: DictExtBot, caplog): # Second argument makes sure that we ignore logs from e.g. httpx with caplog.at_level(logging.DEBUG, logger="telegram"): - await bot.get_me() + await super(bot.__class__, bot).get_me() # call original get_me instead of overriden # Only for stabilizing this test- if len(caplog.records) == 4: for idx, record in enumerate(caplog.records): @@ -340,7 +340,7 @@ async def post(url, request_data: RequestData, *args, **kwargs): async def test_invalid_token_server_response(self): with pytest.raises(InvalidToken, match="The token `12` was rejected by the server."): - async with make_bot(token="12"): + async with ExtBot(token="12"): pass @pytest.mark.parametrize( @@ -365,12 +365,17 @@ async def test_get_me_and_properties_not_initialized(self, bot: Bot, attribute): finally: await bot.shutdown() - async def test_get_me_and_properties(self, bot: Bot): - get_me_bot = await bot.get_me() + async def test_get_me_and_properties(self, bot): + mocked = "mocked" + with bot._bot_user._unfrozen(): + bot._bot_user.username = mocked # set the attribute to a mocked value + assert bot.username == mocked # To test we are using the mocked bot + # call the parent class get_me method instead of the overriden get_me method + get_me_bot = await super(bot.__class__, bot).get_me() assert isinstance(get_me_bot, User) assert get_me_bot.id == bot.id - assert get_me_bot.username == bot.username + assert get_me_bot.username == bot.username != mocked # will be the real bot 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 @@ -414,7 +419,13 @@ def test_bot_pickling_error(self, bot): @bot_methods(ext_bot=False) async def test_defaults_handling( - self, bot_class, bot_method_name, bot_method, bot, raw_bot, monkeypatch + self, + bot_class, + bot_method_name: str, + bot_method, + bot: DictExtBot, + raw_bot: DictBot, + monkeypatch, ): """ Here we check that the bot methods handle tg.ext.Defaults correctly. This has two parts: @@ -2190,7 +2201,6 @@ async def test_leave_chat(self, bot): async def test_get_chat(self, bot, super_group_id): chat = await bot.get_chat(super_group_id) - assert chat.type == "supergroup" assert chat.title == f">>> telegram.Bot(test) @{bot.username}" assert chat.id == int(super_group_id) diff --git a/tests/test_user.py b/tests/test_user.py index c547618b6cc..6feff8abed0 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -44,7 +44,7 @@ def json_dict(): } -@pytest.fixture(scope="module") +@pytest.fixture(scope="function") def user(bot): user = User( id=Space.id_, From f1207dc26a98bedd73e063e833594dc0b943a3db Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 9 Dec 2022 19:02:39 +0530 Subject: [PATCH 03/77] move testing of initialization of bot to Req part --- tests/test_bot.py | 137 ++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index a543e6386b8..5e94c3272d3 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -197,12 +197,6 @@ def __init__( class TestBotNoReq: - test_flag = None - - @pytest.fixture(scope="function", autouse=True) - def reset(self): - self.test_flag = None - @pytest.mark.parametrize("bot_class", [Bot, ExtBot]) def test_slot_behaviour(self, bot_class, bot, mro_slots): inst = bot_class(bot.token) @@ -210,66 +204,16 @@ def test_slot_behaviour(self, bot_class, bot, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): - async def initialize(*args, **kwargs): - self.test_flag = ["initialize"] - - async def stop(*args, **kwargs): - self.test_flag.append("stop") - - temp_bot = Bot(token=bot.token) - orig_stop = temp_bot.request.shutdown - - try: - monkeypatch.setattr(temp_bot.request, "initialize", initialize) - monkeypatch.setattr(temp_bot.request, "shutdown", stop) - await temp_bot.initialize() - assert self.test_flag == ["initialize"] - assert temp_bot.bot == bot.bot - - await temp_bot.shutdown() - assert self.test_flag == ["initialize", "stop"] - finally: - await orig_stop() - - async def test_multiple_inits_and_shutdowns(self, bot, monkeypatch): - self.received = defaultdict(int) - - async def initialize(*args, **kwargs): - self.received["init"] += 1 - - async def shutdown(*args, **kwargs): - self.received["shutdown"] += 1 - - monkeypatch.setattr(HTTPXRequest, "initialize", initialize) - monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) - - test_bot = Bot(bot.token) - await test_bot.initialize() - await test_bot.initialize() - await test_bot.initialize() - await test_bot.shutdown() - await test_bot.shutdown() - await test_bot.shutdown() - - # 2 instead of 1 since we have to request objects for each bot - assert self.received["init"] == 2 - assert self.received["shutdown"] == 2 - - async def test_multiple_init_cycles(self, bot): - # nothing really to assert - this should just not fail - test_bot = Bot(bot.token) - async with test_bot: - await test_bot.get_me() - async with test_bot: - await test_bot.get_me() - async def test_context_manager(self, monkeypatch, bot): + test_flag = [] + async def initialize(): - self.test_flag = ["initialize"] + nonlocal test_flag + test_flag = ["initialize"] async def shutdown(*args): - self.test_flag.append("stop") + nonlocal test_flag + test_flag.append("stop") monkeypatch.setattr(bot, "initialize", initialize) monkeypatch.setattr(bot, "shutdown", shutdown) @@ -277,14 +221,17 @@ async def shutdown(*args): async with bot: pass - assert self.test_flag == ["initialize", "stop"] + assert test_flag == ["initialize", "stop"] async def test_context_manager_exception_on_init(self, monkeypatch, bot): + test_flag = [] + async def initialize(): raise RuntimeError("initialize") async def shutdown(): - self.test_flag = "stop" + nonlocal test_flag + test_flag = "stop" monkeypatch.setattr(bot, "initialize", initialize) monkeypatch.setattr(bot, "shutdown", shutdown) @@ -293,7 +240,7 @@ async def shutdown(): async with bot: pass - assert self.test_flag == "stop" + assert test_flag == "stop" async def test_log_decorator(self, bot: DictExtBot, caplog): # Second argument makes sure that we ignore logs from e.g. httpx @@ -1496,6 +1443,66 @@ def localize(dt, tzinfo): # fail if this branch is ever reached. sys.exit(1) + test_flag = None + + @pytest.fixture(scope="function", autouse=True) + def reset(self): + self.test_flag = None + + async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): + async def initialize(*args, **kwargs): + self.test_flag = ["initialize"] + + async def stop(*args, **kwargs): + self.test_flag.append("stop") + + temp_bot = Bot(token=bot.token) + orig_stop = temp_bot.request.shutdown + + try: + monkeypatch.setattr(temp_bot.request, "initialize", initialize) + monkeypatch.setattr(temp_bot.request, "shutdown", stop) + await temp_bot.initialize() + assert self.test_flag == ["initialize"] + assert temp_bot.bot == bot.bot + + await temp_bot.shutdown() + assert self.test_flag == ["initialize", "stop"] + finally: + await orig_stop() + + async def test_multiple_inits_and_shutdowns(self, bot, monkeypatch): + self.received = defaultdict(int) + + async def initialize(*args, **kwargs): + self.received["init"] += 1 + + async def shutdown(*args, **kwargs): + self.received["shutdown"] += 1 + + monkeypatch.setattr(HTTPXRequest, "initialize", initialize) + monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) + + test_bot = Bot(bot.token) + await test_bot.initialize() + await test_bot.initialize() + await test_bot.initialize() + await test_bot.shutdown() + await test_bot.shutdown() + await test_bot.shutdown() + + # 2 instead of 1 since we have to request objects for each bot + assert self.received["init"] == 2 + assert self.received["shutdown"] == 2 + + async def test_multiple_init_cycles(self, bot): + # nothing really to assert - this should just not fail + test_bot = Bot(bot.token) + async with test_bot: + await test_bot.get_me() + async with test_bot: + await test_bot.get_me() + async def test_forward_message(self, bot, chat_id, message): forward_message = await bot.forward_message( chat_id, from_chat_id=chat_id, message_id=message.message_id From 4fe99558baa9afb16fa279c8957a14331c183ae9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 10 Dec 2022 23:05:45 +0530 Subject: [PATCH 04/77] use TEST_WITH_OPT_DEPS to justify removing TestBot.localize --- tests/test_bot.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index 5e94c3272d3..23b80175dab 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -23,7 +23,6 @@ import logging import pickle import socket -import sys import time from collections import defaultdict @@ -1433,16 +1432,6 @@ class TestBotReq: is tested in `test_callbackdatacache` """ - @staticmethod - def localize(dt, tzinfo): - try: - return tzinfo.localize(dt) - except AttributeError: - # We get here if tzinfo is not a pytz timezone but a datetime.timezone class - # This test class should never be run in if pytz is not installed, we intentionally - # fail if this branch is ever reached. - sys.exit(1) - test_flag = None @pytest.fixture(scope="function", autouse=True) @@ -2501,6 +2490,7 @@ async def test_create_chat_invite_link_basics( ) assert revoked_link.is_revoked + @pytest.mark.skipif(not TEST_WITH_OPT_DEPS, reason="requires pytz") @pytest.mark.parametrize("datetime", argvalues=[True, False], ids=["datetime", "integer"]) async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): # we are testing this all in one function in order to save api calls @@ -2508,7 +2498,7 @@ async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): add_seconds = dtm.timedelta(0, 70) time_in_future = timestamp + add_seconds expire_time = time_in_future if datetime else to_timestamp(time_in_future) - aware_time_in_future = self.localize(time_in_future, UTC) + aware_time_in_future = UTC.localize(time_in_future) invite_link = await bot.create_chat_invite_link( channel_id, expire_date=expire_time, member_limit=10 @@ -2521,7 +2511,7 @@ async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): add_seconds = dtm.timedelta(0, 80) time_in_future = timestamp + add_seconds expire_time = time_in_future if datetime else to_timestamp(time_in_future) - aware_time_in_future = self.localize(time_in_future, UTC) + aware_time_in_future = UTC.localize(time_in_future) edited_invite_link = await bot.edit_chat_invite_link( channel_id, From c67f100bfe351f72c9bd500e8b77738b34e68b35 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 10 Dec 2022 23:24:35 +0530 Subject: [PATCH 05/77] import `TEST_WITH_OPT_DEPS` from conftest instead of redefining every time --- tests/test_applicationbuilder.py | 6 +----- tests/test_callbackdatacache.py | 6 +----- tests/test_datetime.py | 4 +--- tests/test_defaults.py | 5 +---- tests/test_jobqueue.py | 4 +--- tests/test_no_passport.py | 6 +----- tests/test_ratelimiter.py | 4 +--- tests/test_request.py | 6 +----- tests/test_updater.py | 4 +--- 9 files changed, 9 insertions(+), 36 deletions(-) diff --git a/tests/test_applicationbuilder.py b/tests/test_applicationbuilder.py index 148a28a0464..b884102c9fe 100644 --- a/tests/test_applicationbuilder.py +++ b/tests/test_applicationbuilder.py @@ -17,7 +17,6 @@ # 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 asyncio -import os from dataclasses import dataclass import httpx @@ -38,10 +37,7 @@ from telegram.ext._applicationbuilder import _BOT_CHECKS from telegram.request import HTTPXRequest -from .auxil.object_conversions import env_var_2_bool -from .conftest import PRIVATE_KEY, data_file - -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) +from .conftest import PRIVATE_KEY, TEST_WITH_OPT_DEPS @pytest.fixture(scope="function") diff --git a/tests/test_callbackdatacache.py b/tests/test_callbackdatacache.py index 2c2872ec017..3afed54bbfa 100644 --- a/tests/test_callbackdatacache.py +++ b/tests/test_callbackdatacache.py @@ -16,7 +16,6 @@ # # 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 time from copy import deepcopy from datetime import datetime @@ -28,7 +27,7 @@ from telegram._utils.datetime import UTC from telegram.ext import ExtBot from telegram.ext._callbackdatacache import CallbackDataCache, InvalidCallbackData, _KeyboardData -from tests.auxil.object_conversions import env_var_2_bool +from tests.conftest import TEST_WITH_OPT_DEPS @pytest.fixture(scope="function") @@ -36,9 +35,6 @@ def callback_data_cache(bot): return CallbackDataCache(bot) -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) - - @pytest.mark.skipif( TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed", diff --git a/tests/test_datetime.py b/tests/test_datetime.py index aae6ccac0af..2287513c23b 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -17,7 +17,6 @@ # 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 datetime as dtm -import os import time import pytest @@ -26,7 +25,7 @@ from telegram.ext import Defaults # sample time specification values categorised into absolute / delta / time-of-day -from tests.auxil.object_conversions import env_var_2_bool +from tests.conftest import TEST_WITH_OPT_DEPS ABSOLUTE_TIME_SPECS = [ dtm.datetime.now(tz=dtm.timezone(dtm.timedelta(hours=-7))).replace(second=0, microsecond=0), @@ -49,7 +48,6 @@ with the TEST_WITH_OPT_DEPS=False environment variable in addition to the regular test suite. """ -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) class TestDatetime: diff --git a/tests/test_defaults.py b/tests/test_defaults.py index 902753b05d2..8efcca754a2 100644 --- a/tests/test_defaults.py +++ b/tests/test_defaults.py @@ -19,15 +19,12 @@ import datetime as dtm import inspect -import os import pytest from telegram import User from telegram.ext import Defaults -from tests.auxil.object_conversions import env_var_2_bool - -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) +from tests.conftest import TEST_WITH_OPT_DEPS class TestDefault: diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 5488eb476b8..11020372dfc 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -27,9 +27,7 @@ import pytest from telegram.ext import ApplicationBuilder, CallbackContext, ContextTypes, Job, JobQueue -from tests.auxil.object_conversions import env_var_2_bool - -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) +from tests.conftest import TEST_WITH_OPT_DEPS if TEST_WITH_OPT_DEPS: import pytz diff --git a/tests/test_no_passport.py b/tests/test_no_passport.py index 366995fe856..ee4999988aa 100644 --- a/tests/test_no_passport.py +++ b/tests/test_no_passport.py @@ -26,15 +26,11 @@ with the TEST_WITH_OPT_DEPS environment variable set to False in addition to the regular test suite """ -import os - import pytest from telegram import _bot as bot from telegram._passport import credentials as credentials -from tests.auxil.object_conversions import env_var_2_bool - -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) +from tests.conftest import TEST_WITH_OPT_DEPS @pytest.mark.skipif( diff --git a/tests/test_ratelimiter.py b/tests/test_ratelimiter.py index 39c4c731fc9..9c95855e6d7 100644 --- a/tests/test_ratelimiter.py +++ b/tests/test_ratelimiter.py @@ -36,9 +36,7 @@ from telegram.error import RetryAfter from telegram.ext import AIORateLimiter, BaseRateLimiter, Defaults, ExtBot from telegram.request import BaseRequest, RequestData -from tests.auxil.object_conversions import env_var_2_bool - -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) +from tests.conftest import TEST_WITH_OPT_DEPS @pytest.mark.skipif( diff --git a/tests/test_request.py b/tests/test_request.py index d4cd90ac6f4..22d0e01bbe3 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -20,7 +20,6 @@ implementations for BaseRequest and we want to test HTTPXRequest anyway.""" import asyncio import json -import os from collections import defaultdict from dataclasses import dataclass from http import HTTPStatus @@ -43,7 +42,7 @@ ) from telegram.request._httpxrequest import HTTPXRequest -from .auxil.object_conversions import env_var_2_bool +from .conftest import TEST_WITH_OPT_DEPS # We only need the first fixture, but it uses the others, so pytest needs us to import them as well from .test_requestdata import ( # noqa: F401 @@ -72,9 +71,6 @@ async def httpx_request(): yield rq -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) - - @pytest.mark.skipif( TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed" ) diff --git a/tests/test_updater.py b/tests/test_updater.py index 62fb0da5293..bb697e98f2d 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -18,7 +18,6 @@ # along with this program. If not, see [http://www.gnu.org/licenses/]. import asyncio import logging -import os from collections import defaultdict from http import HTTPStatus from pathlib import Path @@ -33,6 +32,7 @@ from telegram.request import HTTPXRequest from tests.auxil.object_conversions import env_var_2_bool from tests.conftest import ( + TEST_WITH_OPT_DEPS, DictBot, data_file, make_bot, @@ -41,8 +41,6 @@ send_webhook_message, ) -TEST_WITH_OPT_DEPS = env_var_2_bool(os.getenv("TEST_WITH_OPT_DEPS", True)) - if TEST_WITH_OPT_DEPS: from telegram.ext._utils.webhookhandler import WebhookServer From 7b412cf3f4a4df3a4e4c884e35bba116d795d905 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 11 Dec 2022 20:20:45 +0530 Subject: [PATCH 06/77] use context manager for data_file in fixtures Also change the scope of some fixtures --- tests/conftest.py | 10 ++++------ tests/test_animation.py | 10 ++++------ tests/test_audio.py | 11 ++++------- tests/test_chatphoto.py | 9 ++++----- tests/test_document.py | 5 ++--- tests/test_encryptedpassportelement.py | 2 +- tests/test_photo.py | 8 +++----- tests/test_video.py | 5 ++--- tests/test_videonote.py | 5 ++--- tests/test_voice.py | 5 ++--- 10 files changed, 28 insertions(+), 42 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 3ee5dbeeb41..a07bc1b2000 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -301,16 +301,14 @@ def data_file(filename: str) -> Path: @pytest.fixture(scope="function") def thumb_file(): - f = data_file("thumb.jpg").open("rb") - yield f - f.close() + with data_file("thumb.jpg").open("rb") as f: + yield f @pytest.fixture(scope="module") def class_thumb_file(): - f = data_file("thumb.jpg").open("rb") - yield f - f.close() + with data_file("thumb.jpg").open("rb") as f: + yield f def make_bot(bot_info=None, **kwargs): diff --git a/tests/test_animation.py b/tests/test_animation.py index 5017f2753c7..3ccce4fba25 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -35,17 +35,15 @@ @pytest.fixture(scope="function") def animation_file(): - f = data_file("game.gif").open("rb") - yield f - f.close() + with data_file("game.gif").open("rb") as f: + yield f @pytest.fixture(scope="module") async def animation(bot, chat_id): - with data_file("game.gif").open("rb") as f: - thumb = data_file("thumb.jpg") + with data_file("game.gif").open("rb") as f, data_file("thumb.jpg").open("rb") as thumb: return ( - await bot.send_animation(chat_id, animation=f, read_timeout=50, thumb=thumb.open("rb")) + await bot.send_animation(chat_id, animation=f, read_timeout=50, thumb=thumb) ).animation diff --git a/tests/test_audio.py b/tests/test_audio.py index f4c1f49b15f..728cc53345d 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -33,19 +33,16 @@ from tests.conftest import data_file -@pytest.fixture(scope="module") +@pytest.fixture(scope="function") def audio_file(): - with open(data_file("telegram.mp3"), "rb") as f: + with data_file("telegram.mp3").open("rb") as f: yield f @pytest.fixture(scope="module") async def audio(bot, chat_id): - with data_file("telegram.mp3").open("rb") as f: - thumb = data_file("thumb.jpg") - return ( - await bot.send_audio(chat_id, audio=f, read_timeout=50, thumb=thumb.open("rb")) - ).audio + with data_file("telegram.mp3").open("rb") as f, data_file("thumb.jpg").open("rb") as thumb: + return (await bot.send_audio(chat_id, audio=f, read_timeout=50, thumb=thumb)).audio class Space: diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index cb357378ea6..dc4ecf4926a 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -33,14 +33,13 @@ from tests.conftest import data_file, expect_bad_request -@pytest.fixture(scope="module") +@pytest.fixture(scope="function") def chatphoto_file(): - f = data_file("telegram.jpg").open("rb") - yield f - f.close() + with data_file("telegram.jpg").open("rb") as f: + yield f -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") async def chat_photo(bot, super_group_id): async def func(): return (await bot.get_chat(super_group_id, read_timeout=50)).photo diff --git a/tests/test_document.py b/tests/test_document.py index f00bf3b26fc..3a28e62a749 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -35,9 +35,8 @@ @pytest.fixture(scope="function") def document_file(): - f = data_file("telegram.png").open("rb") - yield f - f.close() + with data_file("telegram.png").open("rb") as f: + yield f @pytest.fixture(scope="module") diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index a7399050947..a10ba2f843d 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -22,7 +22,7 @@ from telegram import EncryptedPassportElement, PassportElementError, PassportFile -@pytest.fixture(scope="class") +@pytest.fixture(scope="module") def encrypted_passport_element(): return EncryptedPassportElement( Space.type_, diff --git a/tests/test_photo.py b/tests/test_photo.py index 6cbdd137acb..80bf615557c 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -35,17 +35,15 @@ @pytest.fixture(scope="function") def photo_file(): - f = data_file("telegram.jpg").open("rb") - yield f - f.close() + with data_file("telegram.jpg").open("rb") as f: + yield f @pytest.fixture(scope="module") async def _photo(bot, chat_id): async def func(): with data_file("telegram.jpg").open("rb") as f: - photo = (await bot.send_photo(chat_id, photo=f, read_timeout=50)).photo - return photo + return (await bot.send_photo(chat_id, photo=f, read_timeout=50)).photo return await expect_bad_request( func, "Type of file mismatch", "Telegram did not accept the file." diff --git a/tests/test_video.py b/tests/test_video.py index a3b7f5c1471..bf098827f4a 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -35,9 +35,8 @@ @pytest.fixture(scope="function") def video_file(): - f = data_file("telegram.mp4").open("rb") - yield f - f.close() + with data_file("telegram.mp4").open("rb") as f: + yield f @pytest.fixture(scope="module") diff --git a/tests/test_videonote.py b/tests/test_videonote.py index b991ffe576f..0a8a3ec4613 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -34,9 +34,8 @@ @pytest.fixture(scope="function") def video_note_file(): - f = data_file("telegram2.mp4").open("rb") - yield f - f.close() + with data_file("telegram2.mp4").open("rb") as f: + yield f @pytest.fixture(scope="module") diff --git a/tests/test_voice.py b/tests/test_voice.py index d765d3fa509..8c3c376141f 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -35,9 +35,8 @@ @pytest.fixture(scope="function") def voice_file(): - f = data_file("telegram.ogg").open("rb") - yield f - f.close() + with data_file("telegram.ogg").open("rb") as f: + yield f @pytest.fixture(scope="module") From 8725e4b0602bb35a6375e863014b7f5f231118ed Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 11 Dec 2022 20:26:01 +0530 Subject: [PATCH 07/77] rearrange the order of one test method (so tests pass) --- tests/test_chatphoto.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index dc4ecf4926a..1f745834a7e 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -152,16 +152,6 @@ def test_equality(self): class TestChatPhotoReq: - async def test_send_all_args( - self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file - ): - async def func(): - assert await bot.set_chat_photo(super_group_id, chatphoto_file) - - await expect_bad_request( - func, "Type of file mismatch", "Telegram did not accept the file." - ) - async def test_get_and_download(self, bot, chat_photo): jpg_file = Path("telegram.jpg") if jpg_file.is_file(): @@ -185,6 +175,16 @@ async def test_get_and_download(self, bot, chat_photo): assert jpg_file.is_file() + async def test_send_all_args( + self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file + ): + async def func(): + assert await bot.set_chat_photo(super_group_id, chatphoto_file) + + await expect_bad_request( + func, "Type of file mismatch", "Telegram did not accept the file." + ) + async def test_error_send_empty_file(self, bot, super_group_id): chatphoto_file = open(os.devnull, "rb") From 0920f954b7678fb34f68d23c1550613aab735d8a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 02:58:12 +0530 Subject: [PATCH 08/77] Optimize `TestApplication` significantly by making small changes This mainly does two things: - Leverages the session bot while making new applications, this eliminates all calls to get_me - `test_signal_handler` was optimized to use `loop.call_later` which eliminates the chance where we could get a TaskException not retrieved error, which often fatally crash pytest. These two changes thus reduce flakyness and improves speed. --- tests/test_application.py | 143 +++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 64 deletions(-) diff --git a/tests/test_application.py b/tests/test_application.py index 698c40bbc09..13917cf2d0d 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -53,7 +53,18 @@ filters, ) from telegram.warnings import PTBUserWarning -from tests.conftest import PROJECT_ROOT_PATH, call_after, make_message_update, send_webhook_message +from tests.conftest import ( + PROJECT_ROOT_PATH, + call_after, + make_bot, + make_message_update, + send_webhook_message, +) + + +@pytest.fixture(scope="function") +def test_bot(bot_info): # was needed since we get HTTPXRequest not initialized after app tests + return make_bot(bot_info) class CustomContext(CallbackContext): @@ -113,8 +124,8 @@ async def callback_context(self, update, context): ): self.received = context.error.message - async def test_slot_behaviour(self, bot, mro_slots): - async with ApplicationBuilder().token(bot.token).build() as app: + async def test_slot_behaviour(self, test_bot, mro_slots): + async with ApplicationBuilder().bot(test_bot).build() as app: for at in app.__slots__: at = f"_Application{at}" if at.startswith("__") and not at.endswith("__") else at assert getattr(app, at, "err") != "err", f"got extra slot '{at}'" @@ -143,12 +154,12 @@ def test_manual_init_warning(self, recwarn, updater): "concurrent_updates, expected", [(0, 0), (4, 4), (False, 0), (True, 256)] ) @pytest.mark.filterwarnings("ignore: `Application` instances should") - def test_init(self, bot, concurrent_updates, expected): + def test_init(self, test_bot, concurrent_updates, expected): update_queue = asyncio.Queue() job_queue = JobQueue() persistence = PicklePersistence("file_path") context_types = ContextTypes() - updater = Updater(bot=bot, update_queue=update_queue) + updater = Updater(bot=test_bot, update_queue=update_queue) async def post_init(application: Application) -> None: pass @@ -157,7 +168,7 @@ async def post_shutdown(application: Application) -> None: pass app = Application( - bot=bot, + bot=test_bot, update_queue=update_queue, job_queue=job_queue, persistence=persistence, @@ -167,7 +178,7 @@ async def post_shutdown(application: Application) -> None: post_init=post_init, post_shutdown=post_shutdown, ) - assert app.bot is bot + assert app.bot is test_bot assert app.update_queue is update_queue assert app.job_queue is job_queue assert app.persistence is persistence @@ -190,7 +201,7 @@ async def post_shutdown(application: Application) -> None: with pytest.raises(ValueError, match="must be a non-negative"): Application( - bot=bot, + bot=test_bot, update_queue=update_queue, job_queue=job_queue, persistence=persistence, @@ -201,13 +212,13 @@ async def post_shutdown(application: Application) -> None: post_shutdown=None, ) - def test_job_queue(self, bot, app, recwarn): + def test_job_queue(self, test_bot, app, recwarn): expected_warning = ( "No `JobQueue` set up. To use `JobQueue`, you must install PTB via " "`pip install python-telegram-bot[job_queue]`." ) assert app.job_queue is app._job_queue - application = ApplicationBuilder().token(bot.token).job_queue(None).build() + application = ApplicationBuilder().bot(test_bot).job_queue(None).build() assert application.job_queue is None assert len(recwarn) == 1 assert str(recwarn[0].message) == expected_warning @@ -221,14 +232,14 @@ def test_custom_context_init(self, bot): bot_data=complex, ) - application = ApplicationBuilder().token(bot.token).context_types(cc).build() + application = ApplicationBuilder().bot(test_bot).context_types(cc).build() assert isinstance(application.user_data[1], int) assert isinstance(application.chat_data[1], float) assert isinstance(application.bot_data, complex) @pytest.mark.parametrize("updater", (True, False)) - async def test_initialize(self, bot, monkeypatch, updater): + async def test_initialize(self, test_bot, monkeypatch, updater): """Initialization of persistence is tested test_basepersistence""" self.test_flag = set() @@ -244,18 +255,18 @@ async def after_initialize_updater(*args, **kwargs): ) if updater: - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() await app.initialize() assert self.test_flag == {"bot", "updater"} await app.shutdown() else: - app = ApplicationBuilder().token(bot.token).updater(None).build() + app = ApplicationBuilder().bot(test_bot).updater(None).build() await app.initialize() assert self.test_flag == {"bot"} await app.shutdown() @pytest.mark.parametrize("updater", (True, False)) - async def test_shutdown(self, bot, monkeypatch, updater): + async def test_shutdown(self, test_bot, monkeypatch, updater): """Shutdown of persistence is tested in test_basepersistence""" self.test_flag = set() @@ -271,11 +282,11 @@ def after_updater_shutdown(*args, **kwargs): ) if updater: - async with ApplicationBuilder().token(bot.token).build(): + async with ApplicationBuilder().bot(test_bot).build(): pass assert self.test_flag == {"bot", "updater"} else: - async with ApplicationBuilder().token(bot.token).updater(None).build(): + async with ApplicationBuilder().bot(test_bot).updater(None).build(): pass assert self.test_flag == {"bot"} @@ -322,12 +333,12 @@ async def test_shutdown_while_running(self, app): await app.shutdown() await app.stop() - async def test_start_not_running_after_failure(self, bot, monkeypatch): + async def test_start_not_running_after_failure(self, test_bot, monkeypatch): def start(_): raise Exception("Test Exception") monkeypatch.setattr(JobQueue, "start", start) - app = ApplicationBuilder().token(bot.token).job_queue(JobQueue()).build() + app = ApplicationBuilder().bot(test_bot).job_queue(JobQueue()).build() async with app: with pytest.raises(Exception, match="Test Exception"): @@ -398,12 +409,12 @@ def test_builder(self, app): @pytest.mark.parametrize("job_queue", (True, False)) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - async def test_start_stop_processing_updates(self, bot, job_queue): + async def test_start_stop_processing_updates(self, test_bot, job_queue): # TODO: repeat a similar test for create_task, persistence processing and job queue if job_queue: - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() else: - app = ApplicationBuilder().token(bot.token).job_queue(None).build() + app = ApplicationBuilder().bot(test_bot).job_queue(None).build() async def callback(u, c): self.received = u @@ -433,9 +444,10 @@ async def callback(u, c): await asyncio.sleep(0.05) assert app.update_queue.empty() assert self.received == 1 - - await app.updater.start_polling() - await app.stop() + try: # just in case start_polling times out + await app.updater.start_polling() + finally: # stop the app so it doesn't crash on shutdown + await app.stop() assert not app.running # app.stop() should not stop the updater! assert app.updater.running @@ -636,7 +648,7 @@ def handle_update( await asyncio.sleep(0.05) await app.stop() - async def test_flow_stop(self, app, bot): + async def test_flow_stop(self, app, test_bot): passed = [] async def start1(b, u): @@ -661,7 +673,8 @@ async def start3(b, u): ], ), ) - update.message.set_bot(bot) + await test_bot.initialize() + update.message.set_bot(test_bot) async with app: # If ApplicationHandlerStop raised handlers in other groups should not be called. @@ -672,7 +685,7 @@ async def start3(b, u): await app.process_update(update) assert passed == ["start1"] - async def test_flow_stop_by_error_handler(self, app, bot): + async def test_flow_stop_by_error_handler(self, app): passed = [] exception = Exception("General excepition") @@ -721,7 +734,7 @@ async def test_error_in_handler_part_1(self, app): # Higher groups should still be called assert self.count == 42 - async def test_error_in_handler_part_2(self, app, bot): + async def test_error_in_handler_part_2(self, app, test_bot): passed = [] err = Exception("General exception") @@ -751,7 +764,8 @@ async def error(u, c): ], ), ) - update.message.set_bot(bot) + await test_bot.initialize() + update.message.set_bot(test_bot) async with app: # If an unhandled exception was caught, no further handlers from the same group should @@ -830,7 +844,7 @@ async def test_error_handler_that_raises_errors(self, app, caplog): await app.stop() - async def test_custom_context_error_handler(self, bot): + async def test_custom_context_error_handler(self, test_bot): async def error_handler(_, context): self.received = ( type(context), @@ -841,7 +855,7 @@ async def error_handler(_, context): application = ( ApplicationBuilder() - .token(bot.token) + .bot(test_bot) .context_types( ContextTypes( context=CustomContext, bot_data=int, user_data=float, chat_data=complex @@ -859,7 +873,7 @@ async def error_handler(_, context): await asyncio.sleep(0.05) assert self.received == (CustomContext, float, complex, int) - async def test_custom_context_handler_callback(self, bot): + async def test_custom_context_handler_callback(self, test_bot): def callback(_, context): self.received = ( type(context), @@ -870,7 +884,7 @@ def callback(_, context): application = ( ApplicationBuilder() - .token(bot.token) + .bot(test_bot) .context_types( ContextTypes( context=CustomContext, bot_data=int, user_data=float, chat_data=complex @@ -1034,12 +1048,13 @@ async def error_handler(update, context): ), "incorrect stacklevel!" @pytest.mark.parametrize(["block", "expected_output"], [(False, 0), (True, 5)]) - async def test_default_block_error_handler(self, bot, block, expected_output): + async def test_default_block_error_handler(self, bot_info, block, expected_output): async def error_handler(*args, **kwargs): await asyncio.sleep(0.1) self.count = 5 - app = Application.builder().token(bot.token).defaults(Defaults(block=block)).build() + bot = make_bot(bot_info, defaults=Defaults(block=block)) + app = Application.builder().bot(bot).build() async with app: app.add_handler(TypeHandler(object, self.callback_raise_error)) app.add_error_handler(error_handler) @@ -1050,8 +1065,9 @@ async def error_handler(*args, **kwargs): assert self.count == 5 @pytest.mark.parametrize(["block", "expected_output"], [(False, 0), (True, 5)]) - async def test_default_block_handler(self, bot, block, expected_output): - app = Application.builder().token(bot.token).defaults(Defaults(block=block)).build() + async def test_default_block_handler(self, bot_info, block, expected_output): + bot = make_bot(bot_info, defaults=Defaults(block=block)) + app = Application.builder().bot(bot).build() async with app: app.add_handler(TypeHandler(object, self.callback_set_count(5, sleep=0.1))) await app.process_update(1) @@ -1296,10 +1312,10 @@ async def callback(u, c): await app.stop() @pytest.mark.parametrize("concurrent_updates", (15, 50, 100)) - async def test_concurrent_updates(self, bot, concurrent_updates): + async def test_concurrent_updates(self, test_bot, concurrent_updates): # We don't test with `True` since the large number of parallel coroutines quickly leads # to test instabilities - app = Application.builder().token(bot.token).concurrent_updates(concurrent_updates).build() + app = Application.builder().bot(test_bot).concurrent_updates(concurrent_updates).build() events = {i: asyncio.Event() for i in range(app.concurrent_updates + 10)} queue = asyncio.Queue() for event in events.values(): @@ -1330,8 +1346,8 @@ async def callback(u, c): await app.stop() - async def test_concurrent_updates_done_on_shutdown(self, bot): - app = Application.builder().token(bot.token).concurrent_updates(True).build() + async def test_concurrent_updates_done_on_shutdown(self, test_bot): + app = Application.builder().bot(test_bot).concurrent_updates(True).build() event = asyncio.Event() async def callback(update, context): @@ -1415,7 +1431,7 @@ def thread_target(): platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_polling_post_init(self, bot, monkeypatch): + def test_run_polling_post_init(self, test_bot, monkeypatch): events = [] async def get_updates(*args, **kwargs): @@ -1436,7 +1452,7 @@ def thread_target(): async def post_init(app: Application) -> None: events.append("post_init") - app = Application.builder().token(bot.token).post_init(post_init).build() + app = Application.builder().bot(test_bot).post_init(post_init).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "get_updates", get_updates) monkeypatch.setattr( @@ -1458,7 +1474,7 @@ async def post_init(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_polling_post_shutdown(self, bot, monkeypatch): + def test_run_polling_post_shutdown(self, test_bot, monkeypatch): events = [] async def get_updates(*args, **kwargs): @@ -1479,7 +1495,7 @@ def thread_target(): async def post_shutdown(app: Application) -> None: events.append("post_shutdown") - app = Application.builder().token(bot.token).post_shutdown(post_shutdown).build() + app = Application.builder().bot(test_bot).post_shutdown(post_shutdown).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "get_updates", get_updates) monkeypatch.setattr( @@ -1633,7 +1649,7 @@ def thread_target(): platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_post_init(self, bot, monkeypatch): + def test_run_webhook_post_init(self, test_bot, monkeypatch): events = [] async def delete_webhook(*args, **kwargs): @@ -1660,7 +1676,7 @@ def thread_target(): async def post_init(app: Application) -> None: events.append("post_init") - app = Application.builder().token(bot.token).post_init(post_init).build() + app = Application.builder().bot(test_bot).post_init(post_init).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "set_webhook", set_webhook) monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) @@ -1693,7 +1709,7 @@ async def post_init(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_post_shutdown(self, bot, monkeypatch): + def test_run_webhook_post_shutdown(self, test_bot, monkeypatch): events = [] async def delete_webhook(*args, **kwargs): @@ -1720,7 +1736,7 @@ def thread_target(): async def post_shutdown(app: Application) -> None: events.append("post_shutdown") - app = Application.builder().token(bot.token).post_shutdown(post_shutdown).build() + app = Application.builder().bot(test_bot).post_shutdown(post_shutdown).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "set_webhook", set_webhook) monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) @@ -1757,7 +1773,7 @@ async def post_shutdown(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_parameters_passing(self, bot, monkeypatch): + def test_run_webhook_parameters_passing(self, test_bot, monkeypatch): # Check that we pass them correctly async def start_webhook(_, **kwargs): @@ -1772,7 +1788,7 @@ async def stop(_, **kwargs): monkeypatch.setattr(Updater, "start_webhook", start_webhook) monkeypatch.setattr(Updater, "stop", stop) - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() app_signature = inspect.signature(app.run_webhook) for name, param in updater_signature.parameters.items(): @@ -1813,8 +1829,8 @@ def thread_target(): assert set(self.received.keys()) == set(expected.keys()) assert self.received == expected - def test_run_without_updater(self, bot): - app = ApplicationBuilder().token(bot.token).updater(None).build() + def test_run_without_updater(self, test_bot): + app = ApplicationBuilder().bot(test_bot).updater(None).build() with pytest.raises(RuntimeError, match="only available if the application has an Updater"): app.run_webhook() @@ -1824,7 +1840,7 @@ def test_run_without_updater(self, bot): @pytest.mark.parametrize("method", ["start", "initialize"]) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - def test_run_error_in_application(self, bot, monkeypatch, method): + def test_run_error_in_application(self, test_bot, monkeypatch, method): shutdowns = [] async def raise_method(*args, **kwargs): @@ -1845,7 +1861,7 @@ def _after_shutdown(*args, **kwargs): monkeypatch.setattr( Updater, "shutdown", call_after(Updater.shutdown, after_shutdown("updater")) ) - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() with pytest.raises(RuntimeError, match="Test Exception"): app.run_polling(close_loop=False) @@ -1860,7 +1876,7 @@ def _after_shutdown(*args, **kwargs): @pytest.mark.parametrize("method", ["start_polling", "start_webhook"]) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - def test_run_error_in_updater(self, bot, monkeypatch, method): + def test_run_error_in_updater(self, test_bot, monkeypatch, method): shutdowns = [] async def raise_method(*args, **kwargs): @@ -1881,7 +1897,7 @@ def _after_shutdown(*args, **kwargs): monkeypatch.setattr( Updater, "shutdown", call_after(Updater.shutdown, after_shutdown("updater")) ) - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() with pytest.raises(RuntimeError, match="Test Exception"): if "polling" in method: app.run_polling(close_loop=False) @@ -1897,12 +1913,12 @@ def _after_shutdown(*args, **kwargs): reason="Only really relevant on windows", ) @pytest.mark.parametrize("method", ["start_polling", "start_webhook"]) - def test_run_stop_signal_warning_windows(self, bot, method, recwarn, monkeypatch): + def test_run_stop_signal_warning_windows(self, test_bot, method, recwarn, monkeypatch): async def raise_method(*args, **kwargs): raise RuntimeError("Prevent Actually Running") monkeypatch.setattr(Application, "initialize", raise_method) - app = ApplicationBuilder().token(bot.token).build() + app = ApplicationBuilder().bot(test_bot).build() with pytest.raises(RuntimeError, match="Prevent Actually Running"): if "polling" in method: @@ -1942,11 +1958,10 @@ def signal_handler_test(*args, **kwargs): loop = asyncio.get_event_loop() monkeypatch.setattr(loop, "add_signal_handler", signal_handler_test) - async def abort_app(): - await asyncio.sleep(2) + def abort_app(): raise SystemExit - loop.create_task(abort_app()) + loop.call_later(0.5, abort_app) app.run_polling(close_loop=False) @@ -1956,7 +1971,7 @@ async def abort_app(): assert received_signals == [signal.SIGINT, signal.SIGTERM, signal.SIGABRT] received_signals.clear() - loop.create_task(abort_app()) + loop.call_later(0.5, abort_app) app.run_webhook(port=49152, webhook_url="example.com", close_loop=False) if platform.system() == "Windows": From 256758d012b4d7dc873ba17026116c3b18db4880 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 03:02:17 +0530 Subject: [PATCH 09/77] remove pytest.mark.timeout from requirements The last commit addresses the root cause of its addition, so now we don't need this :) --- requirements-dev.txt | 1 - tests/test_application.py | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index c886b6f540d..b06bf6bc29d 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,7 +2,6 @@ pre-commit pytest==7.2.0 pytest-asyncio==0.20.3 -pytest-timeout==2.1.0 # used to timeout tests pytest-xdist==3.1.0 # xdist runs tests in parallel flaky # Used for flaky tests (flaky decorator) diff --git a/tests/test_application.py b/tests/test_application.py index 13917cf2d0d..9e87e6055cb 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -1944,7 +1944,6 @@ async def raise_method(*args, **kwargs): assert len(recwarn) == 0 - @pytest.mark.timeout(6) def test_signal_handlers(self, app, monkeypatch): # this test should make sure that signal handlers are set by default on Linux + Mac, # and not on Windows. From e2cc5367c1b8bc1859dc42376390c52b423c7807 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 04:30:46 +0530 Subject: [PATCH 10/77] Fix: 2 app & job tests were not a coroutine function --- tests/test_application.py | 4 ++-- tests/test_jobqueue.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_application.py b/tests/test_application.py index 9e87e6055cb..a2659d8eab6 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -481,7 +481,7 @@ async def test_one_context_per_update(self, app): async def one(update, context): self.received = context - def two(update, context): + async def two(update, context): if update.message.text == "test": if context is not self.received: pytest.fail("Expected same context object, got different") @@ -874,7 +874,7 @@ async def error_handler(_, context): assert self.received == (CustomContext, float, complex, int) async def test_custom_context_handler_callback(self, test_bot): - def callback(_, context): + async def callback(_, context): self.received = ( type(context), type(context.user_data), diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 11020372dfc..3945666c934 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -566,7 +566,7 @@ async def test_custom_context(self, bot, job_queue): ) job_queue.set_application(application) - def callback(context): + async def callback(context): self.result = ( type(context), context.user_data, From 0a7d03beeaabf9880309bd9e012c526fd0fd09b5 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 05:05:01 +0530 Subject: [PATCH 11/77] don't close event loop after session end This was done as when running pytest with -x, this error is emitted. Not doing this seems to fix the problem. However this could backfire on python versions older than 3.10.6 --- tests/conftest.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index a07bc1b2000..0911e242914 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -102,11 +102,6 @@ def event_loop(request): # loop.close() # instead of closing here, do that at the every end of the test session -# Related to the above, see https://stackoverflow.com/a/67307042/10606962 -def pytest_sessionfinish(session, exitstatus): - asyncio.get_event_loop().close() - - @pytest.fixture(scope="session") def bot_info(): return get_bot() From 40ad364b0c1a402b268a657d5de3b8281b69dbab Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 19:57:28 +0530 Subject: [PATCH 12/77] use DictExtBot in more places, where appropriate. --- tests/test_basepersistence.py | 24 +++++++++++++++--------- tests/test_bot.py | 8 ++++---- tests/test_conversationhandler.py | 8 +++----- tests/test_jobqueue.py | 6 +++--- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/tests/test_basepersistence.py b/tests/test_basepersistence.py index 781c1583d1d..8885371d459 100644 --- a/tests/test_basepersistence.py +++ b/tests/test_basepersistence.py @@ -43,7 +43,7 @@ filters, ) from telegram.warnings import PTBUserWarning -from tests.conftest import DictApplication, make_message_update +from tests.conftest import DictApplication, make_bot, make_message_update class HandlerStates(int, enum.Enum): @@ -227,7 +227,11 @@ class PappInput(NamedTuple): def build_papp( - token: str, store_data: dict = None, update_interval: float = None, fill_data: bool = False + bot_info: dict = None, + token: str = None, + store_data: dict = None, + update_interval: float = None, + fill_data: bool = False, ) -> Application: store_data = PersistenceInput(**(store_data or {})) if update_interval is not None: @@ -237,12 +241,15 @@ def build_papp( else: persistence = TrackingPersistence(store_data=store_data, fill_data=fill_data) + if bot_info is not None: + bot = make_bot(bot_info, arbitrary_callback_data=True) + else: + bot = make_bot(token=token, arbitrary_callback_data=True) return ( ApplicationBuilder() - .token(token) + .bot(bot) .persistence(persistence) .application_class(DictApplication) - .arbitrary_callback_data(True) .build() ) @@ -252,7 +259,7 @@ def build_conversation_handler(name: str, persistent: bool = True) -> BaseHandle @pytest.fixture(scope="function") -def papp(request, bot) -> Application: +def papp(request, bot_info) -> Application: papp_input = request.param store_data = {} if papp_input.bot_data is not None: @@ -265,7 +272,7 @@ def papp(request, bot) -> Application: store_data["callback_data"] = papp_input.callback_data app = build_papp( - bot.token, + bot_info=bot_info, store_data=store_data, update_interval=papp_input.update_interval, fill_data=papp_input.fill_data, @@ -998,7 +1005,7 @@ async def test_migrate_chat_data(self, papp: Application): assert papp.persistence.dropped_chat_ids == {1: 1} assert papp.persistence.updated_chat_ids == {2: 1} - async def test_errors_while_persisting(self, bot, caplog): + async def test_errors_while_persisting(self, bot_info, caplog): class ErrorPersistence(TrackingPersistence): def raise_error(self): raise Exception("PersistenceError") @@ -1032,8 +1039,7 @@ async def error(update, context): app = ( ApplicationBuilder() - .token(bot.token) - .arbitrary_callback_data(True) + .bot(make_bot(bot_info, arbitrary_callback_data=True)) .persistence(ErrorPersistence()) .build() ) diff --git a/tests/test_bot.py b/tests/test_bot.py index 23b80175dab..05e55506dbe 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -261,8 +261,8 @@ async def test_log_decorator(self, bot: DictExtBot, caplog): "acd_in,maxsize", [(True, 1024), (False, 1024), (0, 0), (None, None)], ) - async def test_callback_data_maxsize(self, bot, acd_in, maxsize): - async with ExtBot(bot.token, arbitrary_callback_data=acd_in) as acd_bot: + async def test_callback_data_maxsize(self, bot_info, acd_in, maxsize): + async with make_bot(bot_info, arbitrary_callback_data=acd_in) as acd_bot: if acd_in is not False: assert acd_bot.callback_data_cache.maxsize == maxsize else: @@ -1445,7 +1445,7 @@ async def initialize(*args, **kwargs): async def stop(*args, **kwargs): self.test_flag.append("stop") - temp_bot = Bot(token=bot.token) + temp_bot = DictBot(token=bot.token) orig_stop = temp_bot.request.shutdown try: @@ -1472,7 +1472,7 @@ async def shutdown(*args, **kwargs): monkeypatch.setattr(HTTPXRequest, "initialize", initialize) monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) - test_bot = Bot(bot.token) + test_bot = DictBot(bot.token) await test_bot.initialize() await test_bot.initialize() await test_bot.initialize() diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index 93f64963e08..2f16f94301d 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -24,7 +24,6 @@ import pytest from telegram import ( - Bot, CallbackQuery, Chat, ChosenInlineResult, @@ -45,7 +44,6 @@ CommandHandler, ConversationHandler, Defaults, - ExtBot, InlineQueryHandler, JobQueue, MessageHandler, @@ -59,7 +57,7 @@ filters, ) from telegram.warnings import PTBUserWarning -from tests.conftest import make_command_message +from tests.conftest import DictBot, make_bot, make_command_message @pytest.fixture(scope="class") @@ -2114,7 +2112,7 @@ async def test_conversation_handler_block_dont_override(self, app): @pytest.mark.parametrize("handler_block", [True, False, None]) @pytest.mark.parametrize("ext_bot", [True, False], ids=["ExtBot", "Bot"]) async def test_blocking_resolution_order( - self, bot, default_block, ch_block, handler_block, ext_bot + self, bot_info, default_block, ch_block, handler_block, ext_bot ): event = asyncio.Event() @@ -2151,7 +2149,7 @@ async def callback(_, __): fallbacks=[fallback], ) - bot = ExtBot(bot.token, defaults=defaults) if ext_bot else Bot(bot.token) + bot = make_bot(bot_info, defaults=defaults) if ext_bot else DictBot(bot_info["token"]) app = ApplicationBuilder().bot(bot).build() app.add_handler(conv_handler) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 3945666c934..16d80216f27 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -27,7 +27,7 @@ import pytest from telegram.ext import ApplicationBuilder, CallbackContext, ContextTypes, Job, JobQueue -from tests.conftest import TEST_WITH_OPT_DEPS +from tests.conftest import TEST_WITH_OPT_DEPS, make_bot if TEST_WITH_OPT_DEPS: import pytz @@ -266,8 +266,8 @@ async def test_error(self, job_queue): await asyncio.sleep(0.3) assert self.result == 1 - async def test_in_application(self, bot): - app = ApplicationBuilder().token(bot.token).build() + async def test_in_application(self, bot_info): + app = ApplicationBuilder().bot(make_bot(bot_info)).build() async with app: assert not app.job_queue.scheduler.running await app.start() From fb550d16c904781af23c93219e5263d470c53dbe Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 20:32:00 +0530 Subject: [PATCH 13/77] rearrange test methods in TestBot again this is based on whether the test calls get_me indirectly or not --- tests/test_bot.py | 110 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index 05e55506dbe..d9702158d66 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -203,6 +203,56 @@ def test_slot_behaviour(self, bot_class, bot, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): + test_flag = [] + + async def initialize(*args, **kwargs): + nonlocal test_flag + test_flag = ["initialize"] + + async def stop(*args, **kwargs): + nonlocal test_flag + test_flag.append("stop") + + temp_bot = DictBot(token=bot.token) + orig_stop = temp_bot.request.shutdown + + try: + monkeypatch.setattr(temp_bot.request, "initialize", initialize) + monkeypatch.setattr(temp_bot.request, "shutdown", stop) + await temp_bot.initialize() + assert test_flag == ["initialize"] + assert temp_bot.bot == bot.bot + + await temp_bot.shutdown() + assert test_flag == ["initialize", "stop"] + finally: + await orig_stop() + + async def test_multiple_inits_and_shutdowns(self, bot, monkeypatch): + self.received = defaultdict(int) + + async def initialize(*args, **kwargs): + self.received["init"] += 1 + + async def shutdown(*args, **kwargs): + self.received["shutdown"] += 1 + + monkeypatch.setattr(HTTPXRequest, "initialize", initialize) + monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) + + test_bot = DictBot(bot.token) + await test_bot.initialize() + await test_bot.initialize() + await test_bot.initialize() + await test_bot.shutdown() + await test_bot.shutdown() + await test_bot.shutdown() + + # 2 instead of 1 since we have to request objects for each bot + assert self.received["init"] == 2 + assert self.received["shutdown"] == 2 + async def test_context_manager(self, monkeypatch, bot): test_flag = [] @@ -284,11 +334,6 @@ async def post(url, request_data: RequestData, *args, **kwargs): 123, "text", api_kwargs={"unknown_kwarg_1": 7, "unknown_kwarg_2": 5} ) - async def test_invalid_token_server_response(self): - with pytest.raises(InvalidToken, match="The token `12` was rejected by the server."): - async with ExtBot(token="12"): - pass - @pytest.mark.parametrize( "attribute", [ @@ -1432,57 +1477,10 @@ class TestBotReq: is tested in `test_callbackdatacache` """ - test_flag = None - - @pytest.fixture(scope="function", autouse=True) - def reset(self): - self.test_flag = None - - async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): - async def initialize(*args, **kwargs): - self.test_flag = ["initialize"] - - async def stop(*args, **kwargs): - self.test_flag.append("stop") - - temp_bot = DictBot(token=bot.token) - orig_stop = temp_bot.request.shutdown - - try: - monkeypatch.setattr(temp_bot.request, "initialize", initialize) - monkeypatch.setattr(temp_bot.request, "shutdown", stop) - await temp_bot.initialize() - assert self.test_flag == ["initialize"] - assert temp_bot.bot == bot.bot - - await temp_bot.shutdown() - assert self.test_flag == ["initialize", "stop"] - finally: - await orig_stop() - - async def test_multiple_inits_and_shutdowns(self, bot, monkeypatch): - self.received = defaultdict(int) - - async def initialize(*args, **kwargs): - self.received["init"] += 1 - - async def shutdown(*args, **kwargs): - self.received["shutdown"] += 1 - - monkeypatch.setattr(HTTPXRequest, "initialize", initialize) - monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) - - test_bot = DictBot(bot.token) - await test_bot.initialize() - await test_bot.initialize() - await test_bot.initialize() - await test_bot.shutdown() - await test_bot.shutdown() - await test_bot.shutdown() - - # 2 instead of 1 since we have to request objects for each bot - assert self.received["init"] == 2 - assert self.received["shutdown"] == 2 + async def test_invalid_token_server_response(self): + with pytest.raises(InvalidToken, match="The token `12` was rejected by the server."): + async with ExtBot(token="12"): + pass async def test_multiple_init_cycles(self, bot): # nothing really to assert - this should just not fail From 58aaf04a44330ad27ad4acea02e901e5018394c5 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 20:49:02 +0530 Subject: [PATCH 14/77] Don't rerun tests if they have xfailed --- tests/conftest.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 0911e242914..c817c02d239 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -69,11 +69,20 @@ def pytest_collection_modifyitems(items: List[pytest.Item]): and parent.name.endswith("Req") and not parent.get_closest_marker(name="flaky") ): - parent.add_marker(pytest.mark.flaky(3, 1)) + parent.add_marker(pytest.mark.flaky(3, 1, rerun_filter=no_rerun_after_xfail_or_flood)) elif parent.name.endswith("NoReq") and not parent.get_closest_marker(name="no_req"): parent.add_marker(pytest.mark.no_req) +def no_rerun_after_xfail_or_flood(error, name, test: pytest.Function, plugin): + """Don't rerun tests that have xfailed when marked with xfail, or when we hit a flood limit.""" + xfail_present = test.get_closest_marker(name="xfail") + did_we_flood = "flood" in getattr(error[1], "msg", "") # _pytest.outcomes.XFailed has 'msg' + if xfail_present or did_we_flood: + return False + return True + + GITHUB_ACTION = os.getenv("GITHUB_ACTION", False) if GITHUB_ACTION: From b46a4bbb3bc96ec24e165873fad20ad36da3c518 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 13 Dec 2022 21:17:37 +0530 Subject: [PATCH 15/77] Make the bot_methods decorator not return camelCase names by default --- tests/test_bot.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index d9702158d66..3a42be43ea5 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -146,7 +146,7 @@ def inline_results(): ) -def bot_methods(ext_bot=True): +def bot_methods(ext_bot=True, include_camel_case=False): arg_values = [] ids = [] non_api_methods = [ @@ -166,6 +166,8 @@ def bot_methods(ext_bot=True): for name, attribute in inspect.getmembers(cls, predicate=inspect.isfunction): if name.startswith("_") or name in non_api_methods: continue + if not include_camel_case and any(x.isupper() for x in name): + continue arg_values.append((cls, name, attribute)) ids.append(f"{cls.__name__}.{name}") @@ -1433,9 +1435,6 @@ def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): @bot_methods() def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): """Check that all bot methods are defined as async def ...""" - # not islower() skips the camelcase aliases - if not bot_method_name.islower(): - return # unfortunately `inspect.iscoroutinefunction` doesn't do the trick directly, # as the @_log decorator interferes source = "".join(inspect.getsourcelines(bot_method)[0]) From dea47cf2e77331160bff68097e0a152f6a5a548e Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 14 Dec 2022 02:33:07 +0530 Subject: [PATCH 16/77] small optimization: Make test_coroutine_functions use inspect.iscoroutinefunction The limitation of that function is fixed by using the `__wrapped__` attribute --- tests/test_bot.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index 3a42be43ea5..2e4b03ac3ee 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1433,14 +1433,10 @@ def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}" @bot_methods() - def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): + def test_coroutine_functions(self, bot_class, bot_method_name, bot_method, monkeypatch): """Check that all bot methods are defined as async def ...""" - # unfortunately `inspect.iscoroutinefunction` doesn't do the trick directly, - # as the @_log decorator interferes - source = "".join(inspect.getsourcelines(bot_method)[0]) - assert ( - f"async def {bot_method_name}" in source - ), f"{bot_method_name} should be a coroutine function" + meth = getattr(bot_method, "__wrapped__", bot_method) + assert inspect.iscoroutinefunction(meth), f"{bot_method_name} must be a coroutine function" @bot_methods() def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): From 857949aa829098271d5e9fa34edd5f45c3c97de0 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 14 Dec 2022 20:30:05 +0530 Subject: [PATCH 17/77] Feat: Make some tests run concurrently via asyncio.gather/as_completed/create_task let's take full advantage of the lib now being async --- tests/test_animation.py | 12 +- tests/test_audio.py | 10 +- tests/test_bot.py | 342 ++++++++++++++++++++------------------- tests/test_chatphoto.py | 26 ++- tests/test_constants.py | 35 ++-- tests/test_contact.py | 11 +- tests/test_document.py | 8 +- tests/test_forum.py | 22 +-- tests/test_inputmedia.py | 63 ++++---- tests/test_invoice.py | 74 +++++---- tests/test_location.py | 11 +- tests/test_photo.py | 8 +- tests/test_sticker.py | 42 ++--- tests/test_venue.py | 9 +- tests/test_video.py | 8 +- tests/test_videonote.py | 8 +- tests/test_voice.py | 8 +- 17 files changed, 375 insertions(+), 322 deletions(-) diff --git a/tests/test_animation.py b/tests/test_animation.py index 3ccce4fba25..76b3544b711 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -332,12 +333,13 @@ async def test_send_animation_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_animation_default_protect_content(self, default_bot, chat_id, animation): - animation_protected = await default_bot.send_animation(chat_id, animation) - assert animation_protected.has_protected_content - ani_unprotected = await default_bot.send_animation( - chat_id, animation, protect_content=False + tasks = asyncio.gather( + default_bot.send_animation(chat_id, animation), + default_bot.send_animation(chat_id, animation, protect_content=False), ) - assert not ani_unprotected.has_protected_content + anim_protected, anim_unprotected = await tasks + assert anim_protected.has_protected_content + assert not anim_unprotected.has_protected_content async def test_resend(self, bot, chat_id, animation): message = await bot.send_animation(chat_id, animation.file_id) diff --git a/tests/test_audio.py b/tests/test_audio.py index 728cc53345d..187694b2245 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -311,9 +312,12 @@ async def test_send_audio_default_parse_mode_3(self, default_bot, chat_id, audio @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_audio_default_protect_content(self, default_bot, chat_id, audio): - protected_audio = await default_bot.send_audio(chat_id, audio) - assert protected_audio.has_protected_content - unprotected = await default_bot.send_audio(chat_id, audio, protect_content=False) + tasks = asyncio.gather( + default_bot.send_audio(chat_id, audio), + default_bot.send_audio(chat_id, audio, protect_content=False), + ) + protected, unprotected = await tasks + assert protected.has_protected_content assert not unprotected.has_protected_content async def test_error_send_empty_file(self, bot, chat_id): diff --git a/tests/test_bot.py b/tests/test_bot.py index 2e4b03ac3ee..30cdb64b32f 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1494,25 +1494,28 @@ async def test_forward_message(self, bot, chat_id, message): assert forward_message.forward_from.username == message.from_user.username assert isinstance(forward_message.forward_date, dtm.datetime) - async def test_forward_protected_message(self, bot, message, chat_id): - to_forward_protected = await bot.send_message( - chat_id, "cant forward me", protect_content=True + async def test_forward_protected_message(self, bot, chat_id): + tasks = asyncio.gather( + bot.send_message(chat_id, "cant forward me", protect_content=True), + bot.send_message(chat_id, "forward me", protect_content=False), ) - assert to_forward_protected.has_protected_content - - with pytest.raises(BadRequest, match="can't be forwarded"): - await to_forward_protected.forward(chat_id) + to_forward_protected, to_forward_unprotected = await tasks - to_forward_unprotected = await bot.send_message( - chat_id, "forward me", protect_content=False - ) + assert to_forward_protected.has_protected_content assert not to_forward_unprotected.has_protected_content + forwarded_but_now_protected = await to_forward_unprotected.forward( chat_id, protect_content=True ) assert forwarded_but_now_protected.has_protected_content - with pytest.raises(BadRequest, match="can't be forwarded"): - await forwarded_but_now_protected.forward(chat_id) + + tasks = asyncio.gather( + to_forward_protected.forward(chat_id), + forwarded_but_now_protected.forward(chat_id), + return_exceptions=True, + ) + result = await tasks + assert all("can't be forwarded" in str(exc) for exc in result) async def test_delete_message(self, bot, chat_id): message = await bot.send_message(chat_id, text="will be deleted") @@ -1539,17 +1542,25 @@ async def test_send_venue(self, bot, chat_id): google_place_id = "google_place id" google_place_type = "google_place type" - message = await bot.send_venue( - chat_id=chat_id, - title=title, - address=address, - latitude=latitude, - longitude=longitude, - foursquare_id=foursquare_id, - foursquare_type=foursquare_type, - protect_content=True, + tasks = asyncio.gather( + *( + bot.send_venue( + chat_id=chat_id, + title=title, + address=address, + latitude=latitude, + longitude=longitude, + protect_content=True, + **i, + ) + for i in ( + {"foursquare_id": foursquare_id, "foursquare_type": foursquare_type}, + {"google_place_id": google_place_id, "google_place_type": google_place_type}, + ) + ), ) + message, message2 = await tasks assert message.venue assert message.venue.title == title assert message.venue.address == address @@ -1561,27 +1572,16 @@ async def test_send_venue(self, bot, chat_id): assert message.venue.google_place_type is None assert message.has_protected_content - message = await bot.send_venue( - chat_id=chat_id, - title=title, - address=address, - latitude=latitude, - longitude=longitude, - google_place_id=google_place_id, - google_place_type=google_place_type, - protect_content=True, - ) - - 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 - assert message.venue.google_place_id == google_place_id - assert message.venue.google_place_type == google_place_type - assert message.venue.foursquare_id is None - assert message.venue.foursquare_type is None - assert message.has_protected_content + assert message2.venue + assert message2.venue.title == title + assert message2.venue.address == address + assert message2.venue.location.latitude == latitude + assert message2.venue.location.longitude == longitude + assert message2.venue.google_place_id == google_place_id + assert message2.venue.google_place_type == google_place_type + assert message2.venue.foursquare_id is None + assert message2.venue.foursquare_type is None + assert message2.has_protected_content async def test_send_contact(self, bot, chat_id): phone_number = "+11234567890" @@ -1617,16 +1617,36 @@ async def test_send_contact(self, bot, chat_id): async def test_send_and_stop_poll(self, bot, super_group_id, reply_markup): question = "Is this a test?" answers = ["Yes", "No", "Maybe"] - message = await bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - is_anonymous=False, - allows_multiple_answers=True, - read_timeout=60, - protect_content=True, + explanation = "[Here is a link](https://google.com)" + explanation_entities = [ + MessageEntity(MessageEntity.TEXT_LINK, 0, 14, url="https://google.com") + ] + + poll_task = asyncio.create_task( + bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + is_anonymous=False, + allows_multiple_answers=True, + read_timeout=60, + protect_content=True, + ) + ) + quiz_task = asyncio.create_task( + bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation, + explanation_parse_mode=ParseMode.MARKDOWN_V2, + ) ) + message = await poll_task assert message.poll assert message.poll.question == question assert message.poll.options[0].text == answers[0] @@ -1657,25 +1677,13 @@ async def test_send_and_stop_poll(self, bot, super_group_id, reply_markup): assert poll.question == question assert poll.total_voter_count == 0 - explanation = "[Here is a link](https://google.com)" - explanation_entities = [ - MessageEntity(MessageEntity.TEXT_LINK, 0, 14, url="https://google.com") - ] - message_quiz = await bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation, - explanation_parse_mode=ParseMode.MARKDOWN_V2, - ) + message_quiz = await quiz_task assert message_quiz.poll.correct_option_id == 2 assert message_quiz.poll.type == Poll.QUIZ assert message_quiz.poll.is_closed assert message_quiz.poll.explanation == "Here is a link" assert message_quiz.poll.explanation_entities == tuple(explanation_entities) + assert poll_task.done() and quiz_task.done() @pytest.mark.parametrize( ["open_period", "close_date"], [(5, None), (None, True)], ids=["open_period", "close_date"] @@ -1770,47 +1778,34 @@ async def test_send_poll_default_parse_mode(self, default_bot, super_group_id): question = "Is this a test?" answers = ["Yes", "No", "Maybe"] - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, + tasks = asyncio.gather( + *( + default_bot.send_poll( + chat_id=super_group_id, + question=question, + options=answers, + type=Poll.QUIZ, + correct_option_id=2, + is_closed=True, + explanation=explanation_markdown, + **i, + ) + for i in ({}, {"explanation_parse_mode": None}, {"explanation_parse_mode": "HTML"}) + ), ) - assert message.poll.explanation == explanation - assert message.poll.explanation_entities == ( + message1, message2, message3 = await tasks + assert message1.poll.explanation == explanation + assert message1.poll.explanation_entities == ( MessageEntity(MessageEntity.ITALIC, 0, 6), MessageEntity(MessageEntity.BOLD, 7, 4), MessageEntity(MessageEntity.CODE, 12, 4), ) - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode=None, - ) - assert message.poll.explanation == explanation_markdown - assert message.poll.explanation_entities == () + assert message2.poll.explanation == explanation_markdown + assert message2.poll.explanation_entities == () - message = await default_bot.send_poll( - chat_id=super_group_id, - question=question, - options=answers, - type=Poll.QUIZ, - correct_option_id=2, - is_closed=True, - explanation=explanation_markdown, - explanation_parse_mode="HTML", - ) - assert message.poll.explanation == explanation_markdown - assert message.poll.explanation_entities == () + assert message3.poll.explanation == explanation_markdown + assert message3.poll.explanation_entities == () @pytest.mark.parametrize( "default_bot,custom", @@ -1856,11 +1851,12 @@ async def test_send_poll_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_poll_default_protect_content(self, chat_id, default_bot): - protected_poll = await default_bot.send_poll(chat_id, "Test", ["1", "2"]) - assert protected_poll.has_protected_content - unprotect_poll = await default_bot.send_poll( - chat_id, "test", ["1", "2"], protect_content=False + tasks = asyncio.gather( + default_bot.send_poll(chat_id, "Test", ["1", "2"]), + default_bot.send_poll(chat_id, "test", ["1", "2"], protect_content=False), ) + protected_poll, unprotect_poll = await tasks + assert protected_poll.has_protected_content assert not unprotect_poll.has_protected_content @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI + [None]) @@ -1909,9 +1905,11 @@ async def test_send_dice_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_dice_default_protect_content(self, chat_id, default_bot): - protected_dice = await default_bot.send_dice(chat_id) + tasks = asyncio.gather( + default_bot.send_dice(chat_id), default_bot.send_dice(chat_id, protect_content=False) + ) + protected_dice, unprotected_dice = await tasks assert protected_dice.has_protected_content - unprotected_dice = await default_bot.send_dice(chat_id, protect_content=False) assert not unprotected_dice.has_protected_content @pytest.mark.parametrize("chat_action", list(ChatAction)) @@ -2625,49 +2623,43 @@ async def test_set_chat_description(self, bot, channel_id): assert await bot.set_chat_description(channel_id, "Time: " + str(time.time())) async def test_pin_and_unpin_message(self, bot, super_group_id): - message1 = await bot.send_message(super_group_id, text="test_pin_message_1") - message2 = await bot.send_message(super_group_id, text="test_pin_message_2") - message3 = await bot.send_message(super_group_id, text="test_pin_message_3") - - assert await bot.pin_chat_message( - chat_id=super_group_id, - message_id=message1.message_id, - disable_notification=True, - read_timeout=10, - ) - await asyncio.sleep(1) - - await bot.pin_chat_message( - chat_id=super_group_id, - message_id=message2.message_id, - disable_notification=True, - read_timeout=10, - ) - await bot.pin_chat_message( - chat_id=super_group_id, - message_id=message3.message_id, - disable_notification=True, - read_timeout=10, - ) - await asyncio.sleep(1) - - chat = await bot.get_chat(super_group_id) - assert chat.pinned_message == message3 - - assert await bot.unpin_chat_message( - super_group_id, - message_id=message2.message_id, - read_timeout=10, - ) - assert await bot.unpin_chat_message( - super_group_id, - read_timeout=10, - ) - - assert await bot.unpin_all_chat_messages( - super_group_id, - read_timeout=10, + messages = [] # contains the Messages we sent + pinned_messages_tasks = set() # contains the asyncio.Tasks that pin the messages + + # Let's send 3 messages so we can pin them + awaitables = {bot.send_message(super_group_id, f"test_pin_message_{i}") for i in range(3)} + + # We will pin the messages immediately after sending them + for sending_msg in asyncio.as_completed(awaitables): # as_completed sends the messages + msg = await sending_msg + coro = bot.pin_chat_message(super_group_id, msg.message_id, True, read_timeout=10) + pinned_messages_tasks.add(asyncio.create_task(coro)) # start pinning the message + messages.append(msg) + + assert len(messages) == 3 # Check if we sent 3 messages + + assert all([await i for i in pinned_messages_tasks]) # Check if we pinned 3 messages + assert all([i.done() for i in pinned_messages_tasks]) # Check if all tasks are done + + chat = await bot.get_chat(super_group_id) # get the chat to check the pinned message + assert chat.pinned_message in messages + + # Determine which message is not the most recently pinned + for old_pin_msg in messages: + if chat.pinned_message != old_pin_msg: + break + + # Test unpinning our messages + tasks = asyncio.gather( + bot.unpin_chat_message( # unpins any message except the most recent + chat_id=super_group_id, # because we don't want to accidentally unpin the same msg + message_id=old_pin_msg.message_id, # twice + read_timeout=10, + ), + bot.unpin_chat_message(chat_id=super_group_id, read_timeout=10), # unpins most recent ) + assert all(await tasks) + assert await bot.unpin_all_chat_messages(super_group_id, read_timeout=10) # get_sticker_set, upload_sticker_file, create_new_sticker_set, add_sticker_to_set, # set_sticker_position_in_set, delete_sticker_from_set and get_custom_emoji_stickers @@ -2693,24 +2685,30 @@ async def test_send_message_default_parse_mode(self, default_bot, chat_id): test_string = "Italic Bold Code" test_markdown_string = "_Italic_ *Bold* `Code`" - message = await default_bot.send_message(chat_id, test_markdown_string) - assert message.text_markdown == test_markdown_string - assert message.text == test_string + tasks = asyncio.gather( + *( + default_bot.send_message(chat_id, test_markdown_string, **i) + for i in ({}, {"parse_mode": None}, {"parse_mode": "HTML"}) + ) + ) + msg1, msg2, msg3 = await tasks + assert msg1.text_markdown == test_markdown_string + assert msg1.text == test_string - message = await default_bot.send_message(chat_id, test_markdown_string, parse_mode=None) - assert message.text == test_markdown_string - assert message.text_markdown == escape_markdown(test_markdown_string) + assert msg2.text == test_markdown_string + assert msg2.text_markdown == escape_markdown(test_markdown_string) - message = await default_bot.send_message(chat_id, test_markdown_string, parse_mode="HTML") - assert message.text == test_markdown_string - assert message.text_markdown == escape_markdown(test_markdown_string) + assert msg3.text == test_markdown_string + assert msg3.text_markdown == escape_markdown(test_markdown_string) @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_message_default_protect_content(self, default_bot, chat_id): - to_check = await default_bot.send_message(chat_id, "test") + tasks = asyncio.gather( + default_bot.send_message(chat_id, "test"), + default_bot.send_message(chat_id, "test", protect_content=False), + ) + to_check, no_protect = await tasks assert to_check.has_protected_content - - no_protect = await default_bot.send_message(chat_id, "test", protect_content=False) assert not no_protect.has_protected_content @pytest.mark.parametrize( @@ -2748,14 +2746,14 @@ async def test_send_message_default_allow_sending_without_reply( async def test_get_set_my_default_administrator_rights(self, bot): # Test that my default administrator rights for group are as all False - await bot.set_my_default_administrator_rights() + assert await bot.set_my_default_administrator_rights() # clear any set rights my_admin_rights_grp = await bot.get_my_default_administrator_rights() assert isinstance(my_admin_rights_grp, ChatAdministratorRights) assert all(not getattr(my_admin_rights_grp, at) for at in my_admin_rights_grp.__slots__) # Test setting my default admin rights for channel my_rights = ChatAdministratorRights.all_rights() - await bot.set_my_default_administrator_rights(my_rights, for_channels=True) + assert await bot.set_my_default_administrator_rights(my_rights, for_channels=True) my_admin_rights_ch = await bot.get_my_default_administrator_rights(for_channels=True) assert my_admin_rights_ch.can_invite_users is my_rights.can_invite_users # tg bug? is_anonymous is False despite setting it True for channels: @@ -2780,20 +2778,20 @@ async def test_get_set_chat_menu_button(self, bot, chat_id): # Test setting our chat menu button to Webapp. my_menu = MenuButtonWebApp("click me!", WebAppInfo("https://telegram.org/")) - await bot.set_chat_menu_button(chat_id=chat_id, menu_button=my_menu) + assert await bot.set_chat_menu_button(chat_id=chat_id, menu_button=my_menu) menu_button = await bot.get_chat_menu_button(chat_id) assert isinstance(menu_button, MenuButtonWebApp) assert menu_button.type == MenuButtonType.WEB_APP assert menu_button.text == my_menu.text assert menu_button.web_app.url == my_menu.web_app.url - await bot.set_chat_menu_button(chat_id=chat_id, menu_button=MenuButtonDefault()) + assert await bot.set_chat_menu_button(chat_id=chat_id, menu_button=MenuButtonDefault()) menu_button = await bot.get_chat_menu_button(chat_id=chat_id) assert isinstance(menu_button, MenuButtonDefault) async def test_set_and_get_my_commands(self, bot): commands = [BotCommand("cmd1", "descr1"), ["cmd2", "descr2"]] - await bot.set_my_commands([]) + assert await bot.set_my_commands([]) assert await bot.get_my_commands() == () assert await bot.set_my_commands(commands) @@ -2808,26 +2806,32 @@ async def test_get_set_delete_my_commands_with_scope(self, bot, super_group_id, private_scope = BotCommandScopeChat(chat_id) # Set supergroup command list with lang code and check if the same can be returned from api - await bot.set_my_commands(group_cmds, scope=group_scope, language_code="en") + assert await bot.set_my_commands(group_cmds, scope=group_scope, language_code="en") gotten_group_cmds = await bot.get_my_commands(scope=group_scope, language_code="en") assert len(gotten_group_cmds) == len(group_cmds) assert gotten_group_cmds[0].command == group_cmds[0].command # Set private command list and check if same can be returned from the api - await bot.set_my_commands(private_cmds, scope=private_scope) + assert await bot.set_my_commands(private_cmds, scope=private_scope) gotten_private_cmd = await bot.get_my_commands(scope=private_scope) assert len(gotten_private_cmd) == len(private_cmds) assert gotten_private_cmd[0].command == private_cmds[0].command # Delete command list from that supergroup and private chat- - await bot.delete_my_commands(private_scope) - await bot.delete_my_commands(group_scope, "en") + tasks = asyncio.gather( + bot.delete_my_commands(private_scope), + bot.delete_my_commands(group_scope, "en"), + ) + assert all(await tasks) # Check if its been deleted- - deleted_priv_cmds = await bot.get_my_commands(scope=private_scope) - deleted_grp_cmds = await bot.get_my_commands(scope=group_scope, language_code="en") + tasks = asyncio.gather( + bot.get_my_commands(private_scope), + bot.get_my_commands(group_scope, "en"), + ) + deleted_priv_cmds, deleted_grp_cmds = await tasks assert len(deleted_grp_cmds) == 0 == len(group_cmds) - 1 assert len(deleted_priv_cmds) == 0 == len(private_cmds) - 1 diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index 1f745834a7e..a7c8320448b 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -17,6 +17,7 @@ # 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 asyncio import os from pathlib import Path @@ -157,23 +158,18 @@ async def test_get_and_download(self, bot, chat_photo): if jpg_file.is_file(): jpg_file.unlink() - new_file = await bot.get_file(chat_photo.small_file_id) + tasks = {bot.get_file(chat_photo.small_file_id), bot.get_file(chat_photo.big_file_id)} - assert new_file.file_unique_id == chat_photo.small_file_unique_id - assert new_file.file_path.startswith("https://") + for task in asyncio.as_completed(tasks): + file = await task + assert file.file_unique_id in ( + chat_photo.small_file_unique_id, + chat_photo.big_file_unique_id, + ) + assert file.file_path.startswith("https://") - await new_file.download_to_drive(jpg_file) - - assert jpg_file.is_file() - - new_file = await bot.get_file(chat_photo.big_file_id) - - assert new_file.file_unique_id == chat_photo.big_file_unique_id - assert new_file.file_path.startswith("https://") - - await new_file.download_to_drive(jpg_file) - - assert jpg_file.is_file() + await file.download_to_drive(jpg_file) + assert jpg_file.is_file() async def test_send_all_args( self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file diff --git a/tests/test_constants.py b/tests/test_constants.py index e7908b3bc8a..9bb816700d8 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -16,10 +16,9 @@ # # 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 asyncio import json -import pytest - from telegram import constants from telegram._utils.enum import IntEnum, StringEnum from telegram.error import BadRequest @@ -131,23 +130,23 @@ def test_bot_api_version_info(self): class TestConstantsReq: async def test_max_message_length(self, bot, chat_id): - await bot.send_message(chat_id=chat_id, text="a" * constants.MessageLimit.MAX_TEXT_LENGTH) - - with pytest.raises( - BadRequest, - match="Message is too long", - ): - await bot.send_message( - chat_id=chat_id, text="a" * (constants.MessageLimit.MAX_TEXT_LENGTH + 1) - ) + tasks = asyncio.gather( + bot.send_message(chat_id, text="a" * constants.MessageLimit.MAX_TEXT_LENGTH), + bot.send_message(chat_id, text="a" * (constants.MessageLimit.MAX_TEXT_LENGTH + 1)), + return_exceptions=True, + ) + results = await tasks + assert len(results) == 2 + assert isinstance(results[1], BadRequest) and "Message is too long" in str(results[1]) async def test_max_caption_length(self, bot, chat_id): good_caption = "a" * constants.MessageLimit.CAPTION_LENGTH - with data_file("telegram.png").open("rb") as f: - good_msg = await bot.send_photo(photo=f, caption=good_caption, chat_id=chat_id) - assert good_msg.caption == good_caption - bad_caption = good_caption + "Z" - match = "Message caption is too long" - with pytest.raises(BadRequest, match=match), data_file("telegram.png").open("rb") as f: - await bot.send_photo(photo=f, caption=bad_caption, chat_id=chat_id) + tasks = asyncio.gather( + bot.send_photo(chat_id, data_file("telegram.png").read_bytes(), good_caption), + bot.send_photo(chat_id, data_file("telegram.png").read_bytes(), bad_caption), + return_exceptions=True, + ) + good_msg, bad_msg = await tasks + assert good_msg.caption == good_caption + assert isinstance(bad_msg, BadRequest) and "Message caption is too long" in str(bad_msg) diff --git a/tests/test_contact.py b/tests/test_contact.py index dd9a12f7404..8e90feacf7f 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -17,6 +17,8 @@ # 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 asyncio + import pytest from telegram import Contact, Voice @@ -161,9 +163,10 @@ async def test_send_contact_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_contact_default_protect_content(self, chat_id, default_bot, contact): - protected = await default_bot.send_contact(chat_id, contact=contact) - assert protected.has_protected_content - unprotected = await default_bot.send_contact( - chat_id, contact=contact, protect_content=False + tasks = asyncio.gather( + default_bot.send_contact(chat_id, contact=contact), + default_bot.send_contact(chat_id, contact=contact, protect_content=False), ) + protected, unprotected = await tasks + assert protected.has_protected_content assert not unprotected.has_protected_content diff --git a/tests/test_document.py b/tests/test_document.py index 3a28e62a749..d882553a2e8 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -258,9 +259,12 @@ async def test_send_url_gif_file(self, bot, chat_id): @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_document_default_protect_content(self, chat_id, default_bot, document): - protected = await default_bot.send_document(chat_id, document) + tasks = asyncio.gather( + default_bot.send_document(chat_id, document), + default_bot.send_document(chat_id, document, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_document(chat_id, document, protect_content=False) assert not unprotected.has_protected_content async def test_send_document_caption_entities(self, bot, chat_id, document): diff --git a/tests/test_forum.py b/tests/test_forum.py index bc5e017789c..bcd5122a970 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -16,6 +16,8 @@ # # 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 asyncio + import pytest from telegram import ForumTopic, ForumTopicClosed, ForumTopicCreated, ForumTopicReopened, Sticker @@ -225,22 +227,20 @@ async def test_close_and_reopen_forum_topic(self, bot, forum_group_id, real_topi @pytest.mark.xfail(reason="Can fail due to race conditions in GH actions CI") async def test_unpin_all_forum_topic_messages(self, bot, forum_group_id, real_topic): message_thread_id = real_topic.message_thread_id + pin_msg_tasks = set() - msgs = [ - await ( - await bot.send_message( - chat_id=forum_group_id, text=TEST_MSG_TEXT, message_thread_id=message_thread_id - ) - ).pin() + awaitables = { + bot.send_message(forum_group_id, TEST_MSG_TEXT, message_thread_id=message_thread_id) for _ in range(2) - ] + } + for coro in asyncio.as_completed(awaitables): + msg = await coro + pin_msg_tasks.add(asyncio.create_task(msg.pin())) - assert all(msgs) is True, "Message(s) were not pinned" + assert all([await task for task in pin_msg_tasks]) is True, "Message(s) were not pinned" # We need 2 or more pinned msgs for this to work, else we get Chat_not_modified error - result = await bot.unpin_all_forum_topic_messages( - chat_id=forum_group_id, message_thread_id=message_thread_id - ) + result = await bot.unpin_all_forum_topic_messages(forum_group_id, message_thread_id) assert result is True, "Failed to unpin all the messages in forum topic" diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index dcad5f18c37..d0690b8d8c2 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -16,6 +16,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. +import asyncio import copy import pytest @@ -675,13 +676,13 @@ async def test_send_media_group_with_group_caption( async def test_send_media_group_all_args(self, bot, raw_bot, chat_id, media_group): ext_bot = bot - for bot in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with - # pytest.parametrize appears to be difficult ... - - m1 = await bot.send_message(chat_id, text="test") + # We need to test 1) below both the bot and raw_bot and setting this up with + # pytest.parametrize appears to be difficult ... + aws = {b.send_message(chat_id, text="test") for b in (ext_bot, raw_bot)} + for msg_task in asyncio.as_completed(aws): + m1 = await msg_task copied_media_group = copy.copy(media_group) - messages = await bot.send_media_group( + messages = await m1.get_bot().send_media_group( chat_id, media_group, disable_notification=True, @@ -744,11 +745,12 @@ async def test_send_media_group_default_allow_sending_without_reply( async def test_send_media_group_default_protect_content( self, chat_id, media_group, default_bot ): - protected = await default_bot.send_media_group(chat_id, media_group) - assert all(msg.has_protected_content for msg in protected) - unprotected = await default_bot.send_media_group( - chat_id, media_group, protect_content=False + tasks = asyncio.gather( + default_bot.send_media_group(chat_id, media_group), + default_bot.send_media_group(chat_id, media_group, protect_content=False), ) + protected, unprotected = await tasks + assert all(msg.has_protected_content for msg in protected) assert not all(msg.has_protected_content for msg in unprotected) @pytest.mark.parametrize("default_bot", [{"parse_mode": ParseMode.HTML}], indirect=True) @@ -762,19 +764,21 @@ async def test_send_media_group_default_parse_mode( # make sure no parse_mode was set as a side effect assert not any(item.parse_mode for item in media_group_no_caption_args) - overridden_markdown_v2 = await default_bot.send_media_group( - chat_id, - media_group_no_caption_args.copy(), - caption="*photo* 1", - parse_mode=ParseMode.MARKDOWN_V2, - ) - - overridden_none = await default_bot.send_media_group( - chat_id, - media_group_no_caption_args.copy(), - caption="photo 1", - parse_mode=None, + tasks = asyncio.gather( + default_bot.send_media_group( + chat_id, + media_group_no_caption_args.copy(), + caption="*photo* 1", + parse_mode=ParseMode.MARKDOWN_V2, + ), + default_bot.send_media_group( + chat_id, + media_group_no_caption_args.copy(), + caption="photo 1", + parse_mode=None, + ), ) + overridden_markdown_v2, overridden_none = await tasks # Make sure first message got the caption, which will lead to Telegram # displaying its caption as group caption @@ -797,15 +801,18 @@ async def test_send_media_group_default_parse_mode( async def test_edit_message_media(self, bot, raw_bot, chat_id, media_group): ext_bot = bot - for bot in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with - # pytest.parametrize appears to be difficult ... - messages = await bot.send_media_group(chat_id, media_group) + # We need to test 1) below both the bot and raw_bot and setting this up with + # pytest.parametrize appears to be difficult ... + aws = {b.send_media_group(chat_id, media_group) for b in (ext_bot, raw_bot)} + for msg_task in asyncio.as_completed(aws): + messages = await msg_task cid = messages[-1].chat.id mid = messages[-1].message_id copied_media = copy.copy(media_group[0]) - new_message = await bot.edit_message_media( - chat_id=cid, message_id=mid, media=media_group[0] + new_message = ( + await messages[-1] + .get_bot() + .edit_message_media(chat_id=cid, message_id=mid, media=media_group[0]) ) assert isinstance(new_message, Message) diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 47bfc78b856..298b8eea77a 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -16,6 +16,8 @@ # # 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 asyncio + import pytest from telegram import Invoice, LabeledPrice @@ -170,57 +172,61 @@ def test_equality(self): class TestInvoiceReq: async def test_send_required_args_only(self, bot, chat_id, provider_token): - message = await bot.send_invoice( - chat_id=chat_id, - title=Space.title, - description=Space.description, - payload=Space.payload, - provider_token=provider_token, - currency=Space.currency, - prices=Space.prices, + send_inv_task = asyncio.create_task( + bot.send_invoice( + chat_id=chat_id, + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=provider_token, + currency=Space.currency, + prices=Space.prices, + ) + ) + create_inv_link_task = asyncio.create_task( + bot.create_invoice_link( + title=Space.title, + description=Space.description, + payload=Space.payload, + provider_token=provider_token, + currency=Space.currency, + prices=Space.prices, + ) ) + message = await send_inv_task assert message.invoice.currency == Space.currency assert message.invoice.start_parameter == "" assert message.invoice.description == Space.description assert message.invoice.title == Space.title assert message.invoice.total_amount == Space.total_amount - link = await bot.create_invoice_link( - title=Space.title, - description=Space.description, - payload=Space.payload, - provider_token=provider_token, - currency=Space.currency, - prices=Space.prices, - ) + link = await create_inv_link_task assert isinstance(link, str) assert link != "" + assert send_inv_task.done() and create_inv_link_task.done() @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_invoice_default_protect_content( self, chat_id, default_bot, provider_token ): - protected = await default_bot.send_invoice( - chat_id, - Space.title, - Space.description, - Space.payload, - provider_token, - Space.currency, - Space.prices, + tasks = asyncio.gather( + *( + default_bot.send_invoice( + chat_id, + Space.title, + Space.description, + Space.payload, + provider_token, + Space.currency, + Space.prices, + **i, + ) + for i in ({}, {"protect_content": False}) + ) ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_invoice( - chat_id, - Space.title, - Space.description, - Space.payload, - provider_token, - Space.currency, - Space.prices, - protect_content=False, - ) assert not unprotected.has_protected_content @pytest.mark.parametrize( diff --git a/tests/test_location.py b/tests/test_location.py index ae038262a2e..157a4d88a94 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -16,6 +16,8 @@ # # 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 asyncio + import pytest from telegram import Location @@ -194,11 +196,12 @@ async def test_send_location_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_location_default_protect_content(self, chat_id, default_bot, location): - protected = await default_bot.send_location(chat_id, location=location) - assert protected.has_protected_content - unprotected = await default_bot.send_location( - chat_id, location=location, protect_content=False + tasks = asyncio.gather( + default_bot.send_location(chat_id, location=location), + default_bot.send_location(chat_id, location=location, protect_content=False), ) + protected, unprotected = await tasks + assert protected.has_protected_content assert not unprotected.has_protected_content @pytest.mark.xfail diff --git a/tests/test_photo.py b/tests/test_photo.py index 80bf615557c..cbbfe44a392 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -15,6 +15,7 @@ # # 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 asyncio import os from io import BytesIO from pathlib import Path @@ -322,9 +323,12 @@ async def test_send_photo_default_parse_mode_3( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_photo_default_protect_content(self, chat_id, default_bot, photo): - protected = await default_bot.send_photo(chat_id, photo) + tasks = asyncio.gather( + default_bot.send_photo(chat_id, photo), + default_bot.send_photo(chat_id, photo, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_photo(chat_id, photo, protect_content=False) assert not unprotected.has_protected_content @pytest.mark.parametrize( diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 60353b93a5e..78882c3f28b 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -383,9 +383,12 @@ async def test_send_sticker_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_sticker_default_protect_content(self, chat_id, sticker, default_bot): - protected = await default_bot.send_sticker(chat_id, sticker) + tasks = asyncio.gather( + default_bot.send_sticker(chat_id, sticker), + default_bot.send_sticker(chat_id, sticker, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_sticker(chat_id, sticker, protect_content=False) assert not unprotected.has_protected_content async def test_premium_animation(self, bot): @@ -758,17 +761,20 @@ async def test_bot_methods_1_png(self, bot, chat_id, sticker_file): # chat_id was hardcoded as 95205500 but it stopped working for some reason file = await bot.upload_sticker_file(chat_id, f) assert file - assert await bot.add_sticker_to_set( - chat_id, f"test_by_{bot.username}", png_sticker=file.file_id, emojis="😄" - ) - # Also test with file input and mask - assert await bot.add_sticker_to_set( - chat_id, - f"test_by_{bot.username}", - png_sticker=sticker_file, - emojis="😄", - mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2), + + tasks = asyncio.gather( + bot.add_sticker_to_set( + chat_id, f"test_by_{bot.username}", png_sticker=file.file_id, emojis="😄" + ), + bot.add_sticker_to_set( # Also test with file input and mask + chat_id, + f"test_by_{bot.username}", + png_sticker=sticker_file, + emojis="😄", + mask_position=MaskPosition(MaskPosition.EYES, -1, 1, 2), + ), ) + assert all(await tasks) async def test_bot_methods_1_tgs(self, bot, chat_id): assert await bot.add_sticker_to_set( @@ -804,12 +810,13 @@ async def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): async def test_bot_methods_3_tgs( self, bot, chat_id, animated_sticker_file, animated_sticker_set ): - await asyncio.sleep(1) animated_test = f"animated_test_by_{bot.username}" - assert await bot.set_sticker_set_thumb(animated_test, chat_id, animated_sticker_file) file_id = animated_sticker_set.stickers[-1].file_id - # also test with file input and mask - assert await bot.set_sticker_set_thumb(animated_test, chat_id, file_id) + tasks = asyncio.gather( + bot.set_sticker_set_thumb(animated_test, chat_id, animated_sticker_file), + bot.set_sticker_set_thumb(animated_test, chat_id, file_id), + ) + assert all(await tasks) # TODO: Try the below by creating a custom .webm and not by downloading another pack's thumb @pytest.mark.skip( @@ -820,17 +827,14 @@ def test_bot_methods_3_webm(self, bot, chat_id, video_sticker_file, video_sticke pass async def test_bot_methods_4_png(self, bot, sticker_set): - await asyncio.sleep(1) file_id = sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) async def test_bot_methods_4_tgs(self, bot, animated_sticker_set): - await asyncio.sleep(1) file_id = animated_sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) async def test_bot_methods_4_webm(self, bot, video_sticker_set): - await asyncio.sleep(1) file_id = video_sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) diff --git a/tests/test_venue.py b/tests/test_venue.py index 6088bbfcaf6..48706e8f4b7 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -16,6 +16,8 @@ # # 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 asyncio + import pytest from telegram import Location, Venue @@ -175,7 +177,10 @@ async def test_send_venue_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_venue_default_protect_content(self, default_bot, chat_id, venue): - protected = await default_bot.send_venue(chat_id, venue=venue) + tasks = asyncio.gather( + default_bot.send_venue(chat_id, venue=venue), + default_bot.send_venue(chat_id, venue=venue, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_venue(chat_id, venue=venue, protect_content=False) assert not unprotected.has_protected_content diff --git a/tests/test_video.py b/tests/test_video.py index bf098827f4a..a060a2d40f2 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -325,9 +326,12 @@ async def test_send_video_default_parse_mode_3(self, default_bot, chat_id, video @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_video_default_protect_content(self, chat_id, default_bot, video): - protected = await default_bot.send_video(chat_id, video) + tasks = asyncio.gather( + default_bot.send_video(chat_id, video), + default_bot.send_video(chat_id, video, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_video(chat_id, video, protect_content=False) assert not unprotected.has_protected_content @pytest.mark.parametrize( diff --git a/tests/test_videonote.py b/tests/test_videonote.py index 0a8a3ec4613..c88e27c391c 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -269,9 +270,12 @@ async def test_send_video_note_default_allow_sending_without_reply( @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_video_note_default_protect_content(self, chat_id, default_bot, video_note): - protected = await default_bot.send_video_note(chat_id, video_note) + tasks = asyncio.gather( + default_bot.send_video_note(chat_id, video_note), + default_bot.send_video_note(chat_id, video_note, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_video_note(chat_id, video_note, protect_content=False) assert not unprotected.has_protected_content async def test_error_send_empty_file(self, bot, chat_id): diff --git a/tests/test_voice.py b/tests/test_voice.py index 8c3c376141f..4c5e7c2c92f 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -16,6 +16,7 @@ # # 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 asyncio import os from pathlib import Path @@ -276,9 +277,12 @@ async def test_send_voice_default_parse_mode_3(self, default_bot, chat_id, voice @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_voice_default_protect_content(self, chat_id, default_bot, voice): - protected = await default_bot.send_voice(chat_id, voice) + tasks = asyncio.gather( + default_bot.send_voice(chat_id, voice), + default_bot.send_voice(chat_id, voice, protect_content=False), + ) + protected, unprotected = await tasks assert protected.has_protected_content - unprotected = await default_bot.send_voice(chat_id, voice, protect_content=False) assert not unprotected.has_protected_content @pytest.mark.parametrize( From 6f4036344a5dee2eda15feacf2c0ade8bee6dedd Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 14 Dec 2022 21:06:05 +0530 Subject: [PATCH 18/77] Fix/Refactor: Move test_custom_emoji_sticker to TestStickerReq --- tests/test_sticker.py | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 78882c3f28b..974bf9f713a 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -417,6 +417,24 @@ async def test_custom_emoji(self, bot): custom_emoji_sticker = custom_emoji_set.stickers[0] assert custom_emoji_sticker.custom_emoji_id == "6046140249875156202" + async def test_custom_emoji_sticker(self, bot): + # we use the same ID as in test_custom_emoji + emoji_sticker_list = await bot.get_custom_emoji_stickers(["6046140249875156202"]) + assert emoji_sticker_list[0].emoji == "😎" + assert emoji_sticker_list[0].height == 100 + assert emoji_sticker_list[0].width == 100 + assert not emoji_sticker_list[0].is_animated + assert not emoji_sticker_list[0].is_video + assert emoji_sticker_list[0].set_name == "PTBStaticEmojiTestPack" + assert emoji_sticker_list[0].type == Sticker.CUSTOM_EMOJI + assert emoji_sticker_list[0].custom_emoji_id == "6046140249875156202" + assert emoji_sticker_list[0].thumb.width == 100 + assert emoji_sticker_list[0].thumb.height == 100 + assert emoji_sticker_list[0].thumb.file_size == 3614 + assert emoji_sticker_list[0].thumb.file_unique_id == "AQAD6gwAAoY06FNy" + assert emoji_sticker_list[0].file_size == 3678 + assert emoji_sticker_list[0].file_unique_id == "AgAD6gwAAoY06FM" + async def test_error_send_empty_file(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_sticker(chat_id, open(os.devnull, "rb")) @@ -897,23 +915,3 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) - - -class TestGetCustomEmojiStickerReq: - async def test_custom_emoji_sticker(self, bot): - # we use the same ID as in test_custom_emoji - emoji_sticker_list = await bot.get_custom_emoji_stickers(["6046140249875156202"]) - assert emoji_sticker_list[0].emoji == "😎" - assert emoji_sticker_list[0].height == 100 - assert emoji_sticker_list[0].width == 100 - assert not emoji_sticker_list[0].is_animated - assert not emoji_sticker_list[0].is_video - assert emoji_sticker_list[0].set_name == "PTBStaticEmojiTestPack" - assert emoji_sticker_list[0].type == Sticker.CUSTOM_EMOJI - assert emoji_sticker_list[0].custom_emoji_id == "6046140249875156202" - assert emoji_sticker_list[0].thumb.width == 100 - assert emoji_sticker_list[0].thumb.height == 100 - assert emoji_sticker_list[0].thumb.file_size == 3614 - assert emoji_sticker_list[0].thumb.file_unique_id == "AQAD6gwAAoY06FNy" - assert emoji_sticker_list[0].file_size == 3678 - assert emoji_sticker_list[0].file_unique_id == "AgAD6gwAAoY06FM" From e90f0a09b1c1824d467b1862d7129008ae3cde5c Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 14 Dec 2022 23:03:10 +0530 Subject: [PATCH 19/77] Miscellaneous fixes includes removing unused params, removing unnecessary monkeypatch.delattr's, missing import, beautification, etc --- tests/test_animation.py | 2 -- tests/test_applicationbuilder.py | 2 +- tests/test_audio.py | 1 - tests/test_bot.py | 7 ++----- tests/test_chat.py | 1 - tests/test_chatlocation.py | 2 +- tests/test_chatphoto.py | 4 +--- tests/test_contact.py | 7 +------ tests/test_conversationhandler.py | 2 +- tests/test_forum.py | 9 ++++----- tests/test_inputfile.py | 2 +- tests/test_inputmedia.py | 9 ++------- tests/test_message.py | 2 +- tests/test_no_passport.py | 6 +++--- tests/test_orderinfo.py | 7 +------ tests/test_photo.py | 26 ++++++++++---------------- tests/test_request.py | 6 +++--- tests/test_requestdata.py | 2 +- tests/test_sticker.py | 11 +++-------- tests/test_update.py | 3 ++- tests/test_updater.py | 1 - 21 files changed, 38 insertions(+), 74 deletions(-) diff --git a/tests/test_animation.py b/tests/test_animation.py index 76b3544b711..054b60c4efb 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -88,7 +88,6 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.setattr(bot.request, "post", make_assertion) assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") - monkeypatch.delattr(bot.request, "post") @pytest.mark.parametrize("local_mode", [True, False]) async def test_send_animation_local_files(self, monkeypatch, bot, chat_id, local_mode): @@ -111,7 +110,6 @@ async def make_assertion(_, data, *args, **kwargs): monkeypatch.setattr(bot, "_post", make_assertion) await bot.send_animation(chat_id, file, thumb=file) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False diff --git a/tests/test_applicationbuilder.py b/tests/test_applicationbuilder.py index b884102c9fe..dd9c2b9e3ac 100644 --- a/tests/test_applicationbuilder.py +++ b/tests/test_applicationbuilder.py @@ -37,7 +37,7 @@ from telegram.ext._applicationbuilder import _BOT_CHECKS from telegram.request import HTTPXRequest -from .conftest import PRIVATE_KEY, TEST_WITH_OPT_DEPS +from .conftest import PRIVATE_KEY, TEST_WITH_OPT_DEPS, data_file @pytest.fixture(scope="function") diff --git a/tests/test_audio.py b/tests/test_audio.py index 187694b2245..29f9de940e0 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -125,7 +125,6 @@ async def make_assertion(_, data, *args, **kwargs): monkeypatch.setattr(bot, "_post", make_assertion) await bot.send_audio(chat_id, file, thumb=file) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False diff --git a/tests/test_bot.py b/tests/test_bot.py index 30cdb64b32f..d903d42bef2 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -982,7 +982,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): async def test_get_file_local_mode(self, bot, monkeypatch): path = str(data_file("game.gif")) - async def _post(*args, **kwargs): + async def make_assertion(*args, **kwargs): return { "file_id": None, "file_unique_id": None, @@ -990,12 +990,11 @@ async def _post(*args, **kwargs): "file_path": path, } - monkeypatch.setattr(bot, "_post", _post) + monkeypatch.setattr(bot, "_post", make_assertion) resulting_path = (await bot.get_file("file_id")).file_path assert bot.token not in resulting_path assert resulting_path == path - monkeypatch.delattr(bot, "_post") # TODO: Needs improvement. No feasible way to test until bots can add members. async def test_ban_chat_member(self, monkeypatch, bot): @@ -1014,7 +1013,6 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.ban_chat_member(2, 32, until_date=until) assert await bot.ban_chat_member(2, 32, until_date=1577887200) assert await bot.ban_chat_member(2, 32, revoke_messages=True) - monkeypatch.delattr(bot.request, "post") async def test_ban_chat_member_default_tz(self, monkeypatch, tz_bot): until = dtm.datetime(2020, 1, 11, 16, 13) @@ -1043,7 +1041,6 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.setattr(bot.request, "post", make_assertion) assert await bot.ban_chat_sender_chat(2, 32) - monkeypatch.delattr(bot.request, "post") # TODO: Needs improvement. @pytest.mark.parametrize("only_if_banned", [True, False, None]) diff --git a/tests/test_chat.py b/tests/test_chat.py index 1f78a4ad4f4..541f3c49a34 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -214,7 +214,6 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(chat.get_bot(), "send_chat_action", make_assertion) assert await chat.send_action(action=ChatAction.TYPING) - assert await chat.send_action(action=ChatAction.TYPING) async def test_leave(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index 91f6ff5c7bc..9e5e629f5e8 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -23,7 +23,7 @@ @pytest.fixture(scope="module") -def chat_location(bot): +def chat_location(): return ChatLocation(Space.location, Space.address) diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index a7c8320448b..f0b0a2c3b91 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -171,9 +171,7 @@ async def test_get_and_download(self, bot, chat_photo): await file.download_to_drive(jpg_file) assert jpg_file.is_file() - async def test_send_all_args( - self, bot, super_group_id, chatphoto_file, chat_photo, thumb_file - ): + async def test_send_all_args(self, bot, super_group_id, chatphoto_file): async def func(): assert await bot.set_chat_photo(super_group_id, chatphoto_file) diff --git a/tests/test_contact.py b/tests/test_contact.py index 8e90feacf7f..c7b1d3c7399 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -28,12 +28,7 @@ @pytest.fixture(scope="module") def contact(): - return Contact( - Space.phone_number, - Space.first_name, - Space.last_name, - Space.user_id, - ) + return Contact(Space.phone_number, Space.first_name, Space.last_name, Space.user_id) class Space: diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index 2f16f94301d..fffd9e59aba 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -2160,7 +2160,7 @@ async def callback(_, __): fallback_message.set_bot(bot) # This loop makes sure that we test all of entry points, states handler & fallbacks - for message in [start_message, start_message, fallback_message]: + for message in [start_message, fallback_message]: process_update_task = asyncio.create_task( app.process_update(Update(0, message=message)) ) diff --git a/tests/test_forum.py b/tests/test_forum.py index bcd5122a970..c6304229ffb 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -63,11 +63,10 @@ async def real_topic(bot, emoji_id, forum_group_id): class TestForumTopicNoReq: def test_slot_behaviour(self, mro_slots, forum_topic_object): - for attr in forum_topic_object.__slots__: - assert getattr(forum_topic_object, attr, "err") != "err", f"got extra slot '{attr}'" - assert len(mro_slots(forum_topic_object)) == len( - set(mro_slots(forum_topic_object)) - ), "duplicate slot" + inst = forum_topic_object + for attr in inst.__slots__: + assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" async def test_expected_values(self, emoji_id, forum_group_id, forum_topic_object): assert forum_topic_object.message_thread_id == forum_group_id diff --git a/tests/test_inputfile.py b/tests/test_inputfile.py index bde7c935b00..1b5fecb768a 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -65,7 +65,7 @@ def test_attach(self, attach): assert input_file.attach_name is None assert input_file.attach_uri is None - def test_mimetypes(self, caplog): + def test_mimetypes(self): # Only test a few to make sure logic works okay assert InputFile(data_file("telegram.jpg").open("rb")).mimetype == "image/jpeg" # For some reason python can guess the type on macOS diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index d0690b8d8c2..98422f0334f 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -72,7 +72,7 @@ def input_media_video(class_thumb_file): @pytest.fixture(scope="module") -def input_media_photo(class_thumb_file): +def input_media_photo(): return InputMediaPhoto( media=PhotoSpace.media, caption=PhotoSpace.caption, @@ -582,12 +582,7 @@ async def test_send_media_group_photo(self, bot, chat_id, media_group): ) async def test_send_media_group_new_files( - self, - bot, - chat_id, - video_file, # noqa: F811 - photo_file, # noqa: F811 - animation_file, # noqa: F811 + self, bot, chat_id, video_file, photo_file # noqa: F811 ): async def func(): return await bot.send_media_group( diff --git a/tests/test_message.py b/tests/test_message.py index fd474ea1bde..284ead40e8e 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -559,7 +559,7 @@ def test_text_markdown_emoji(self): expected = b"\\U0001f469\\u200d\\U0001f469\\u200d *ABC*".decode("unicode-escape") bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( - 1, Space.from_user, Space.date, Space.chat, text=text, entities=[bold_entity] + 1, Space.date, Space.chat, Space.from_user, text=text, entities=[bold_entity] ) assert expected == message.text_markdown diff --git a/tests/test_no_passport.py b/tests/test_no_passport.py index ee4999988aa..714bfcdbd30 100644 --- a/tests/test_no_passport.py +++ b/tests/test_no_passport.py @@ -37,15 +37,15 @@ TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed" ) class TestNoPassportNoReq: - def test_bot_init(self, bot_info, monkeypatch): + def test_bot_init(self, bot_info): with pytest.raises(RuntimeError, match="passport"): bot.Bot(bot_info["token"], private_key=1, private_key_password=2) - def test_credentials_decrypt(self, monkeypatch): + def test_credentials_decrypt(self): with pytest.raises(RuntimeError, match="passport"): credentials.decrypt(1, 1, 1) - def test_encrypted_credentials_decrypted_secret(self, monkeypatch): + def test_encrypted_credentials_decrypted_secret(self): ec = credentials.EncryptedCredentials("data", "hash", "secret") with pytest.raises(RuntimeError, match="passport"): ec.decrypted_secret diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index a569b4e1884..dd6f1abf638 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -23,12 +23,7 @@ @pytest.fixture(scope="module") def order_info(): - return OrderInfo( - Space.name, - Space.phone_number, - Space.email, - Space.shipping_address, - ) + return OrderInfo(Space.name, Space.phone_number, Space.email, Space.shipping_address) class Space: diff --git a/tests/test_photo.py b/tests/test_photo.py index cbbfe44a392..021466ac806 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -209,7 +209,7 @@ def test_equality(self, photo): class TestPhotoReq: - async def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo): + async def test_send_photo_all_args(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, photo_file, @@ -234,7 +234,7 @@ async def test_send_photo_all_args(self, bot, chat_id, photo_file, thumb, photo) assert message.caption == Space.caption.replace("*", "") assert message.has_protected_content - async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file, thumb, photo): + async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, photo_file, caption=Space.caption, parse_mode="Markdown" ) @@ -253,7 +253,7 @@ async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file, th assert message.caption == Space.caption.replace("*", "") assert len(message.caption_entities) == 1 - async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, photo): + async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, photo_file, caption=Space.caption, parse_mode="HTML" ) @@ -272,7 +272,7 @@ async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file, thumb, assert message.caption == Space.caption.replace("", "").replace("", "") assert len(message.caption_entities) == 1 - async def test_send_photo_caption_entities(self, bot, chat_id, photo_file, thumb, photo): + async def test_send_photo_caption_entities(self, bot, chat_id, photo_file): test_string = "Italic Bold Code" entities = [ MessageEntity(MessageEntity.ITALIC, 0, 6), @@ -287,9 +287,7 @@ async def test_send_photo_caption_entities(self, bot, chat_id, photo_file, thumb assert message.caption_entities == tuple(entities) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) - async def test_send_photo_default_parse_mode_1( - self, default_bot, chat_id, photo_file, thumb, photo - ): + async def test_send_photo_default_parse_mode_1(self, default_bot, chat_id, photo_file): test_string = "Italic Bold Code" test_markdown_string = "_Italic_ *Bold* `Code`" @@ -298,9 +296,7 @@ async def test_send_photo_default_parse_mode_1( assert message.caption == test_string @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) - async def test_send_photo_default_parse_mode_2( - self, default_bot, chat_id, photo_file, thumb, photo - ): + async def test_send_photo_default_parse_mode_2(self, default_bot, chat_id, photo_file): test_markdown_string = "_Italic_ *Bold* `Code`" message = await default_bot.send_photo( @@ -310,9 +306,7 @@ async def test_send_photo_default_parse_mode_2( assert message.caption_markdown == escape_markdown(test_markdown_string) @pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True) - async def test_send_photo_default_parse_mode_3( - self, default_bot, chat_id, photo_file, thumb, photo - ): + async def test_send_photo_default_parse_mode_3(self, default_bot, chat_id, photo_file): test_markdown_string = "_Italic_ *Bold* `Code`" message = await default_bot.send_photo( @@ -341,7 +335,7 @@ async def test_send_photo_default_protect_content(self, chat_id, default_bot, ph indirect=["default_bot"], ) async def test_send_photo_default_allow_sending_without_reply( - self, default_bot, chat_id, photo_file, thumb, photo, custom + self, default_bot, chat_id, photo_file, custom ): reply_to_message = await default_bot.send_message(chat_id, "test") await reply_to_message.delete() @@ -379,7 +373,7 @@ async def test_get_and_download(self, bot, photo): assert path.is_file() - async def test_send_url_jpg_file(self, bot, chat_id, thumb, photo): + async def test_send_url_jpg_file(self, bot, chat_id): message = await bot.send_photo(chat_id, photo=Space.photo_file_url) assert isinstance(message.photo[-2], PhotoSize) @@ -462,7 +456,7 @@ async def test_send_bytesio_jpg_file(self, bot, chat_id): assert photo.height == 720 assert photo.file_size == 33372 - async def test_resend(self, bot, chat_id, photo, thumb): + async def test_resend(self, bot, chat_id, photo): message = await bot.send_photo(chat_id=chat_id, photo=photo.file_id) assert isinstance(message.photo[-2], PhotoSize) diff --git a/tests/test_request.py b/tests/test_request.py index 22d0e01bbe3..a7d00601606 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -44,7 +44,7 @@ from .conftest import TEST_WITH_OPT_DEPS -# We only need the first fixture, but it uses the others, so pytest needs us to import them as well +# We only need mixed_rqs fixture, but it uses the others, so pytest needs us to import them as well from .test_requestdata import ( # noqa: F401 file_params, input_media_photo, @@ -87,7 +87,7 @@ class TestRequestNoReq: def reset(self): self.test_flag = None - async def test_init_import_errors(self, bot, monkeypatch): + async def test_init_import_errors(self, monkeypatch): """Makes sure that import errors are forwarded - related to TestNoSocks above""" def __init__(self, *args, **kwargs): @@ -565,7 +565,7 @@ async def request(_, **kwargs): class TestHTTPXRequestReq: - async def test_do_request_wait_for_pool(self, monkeypatch, httpx_request): + async def test_do_request_wait_for_pool(self, httpx_request): """The pool logic is buried rather deeply in httpxcore, so we make actual requests here instead of mocking""" task_1 = asyncio.create_task( diff --git a/tests/test_requestdata.py b/tests/test_requestdata.py index 908cda5db7b..0bd8164feca 100644 --- a/tests/test_requestdata.py +++ b/tests/test_requestdata.py @@ -201,7 +201,7 @@ def test_multipart_data( assert file_rqs.multipart_data == expected assert mixed_rqs.multipart_data == expected - def test_url_encoding(self, monkeypatch): + def test_url_encoding(self): data = RequestData( [ RequestParameter.from_input("chat_id", 123), diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 974bf9f713a..af653119fe6 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -96,7 +96,7 @@ class StickerSpace: class TestStickerNoReq: - def test_slot_behaviour(self, sticker, mro_slots, recwarn): + def test_slot_behaviour(self, sticker, mro_slots): for attr in sticker.__slots__: assert getattr(sticker, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(sticker)) == len(set(mro_slots(sticker))), "duplicate slot" @@ -185,7 +185,6 @@ async def make_assertion(_, data, *args, **kwargs): monkeypatch.setattr(bot, "_post", make_assertion) await bot.send_sticker(chat_id, file) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False @@ -557,7 +556,6 @@ async def make_assertion(_, data, *args, **kwargs): monkeypatch.setattr(bot, "_post", make_assertion) await bot.upload_sticker_file(chat_id, file) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False @@ -596,7 +594,6 @@ async def make_assertion(_, data, *args, **kwargs): webm_sticker=file, ) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False @@ -624,7 +621,6 @@ async def make_assertion(_, data, *args, **kwargs): webm_sticker="wow.webm", sticker_type=Sticker.MASK, ) - monkeypatch.delattr(bot, "_post") @pytest.mark.parametrize("local_mode", [True, False]) async def test_add_sticker_to_set_local_files(self, monkeypatch, bot, chat_id, local_mode): @@ -651,7 +647,6 @@ async def make_assertion(_, data, *args, **kwargs): chat_id, "name", "emoji", png_sticker=file, tgs_sticker=file ) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False @@ -674,7 +669,6 @@ async def make_assertion(_, data, *args, **kwargs): monkeypatch.setattr(bot, "_post", make_assertion) await bot.set_sticker_set_thumb("name", chat_id, thumb=file) assert test_flag - monkeypatch.delattr(bot, "_post") finally: bot._local_mode = False @@ -741,7 +735,8 @@ async def test_create_sticker_set( test_by = f"test_by_{bot.username}" for sticker_set in [test_by, f"animated_{test_by}", f"video_{test_by}"]: try: - await bot.get_sticker_set(sticker_set) + ss = await bot.get_sticker_set(sticker_set) + assert isinstance(ss, StickerSet) except BadRequest as e: if not e.message == "Stickerset_invalid": raise e diff --git a/tests/test_update.py b/tests/test_update.py index cf244ee35de..08e1dbbcf14 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -106,7 +106,8 @@ class Space: class TestUpdateNoReq: - def test_slot_behaviour(self, update, mro_slots): + def test_slot_behaviour(self, mro_slots): + update = Update(Space.update_id) for attr in update.__slots__: assert getattr(update, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(update)) == len(set(mro_slots(update))), "duplicate slot" diff --git a/tests/test_updater.py b/tests/test_updater.py index bb697e98f2d..d99c2631bbc 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -30,7 +30,6 @@ from telegram.error import InvalidToken, RetryAfter, TelegramError, TimedOut from telegram.ext import ExtBot, InvalidCallbackData, Updater from telegram.request import HTTPXRequest -from tests.auxil.object_conversions import env_var_2_bool from tests.conftest import ( TEST_WITH_OPT_DEPS, DictBot, From b330c9732e65e298aa83c7f3bcfa770662979273 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 15 Dec 2022 00:12:33 +0530 Subject: [PATCH 20/77] small refactor: delete a duplicate test, split one test --- tests/test_invoice.py | 133 +++++++++++++----------------------------- tests/test_photo.py | 13 ----- 2 files changed, 42 insertions(+), 104 deletions(-) diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 298b8eea77a..686b41dec77 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -84,33 +84,45 @@ def test_to_dict(self, invoice): assert invoice_dict["currency"] == invoice.currency assert invoice_dict["total_amount"] == invoice.total_amount - async def test_send_all_args_create_invoice_link( - self, bot, chat_id, provider_token, monkeypatch - ): + async def test_send_invoice_all_args_mock(self, bot, monkeypatch): + # We do this one as safety guard to make sure that we pass all of the optional + # parameters correctly because #2526 went unnoticed for 3 years … async def make_assertion(*args, **_): kwargs = args[1] - return ( - kwargs["title"] == "title" - and kwargs["description"] == "description" - and kwargs["payload"] == "payload" - and kwargs["provider_token"] == "provider_token" - and kwargs["currency"] == "currency" - and kwargs["prices"] == Space.prices - and kwargs["max_tip_amount"] == "max_tip_amount" - and kwargs["suggested_tip_amounts"] == "suggested_tip_amounts" - and kwargs["provider_data"] == "provider_data" - and kwargs["photo_url"] == "photo_url" - and kwargs["photo_size"] == "photo_size" - and kwargs["photo_width"] == "photo_width" - and kwargs["photo_height"] == "photo_height" - and kwargs["need_name"] == "need_name" - and kwargs["need_phone_number"] == "need_phone_number" - and kwargs["need_email"] == "need_email" - and kwargs["need_shipping_address"] == "need_shipping_address" - and kwargs["send_phone_number_to_provider"] == "send_phone_number_to_provider" - and kwargs["send_email_to_provider"] == "send_email_to_provider" - and kwargs["is_flexible"] == "is_flexible" - ) + return all([kwargs[i] == i for i in kwargs]) + + monkeypatch.setattr(bot, "_send_message", make_assertion) + assert await bot.send_invoice( + chat_id="chat_id", + title="title", + description="description", + payload="payload", + provider_token="provider_token", + currency="currency", + prices="prices", + max_tip_amount="max_tip_amount", + suggested_tip_amounts="suggested_tip_amounts", + start_parameter="start_parameter", + provider_data="provider_data", + photo_url="photo_url", + photo_size="photo_size", + photo_width="photo_width", + photo_height="photo_height", + need_name="need_name", + need_phone_number="need_phone_number", + need_email="need_email", + need_shipping_address="need_shipping_address", + send_phone_number_to_provider="send_phone_number_to_provider", + send_email_to_provider="send_email_to_provider", + is_flexible="is_flexible", + disable_notification=True, + protect_content=True, + ) + + async def test_send_all_args_create_invoice_link(self, bot, monkeypatch): + async def make_assertion(*args, **_): + kwargs = args[1] + return all([kwargs[i] == i for i in kwargs]) monkeypatch.setattr(bot, "_post", make_assertion) assert await bot.create_invoice_link( @@ -119,7 +131,7 @@ async def make_assertion(*args, **_): payload="payload", provider_token="provider_token", currency="currency", - prices=Space.prices, + prices="prices", max_tip_amount="max_tip_amount", suggested_tip_amounts="suggested_tip_amounts", provider_data="provider_data", @@ -281,7 +293,7 @@ async def test_send_invoice_default_allow_sending_without_reply( reply_to_message_id=reply_to_message.message_id, ) - async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token, monkeypatch): + async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token): message = await bot.send_invoice( chat_id, Space.title, @@ -295,8 +307,7 @@ async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token, mo start_parameter=Space.start_parameter, provider_data=Space.provider_data, 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, @@ -311,66 +322,6 @@ async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token, mo protect_content=True, ) - assert message.invoice.currency == Space.currency - assert message.invoice.start_parameter == Space.start_parameter - assert message.invoice.description == Space.description - assert message.invoice.title == Space.title - assert message.invoice.total_amount == Space.total_amount + for attr in message.invoice.__slots__: + assert getattr(message.invoice, attr) == getattr(Space, attr) assert message.has_protected_content - - # We do this next one as safety guard to make sure that we pass all of the optional - # parameters correctly because #2526 went unnoticed for 3 years … - async def make_assertion(*args, **_): - kwargs = args[1] - return ( - kwargs["chat_id"] == "chat_id" - and kwargs["title"] == "title" - and kwargs["description"] == "description" - and kwargs["payload"] == "payload" - and kwargs["provider_token"] == "provider_token" - and kwargs["currency"] == "currency" - and kwargs["prices"] == Space.prices - and kwargs["max_tip_amount"] == "max_tip_amount" - and kwargs["suggested_tip_amounts"] == "suggested_tip_amounts" - and kwargs["start_parameter"] == "start_parameter" - and kwargs["provider_data"] == "provider_data" - and kwargs["photo_url"] == "photo_url" - and kwargs["photo_size"] == "photo_size" - and kwargs["photo_width"] == "photo_width" - and kwargs["photo_height"] == "photo_height" - and kwargs["need_name"] == "need_name" - and kwargs["need_phone_number"] == "need_phone_number" - and kwargs["need_email"] == "need_email" - and kwargs["need_shipping_address"] == "need_shipping_address" - and kwargs["send_phone_number_to_provider"] == "send_phone_number_to_provider" - and kwargs["send_email_to_provider"] == "send_email_to_provider" - and kwargs["is_flexible"] == "is_flexible" - ) - - monkeypatch.setattr(bot, "_send_message", make_assertion) - assert await bot.send_invoice( - chat_id="chat_id", - title="title", - description="description", - payload="payload", - provider_token="provider_token", - currency="currency", - prices=Space.prices, - max_tip_amount="max_tip_amount", - suggested_tip_amounts="suggested_tip_amounts", - start_parameter="start_parameter", - provider_data="provider_data", - photo_url="photo_url", - photo_size="photo_size", - photo_width="photo_width", - photo_height="photo_height", - need_name="need_name", - need_phone_number="need_phone_number", - need_email="need_email", - need_shipping_address="need_shipping_address", - send_phone_number_to_provider="send_phone_number_to_provider", - send_email_to_provider="send_email_to_provider", - is_flexible="is_flexible", - disable_notification=True, - protect_content=True, - ) diff --git a/tests/test_photo.py b/tests/test_photo.py index 021466ac806..f1efe2a5ed2 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -401,19 +401,6 @@ async def test_send_url_png_file(self, bot, chat_id): assert photo.file_id != "" assert photo.file_unique_id != "" - async def test_send_url_gif_file(self, bot, chat_id): - message = await bot.send_photo( - photo="http://dummyimage.com/600x400/000/fff.png&text=telegram", chat_id=chat_id - ) - - photo = message.photo[-1] - - assert isinstance(photo, PhotoSize) - assert isinstance(photo.file_id, str) - assert isinstance(photo.file_unique_id, str) - assert photo.file_id != "" - assert photo.file_unique_id != "" - async def test_send_file_unicode_filename(self, bot, chat_id): """ Regression test for https://github.com/python-telegram-bot/python-telegram-bot/issues/1202 From 738fd4436154ae6d75fc1517a49798154cfc3b53 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 15 Dec 2022 00:27:28 +0530 Subject: [PATCH 21/77] refactor and rearrange: remove bot.delete_webhook() from arbitrary callback tests This means we can now move those methods back to TestBotNoReq, since they did not make any request apart from delete_webhook() --- tests/test_bot.py | 359 +++++++++++++++++++++++----------------------- 1 file changed, 178 insertions(+), 181 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index d903d42bef2..51e3f56157a 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1366,6 +1366,140 @@ async def post(url, request_data: RequestData, *args, **kwargs): message_thread_id=1, ) + # In the following tests we check that get_updates inserts callback data correctly if necessary + # The same must be done in the webhook updater. This is tested over at test_updater.py, but + # here we test more extensively. + + async def test_arbitrary_callback_data_no_insert(self, monkeypatch, cdc_bot): + """Updates that don't need insertion shouldn't fail obviously""" + bot = cdc_bot + + async def post(*args, **kwargs): + update = Update( + 17, + poll=Poll( + "42", + "question", + options=[PollOption("option", 0)], + total_voter_count=0, + is_closed=False, + is_anonymous=True, + type=Poll.REGULAR, + allows_multiple_answers=False, + ), + ) + return [update.to_dict()] + + try: + monkeypatch.setattr(BaseRequest, "post", post) + updates = await bot.get_updates(timeout=1) + + assert len(updates) == 1 + assert updates[0].update_id == 17 + assert updates[0].poll.id == "42" + finally: + bot.callback_data_cache.clear_callback_data() + bot.callback_data_cache.clear_callback_queries() + + @pytest.mark.parametrize( + "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] + ) + async def test_arbitrary_callback_data_pinned_message_reply_to_message( + self, cdc_bot, monkeypatch, message_type + ): + bot = cdc_bot + + reply_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="callback_data") + ) + + message = Message( + 1, + dtm.datetime.utcnow(), + None, + reply_markup=bot.callback_data_cache.process_keyboard(reply_markup), + ) + message._unfreeze() + # We do to_dict -> de_json to make sure those aren't the same objects + message.pinned_message = Message.de_json(message.to_dict(), bot) + + async def post(*args, **kwargs): + update = Update( + 17, + **{ + message_type: Message( + 1, + dtm.datetime.utcnow(), + None, + pinned_message=message, + reply_to_message=Message.de_json(message.to_dict(), bot), + ) + }, + ) + return [update.to_dict()] + + try: + monkeypatch.setattr(BaseRequest, "post", post) + updates = await bot.get_updates(timeout=1) + + assert isinstance(updates, tuple) + assert len(updates) == 1 + + effective_message = updates[0][message_type] + assert ( + effective_message.reply_to_message.reply_markup.inline_keyboard[0][0].callback_data + == "callback_data" + ) + assert ( + effective_message.pinned_message.reply_markup.inline_keyboard[0][0].callback_data + == "callback_data" + ) + + pinned_message = effective_message.reply_to_message.pinned_message + assert ( + pinned_message.reply_markup.inline_keyboard[0][0].callback_data == "callback_data" + ) + + finally: + bot.callback_data_cache.clear_callback_data() + bot.callback_data_cache.clear_callback_queries() + + async def test_get_updates_invalid_callback_data(self, cdc_bot, monkeypatch): + bot = cdc_bot + + async def post(*args, **kwargs): + return [ + Update( + 17, + callback_query=CallbackQuery( + id=1, + from_user=None, + chat_instance=123, + data="invalid data", + message=Message( + 1, + from_user=User(1, "", False), + date=dtm.datetime.utcnow(), + chat=Chat(1, ""), + text="Webhook", + ), + ), + ).to_dict() + ] + + try: + monkeypatch.setattr(BaseRequest, "post", post) + updates = await bot.get_updates(timeout=1) + + assert isinstance(updates, tuple) + assert len(updates) == 1 + assert isinstance(updates[0].callback_query.data, InvalidCallbackData) + + finally: + # Reset b/c bots scope is session + bot.callback_data_cache.clear_callback_data() + bot.callback_data_cache.clear_callback_queries() + # TODO: Needs improvement. We need incoming inline query to test answer. async def test_replace_callback_data_answer_inline_query(self, monkeypatch, cdc_bot, chat_id): bot = cdc_bot @@ -1422,6 +1556,49 @@ async def make_assertion( bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() + @pytest.mark.parametrize( + "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] + ) + @pytest.mark.parametrize("self_sender", [True, False]) + async def test_arbitrary_callback_data_via_bot( + self, cdc_bot, monkeypatch, self_sender, message_type + ): + bot = cdc_bot + reply_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="text", callback_data="callback_data") + ) + + reply_markup = bot.callback_data_cache.process_keyboard(reply_markup) + message = Message( + 1, + dtm.datetime.utcnow(), + None, + reply_markup=reply_markup, + via_bot=bot.bot if self_sender else User(1, "first", False), + ) + + async def post(*args, **kwargs): + return [Update(17, **{message_type: message}).to_dict()] + + try: + monkeypatch.setattr(BaseRequest, "post", post) + updates = await bot.get_updates(timeout=1) + + assert isinstance(updates, tuple) + assert len(updates) == 1 + + message = updates[0][message_type] + if self_sender: + assert message.reply_markup.inline_keyboard[0][0].callback_data == "callback_data" + else: + assert ( + message.reply_markup.inline_keyboard[0][0].callback_data + == reply_markup.inline_keyboard[0][0].callback_data + ) + finally: + bot.callback_data_cache.clear_callback_data() + bot.callback_data_cache.clear_callback_queries() + @bot_methods() def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): camel_case_name = to_camel_case(bot_method_name) @@ -2102,43 +2279,6 @@ async def test_get_updates(self, bot): if updates: assert isinstance(updates[0], Update) - async def test_get_updates_invalid_callback_data(self, cdc_bot, monkeypatch): - bot = cdc_bot - - async def post(*args, **kwargs): - return [ - Update( - 17, - callback_query=CallbackQuery( - id=1, - from_user=None, - chat_instance=123, - data="invalid data", - message=Message( - 1, - from_user=User(1, "", False), - date=dtm.datetime.utcnow(), - chat=Chat(1, ""), - text="Webhook", - ), - ), - ).to_dict() - ] - - try: - await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed - monkeypatch.setattr(BaseRequest, "post", post) - updates = await bot.get_updates(timeout=1) - - assert isinstance(updates, tuple) - assert len(updates) == 1 - assert isinstance(updates[0].callback_query.data, InvalidCallbackData) - - finally: - # Reset b/c bots scope is session - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() - @pytest.mark.parametrize("use_ip", [True, False]) # local file path as file_input is tested below in test_set_webhook_params @pytest.mark.parametrize("file_input", ["bytes", "file_handle"]) @@ -2901,6 +3041,7 @@ async def test_copy_message_with_default(self, default_bot, chat_id, media_messa else: assert len(message.caption_entities) == 0 + # Continue testing arbitrary callback data here with actual requests: async def test_replace_callback_data_send_message(self, cdc_bot, chat_id): bot = cdc_bot @@ -3016,106 +3157,6 @@ async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): bot.callback_data_cache.clear_callback_queries() await bot.unpin_all_chat_messages(super_group_id) - # In the following tests we check that get_updates inserts callback data correctly if necessary - # The same must be done in the webhook updater. This is tested over at test_updater.py, but - # here we test more extensively. - - async def test_arbitrary_callback_data_no_insert(self, monkeypatch, cdc_bot): - """Updates that don't need insertion shouldn't fail obviously""" - bot = cdc_bot - - async def post(*args, **kwargs): - update = Update( - 17, - poll=Poll( - "42", - "question", - options=[PollOption("option", 0)], - total_voter_count=0, - is_closed=False, - is_anonymous=True, - type=Poll.REGULAR, - allows_multiple_answers=False, - ), - ) - return [update.to_dict()] - - try: - monkeypatch.setattr(BaseRequest, "post", post) - await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed - updates = await bot.get_updates(timeout=1) - - assert len(updates) == 1 - assert updates[0].update_id == 17 - assert updates[0].poll.id == "42" - finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() - - @pytest.mark.parametrize( - "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] - ) - async def test_arbitrary_callback_data_pinned_message_reply_to_message( - self, super_group_id, cdc_bot, monkeypatch, message_type - ): - bot = cdc_bot - - reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="callback_data") - ) - - message = Message( - 1, - dtm.datetime.utcnow(), - None, - reply_markup=bot.callback_data_cache.process_keyboard(reply_markup), - ) - message._unfreeze() - # We do to_dict -> de_json to make sure those aren't the same objects - message.pinned_message = Message.de_json(message.to_dict(), bot) - - async def post(*args, **kwargs): - update = Update( - 17, - **{ - message_type: Message( - 1, - dtm.datetime.utcnow(), - None, - pinned_message=message, - reply_to_message=Message.de_json(message.to_dict(), bot), - ) - }, - ) - return [update.to_dict()] - - try: - monkeypatch.setattr(BaseRequest, "post", post) - await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed - updates = await bot.get_updates(timeout=1) - - assert isinstance(updates, tuple) - assert len(updates) == 1 - - effective_message = updates[0][message_type] - assert ( - effective_message.reply_to_message.reply_markup.inline_keyboard[0][0].callback_data - == "callback_data" - ) - assert ( - effective_message.pinned_message.reply_markup.inline_keyboard[0][0].callback_data - == "callback_data" - ) - - pinned_message = effective_message.reply_to_message.pinned_message - assert ( - pinned_message.reply_markup.inline_keyboard[0][0].callback_data == "callback_data" - ) - - finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() - async def test_arbitrary_callback_data_get_chat_no_pinned_message( self, super_group_id, cdc_bot ): @@ -3131,47 +3172,3 @@ async def test_arbitrary_callback_data_get_chat_no_pinned_message( finally: bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - - @pytest.mark.parametrize( - "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] - ) - @pytest.mark.parametrize("self_sender", [True, False]) - async def test_arbitrary_callback_data_via_bot( - self, super_group_id, cdc_bot, monkeypatch, self_sender, message_type - ): - bot = cdc_bot - reply_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="text", callback_data="callback_data") - ) - - reply_markup = bot.callback_data_cache.process_keyboard(reply_markup) - message = Message( - 1, - dtm.datetime.utcnow(), - None, - reply_markup=reply_markup, - via_bot=bot.bot if self_sender else User(1, "first", False), - ) - - async def post(*args, **kwargs): - return [Update(17, **{message_type: message}).to_dict()] - - try: - monkeypatch.setattr(BaseRequest, "post", post) - await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed - updates = await bot.get_updates(timeout=1) - - assert isinstance(updates, tuple) - assert len(updates) == 1 - - message = updates[0][message_type] - if self_sender: - assert message.reply_markup.inline_keyboard[0][0].callback_data == "callback_data" - else: - assert ( - message.reply_markup.inline_keyboard[0][0].callback_data - == reply_markup.inline_keyboard[0][0].callback_data - ) - finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() From 77b8438f8b7aa391f9cf6b4018426d0267a02b99 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 16 Dec 2022 00:34:28 +0530 Subject: [PATCH 22/77] rearrange tests The tests are roughly arranged as follows: - test_slot_behaviour - test de_json/to_dict - test init - test equality - test wrong init - etc --- tests/test_animation.py | 102 +++++++------- tests/test_audio.py | 110 ++++++++------- tests/test_bot.py | 207 ++++++++++++++--------------- tests/test_callbackquery.py | 40 +++--- tests/test_chat.py | 40 +++--- tests/test_chatphoto.py | 64 ++++----- tests/test_contact.py | 49 ++++--- tests/test_document.py | 98 +++++++------- tests/test_file.py | 72 +++++----- tests/test_game.py | 28 ++-- tests/test_inlinekeyboardmarkup.py | 160 +++++++++++----------- tests/test_inlinequery.py | 48 +++---- tests/test_inputmedia.py | 60 ++++----- tests/test_location.py | 80 +++++------ tests/test_message.py | 60 ++++----- tests/test_passport.py | 60 ++++----- tests/test_passportfile.py | 30 ++--- tests/test_photo.py | 104 +++++++-------- tests/test_poll.py | 30 ++--- tests/test_precheckoutquery.py | 42 +++--- tests/test_replykeyboardmarkup.py | 90 ++++++------- tests/test_requestparameter.py | 12 +- tests/test_shippingquery.py | 30 ++--- tests/test_sticker.py | 177 ++++++++++++------------ tests/test_update.py | 40 +++--- tests/test_user.py | 40 +++--- tests/test_venue.py | 66 ++++----- tests/test_video.py | 109 ++++++++------- tests/test_videonote.py | 83 ++++++------ tests/test_voice.py | 105 ++++++++------- 30 files changed, 1105 insertions(+), 1131 deletions(-) diff --git a/tests/test_animation.py b/tests/test_animation.py index 054b60c4efb..c89d0a775bb 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -81,46 +81,6 @@ def test_expected_values(self, animation): assert animation.file_name.startswith("game.gif") == Space.file_name.startswith("game.gif") assert isinstance(animation.thumb, PhotoSize) - async def test_send_animation_custom_filename(self, bot, chat_id, animation_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_animation_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("animation") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("animation"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_animation(chat_id, file, thumb=file) - assert test_flag - finally: - bot._local_mode = False - - async def test_send_with_animation(self, monkeypatch, bot, chat_id, animation): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["animation"] == animation.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_animation(animation=animation, chat_id=chat_id) - assert message - def test_de_json(self, bot, animation): json_dict = { "file_id": Space.animation_file_id, @@ -155,17 +115,6 @@ def test_to_dict(self, animation): assert animation_dict["mime_type"] == animation.mime_type assert animation_dict["file_size"] == animation.file_size - async def test_get_file_instance_method(self, monkeypatch, animation): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == animation.file_id - - assert check_shortcut_signature(Animation.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(animation.get_file, animation.get_bot(), "get_file") - assert await check_defaults_handling(animation.get_file, animation.get_bot()) - - monkeypatch.setattr(animation.get_bot(), "get_file", make_assertion) - assert await animation.get_file() - def test_equality(self): a = Animation( Space.animation_file_id, @@ -190,6 +139,55 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + async def test_send_animation_custom_filename(self, bot, chat_id, animation_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_animation_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("animation") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("animation"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_animation(chat_id, file, thumb=file) + assert test_flag + finally: + bot._local_mode = False + + async def test_send_with_animation(self, monkeypatch, bot, chat_id, animation): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["animation"] == animation.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_animation(animation=animation, chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, animation): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == animation.file_id + + assert check_shortcut_signature(Animation.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(animation.get_file, animation.get_bot(), "get_file") + assert await check_defaults_handling(animation.get_file, animation.get_bot()) + + monkeypatch.setattr(animation.get_bot(), "get_file", make_assertion) + assert await animation.get_file() + class TestAnimationReq: async def test_send_all_args(self, bot, chat_id, animation_file, animation, thumb_file): @@ -229,7 +227,6 @@ async def test_get_and_download(self, bot, animation): assert new_file.file_path.startswith("https://") new_filepath = await new_file.download_to_drive("game.gif") - assert new_filepath.is_file() async def test_send_animation_url_file(self, bot, chat_id, animation): @@ -341,7 +338,6 @@ async def test_send_animation_default_protect_content(self, default_bot, chat_id async def test_resend(self, bot, chat_id, animation): message = await bot.send_animation(chat_id, animation.file_id) - assert message.animation == animation async def test_error_send_empty_file(self, bot, chat_id): diff --git a/tests/test_audio.py b/tests/test_audio.py index 29f9de940e0..a1f69de6aa6 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -88,46 +88,6 @@ def test_expected_values(self, audio): assert audio.thumb.width == Space.thumb_width assert audio.thumb.height == Space.thumb_height - async def test_send_audio_custom_filename(self, bot, chat_id, audio_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_audio(chat_id, audio_file, filename="custom_filename") - - async def test_send_with_audio(self, monkeypatch, bot, chat_id, audio): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["audio"] == audio.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_audio(audio=audio, chat_id=chat_id) - assert message - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_audio_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("audio") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("audio"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_audio(chat_id, file, thumb=file) - assert test_flag - finally: - bot._local_mode = False - def test_de_json(self, bot, audio): json_dict = { "file_id": Space.audio_file_id, @@ -164,17 +124,6 @@ def test_to_dict(self, audio): assert audio_dict["file_size"] == audio.file_size assert audio_dict["file_name"] == audio.file_name - async def test_get_file_instance_method(self, monkeypatch, audio): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == audio.file_id - - assert check_shortcut_signature(Audio.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(audio.get_file, audio.get_bot(), "get_file") - assert await check_defaults_handling(audio.get_file, audio.get_bot()) - - monkeypatch.setattr(audio._bot, "get_file", make_assertion) - assert await audio.get_file() - def test_equality(self, audio): a = Audio(audio.file_id, audio.file_unique_id, audio.duration) b = Audio("", audio.file_unique_id, audio.duration) @@ -195,6 +144,55 @@ def test_equality(self, audio): assert a != e assert hash(a) != hash(e) + async def test_send_with_audio(self, monkeypatch, bot, chat_id, audio): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["audio"] == audio.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_audio(audio=audio, chat_id=chat_id) + + async def test_send_audio_custom_filename(self, bot, chat_id, audio_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_audio(chat_id, audio_file, filename="custom_filename") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_audio_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("audio") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("audio"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_audio(chat_id, file, thumb=file) + assert test_flag + finally: + bot._local_mode = False + + async def test_get_file_instance_method(self, monkeypatch, audio): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == audio.file_id + + assert check_shortcut_signature(Audio.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(audio.get_file, audio.get_bot(), "get_file") + assert await check_defaults_handling(audio.get_file, audio.get_bot()) + + monkeypatch.setattr(audio._bot, "get_file", make_assertion) + assert await audio.get_file() + class TestAudioReq: async def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): @@ -242,7 +240,6 @@ async def test_get_and_download(self, bot, audio): assert str(new_file.file_path).startswith("https://") await new_file.download_to_drive("telegram.mp3") - assert path.is_file() async def test_send_mp3_url_file(self, bot, chat_id, audio): @@ -261,11 +258,6 @@ async def test_send_mp3_url_file(self, bot, chat_id, audio): assert message.audio.mime_type == audio.mime_type assert message.audio.file_size == audio.file_size - async def test_resend(self, bot, chat_id, audio): - message = await bot.send_audio(chat_id=chat_id, audio=audio.file_id) - - assert message.audio == audio - async def test_send_audio_caption_entities(self, bot, chat_id, audio): test_string = "Italic Bold Code" entities = [ @@ -319,6 +311,10 @@ async def test_send_audio_default_protect_content(self, default_bot, chat_id, au assert protected.has_protected_content assert not unprotected.has_protected_content + async def test_resend(self, bot, chat_id, audio): + message = await bot.send_audio(chat_id=chat_id, audio=audio.file_id) + assert message.audio == audio + async def test_error_send_empty_file(self, bot, chat_id): audio_file = open(os.devnull, "rb") diff --git a/tests/test_bot.py b/tests/test_bot.py index 51e3f56157a..f437040ef6f 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -205,6 +205,20 @@ def test_slot_behaviour(self, bot_class, bot, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + async def test_no_token_passed(self): + with pytest.raises(InvalidToken, match="You must pass the token"): + Bot("") + + async def test_to_dict(self, bot): + to_dict_bot = bot.to_dict() + + assert isinstance(to_dict_bot, dict) + assert to_dict_bot["id"] == bot.id + assert to_dict_bot["username"] == bot.username + assert to_dict_bot["first_name"] == bot.first_name + if bot.last_name: + assert to_dict_bot["last_name"] == bot.last_name + async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): test_flag = [] @@ -293,48 +307,24 @@ async def shutdown(): assert test_flag == "stop" - async def test_log_decorator(self, bot: DictExtBot, caplog): - # Second argument makes sure that we ignore logs from e.g. httpx - with caplog.at_level(logging.DEBUG, logger="telegram"): - await super(bot.__class__, bot).get_me() # call original get_me instead of overriden - # Only for stabilizing this test- - if len(caplog.records) == 4: - for idx, record in enumerate(caplog.records): - print(record) - if record.getMessage().startswith("Task was destroyed but it is pending"): - caplog.records.pop(idx) - if record.getMessage().startswith("Task exception was never retrieved"): - caplog.records.pop(idx) - assert len(caplog.records) == 3 - assert caplog.records[0].getMessage().startswith("Entering: get_me") - assert caplog.records[-1].getMessage().startswith("Exiting: get_me") + async def test_equality(self): + async with make_bot(token=FALLBACKS[0]["token"]) as a, make_bot( + token=FALLBACKS[0]["token"] + ) as b, make_bot(token=FALLBACKS[1]["token"]) as c, Bot(token=FALLBACKS[0]["token"]) as d: + e = Update(123456789) - @pytest.mark.parametrize( - "acd_in,maxsize", - [(True, 1024), (False, 1024), (0, 0), (None, None)], - ) - async def test_callback_data_maxsize(self, bot_info, acd_in, maxsize): - async with make_bot(bot_info, arbitrary_callback_data=acd_in) as acd_bot: - if acd_in is not False: - assert acd_bot.callback_data_cache.maxsize == maxsize - else: - assert acd_bot.callback_data_cache is None + assert a == b + assert hash(a) == hash(b) + assert a is not b - async def test_no_token_passed(self): - with pytest.raises(InvalidToken, match="You must pass the token"): - Bot("") + assert a != c + assert hash(a) != hash(c) - async def test_unknown_kwargs(self, bot, monkeypatch): - async def post(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - if not all([data["unknown_kwarg_1"] == "7", data["unknown_kwarg_2"] == "5"]): - pytest.fail("got wrong parameters") - return True + assert a != d + assert hash(a) != hash(d) - monkeypatch.setattr(bot.request, "post", post) - await bot.send_message( - 123, "text", api_kwargs={"unknown_kwarg_1": 7, "unknown_kwarg_2": 5} - ) + assert a != e + assert hash(a) != hash(e) @pytest.mark.parametrize( "attribute", @@ -377,38 +367,63 @@ async def test_get_me_and_properties(self, bot): assert get_me_bot.supports_inline_queries == bot.supports_inline_queries assert f"https://t.me/{get_me_bot.username}" == bot.link - async def test_equality(self): - async with make_bot(token=FALLBACKS[0]["token"]) as a, make_bot( - token=FALLBACKS[0]["token"] - ) as b, make_bot(token=FALLBACKS[1]["token"]) as c, Bot(token=FALLBACKS[0]["token"]) as d: - e = Update(123456789) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != c - assert hash(a) != hash(c) + def test_bot_pickling_error(self, bot): + with pytest.raises(pickle.PicklingError, match="Bot objects cannot be pickled"): + pickle.dumps(bot) - assert a != d - assert hash(a) != hash(d) + async def test_log_decorator(self, bot: DictExtBot, caplog): + # Second argument makes sure that we ignore logs from e.g. httpx + with caplog.at_level(logging.DEBUG, logger="telegram"): + await super(bot.__class__, bot).get_me() # call original get_me instead of overriden + # Only for stabilizing this test- + if len(caplog.records) == 4: + for idx, record in enumerate(caplog.records): + print(record) + if record.getMessage().startswith("Task was destroyed but it is pending"): + caplog.records.pop(idx) + if record.getMessage().startswith("Task exception was never retrieved"): + caplog.records.pop(idx) + assert len(caplog.records) == 3 + assert caplog.records[0].getMessage().startswith("Entering: get_me") + assert caplog.records[-1].getMessage().startswith("Exiting: get_me") - assert a != e - assert hash(a) != hash(e) + @bot_methods() + def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): + camel_case_name = to_camel_case(bot_method_name) + camel_case_function = getattr(bot_class, camel_case_name, False) + assert camel_case_function is not False, f"{camel_case_name} not found" + assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}" - async def test_to_dict(self, bot): - to_dict_bot = bot.to_dict() + @bot_methods() + def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): + """Check that all bot methods are defined as async def ...""" + meth = getattr(bot_method, "__wrapped__", bot_method) + assert inspect.iscoroutinefunction(meth), f"{bot_method_name} must be a coroutine function" - assert isinstance(to_dict_bot, dict) - assert to_dict_bot["id"] == bot.id - assert to_dict_bot["username"] == bot.username - assert to_dict_bot["first_name"] == bot.first_name - if bot.last_name: - assert to_dict_bot["last_name"] == bot.last_name + @bot_methods() + def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): + """Check that all bot methods have `api_kwargs` and timeout params.""" + param_names = inspect.signature(bot_method).parameters.keys() + assert ( + "pool_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `pool_timeout`" + assert ( + "read_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `read_timeout`" + assert ( + "connect_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `connect_timeout`" + assert ( + "write_timeout" in param_names + ), f"{bot_method_name} is missing the parameter `write_timeout`" + assert ( + "api_kwargs" in param_names + ), f"{bot_method_name} is missing the parameter `api_kwargs`" - def test_bot_pickling_error(self, bot): - with pytest.raises(pickle.PicklingError, match="Bot objects cannot be pickled"): - pickle.dumps(bot) + if bot_class is ExtBot and bot_method_name.replace("_", "").lower() != "getupdates": + assert ( + "rate_limit_args" in param_names + ), f"{bot_method_name} of ExtBot is missing the parameter `rate_limit_args`" @bot_methods(ext_bot=False) async def test_defaults_handling( @@ -418,7 +433,6 @@ async def test_defaults_handling( bot_method, bot: DictExtBot, raw_bot: DictBot, - monkeypatch, ): """ Here we check that the bot methods handle tg.ext.Defaults correctly. This has two parts: @@ -488,6 +502,18 @@ def test_ext_bot_signature(self): param.kind == ext_signature.parameters[param_name].kind ), f"Wrong parameter kind for parameter {param_name} of method {name}" + async def test_unknown_kwargs(self, bot, monkeypatch): + async def post(url, request_data: RequestData, *args, **kwargs): + data = request_data.json_parameters + if not all([data["unknown_kwarg_1"] == "7", data["unknown_kwarg_2"] == "5"]): + pytest.fail("got wrong parameters") + return True + + monkeypatch.setattr(bot.request, "post", post) + await bot.send_message( + 123, "text", api_kwargs={"unknown_kwarg_1": 7, "unknown_kwarg_2": 5} + ) + async def test_answer_web_app_query(self, bot, raw_bot, monkeypatch): params = False @@ -1370,6 +1396,17 @@ async def post(url, request_data: RequestData, *args, **kwargs): # The same must be done in the webhook updater. This is tested over at test_updater.py, but # here we test more extensively. + @pytest.mark.parametrize( + "acd_in,maxsize", + [(True, 1024), (False, 1024), (0, 0), (None, None)], + ) + async def test_callback_data_maxsize(self, bot_info, acd_in, maxsize): + async with make_bot(bot_info, arbitrary_callback_data=acd_in) as acd_bot: + if acd_in is not False: + assert acd_bot.callback_data_cache.maxsize == maxsize + else: + assert acd_bot.callback_data_cache is None + async def test_arbitrary_callback_data_no_insert(self, monkeypatch, cdc_bot): """Updates that don't need insertion shouldn't fail obviously""" bot = cdc_bot @@ -1599,44 +1636,6 @@ async def post(*args, **kwargs): bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - @bot_methods() - def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): - camel_case_name = to_camel_case(bot_method_name) - camel_case_function = getattr(bot_class, camel_case_name, False) - assert camel_case_function is not False, f"{camel_case_name} not found" - assert camel_case_function is bot_method, f"{camel_case_name} is not {bot_method}" - - @bot_methods() - def test_coroutine_functions(self, bot_class, bot_method_name, bot_method, monkeypatch): - """Check that all bot methods are defined as async def ...""" - meth = getattr(bot_method, "__wrapped__", bot_method) - assert inspect.iscoroutinefunction(meth), f"{bot_method_name} must be a coroutine function" - - @bot_methods() - def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): - """Check that all bot methods have `api_kwargs` and timeout params.""" - param_names = inspect.signature(bot_method).parameters.keys() - assert ( - "pool_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `pool_timeout`" - assert ( - "read_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `read_timeout`" - assert ( - "connect_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `connect_timeout`" - assert ( - "write_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `write_timeout`" - assert ( - "api_kwargs" in param_names - ), f"{bot_method_name} is missing the parameter `api_kwargs`" - - if bot_class is ExtBot and bot_method_name.replace("_", "").lower() != "getupdates": - assert ( - "rate_limit_args" in param_names - ), f"{bot_method_name} of ExtBot is missing the parameter `rate_limit_args`" - class TestBotReq: """ diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 2135f7569c2..1422d120580 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -123,6 +123,26 @@ def test_to_dict(self, callback_query): assert callback_query_dict["data"] == callback_query.data assert callback_query_dict["game_short_name"] == callback_query.game_short_name + def test_equality(self): + a = CallbackQuery(Space.id_, Space.from_user, "chat") + b = CallbackQuery(Space.id_, Space.from_user, "chat") + c = CallbackQuery(Space.id_, None, "") + d = CallbackQuery("", None, "chat") + e = Audio(Space.id_, "unique_id", 1) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + async def test_answer(self, monkeypatch, callback_query): async def make_assertion(*_, **kwargs): return kwargs["callback_query_id"] == callback_query.id @@ -449,23 +469,3 @@ async def make_assertion(*args, **kwargs): monkeypatch.setattr(callback_query.get_bot(), "copy_message", make_assertion) assert await callback_query.copy_message(1) - - def test_equality(self): - a = CallbackQuery(Space.id_, Space.from_user, "chat") - b = CallbackQuery(Space.id_, Space.from_user, "chat") - c = CallbackQuery(Space.id_, None, "") - d = CallbackQuery("", None, "chat") - e = Audio(Space.id_, "unique_id", 1) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a == c - assert hash(a) == hash(c) - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) diff --git a/tests/test_chat.py b/tests/test_chat.py index 541f3c49a34..e7f67b59164 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -202,6 +202,26 @@ def test_full_name(self): ) assert chat.full_name is None + def test_equality(self): + a = Chat(Space.id_, Space.title, Space.type_) + b = Chat(Space.id_, Space.title, Space.type_) + c = Chat(Space.id_, "", "") + d = Chat(0, Space.title, Space.type_) + e = User(Space.id_, "", False) + + 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) + async def test_send_action(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): id_ = kwargs["chat_id"] == chat.id @@ -1125,23 +1145,3 @@ def test_mention_markdown_v2(self): ): chat = Chat(id=1, type="foo", username="user\u2022name") chat.mention_markdown_v2() - - def test_equality(self): - a = Chat(Space.id_, Space.title, Space.type_) - b = Chat(Space.id_, Space.title, Space.type_) - c = Chat(Space.id_, "", "") - d = Chat(0, Space.title, Space.type_) - e = User(Space.id_, "", False) - - 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_chatphoto.py b/tests/test_chatphoto.py index f0b0a2c3b91..323febaa346 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -64,14 +64,6 @@ def test_slot_behaviour(self, chat_photo, mro_slots): assert getattr(chat_photo, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(chat_photo)) == len(set(mro_slots(chat_photo))), "duplicate slot" - async def test_send_with_chat_photo(self, monkeypatch, bot, super_group_id, chat_photo): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.parameters["photo"] == chat_photo.to_dict() - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.set_chat_photo(photo=chat_photo, chat_id=super_group_id) - assert message - def test_de_json(self, bot, chat_photo): json_dict = { "small_file_id": Space.chatphoto_small_file_id, @@ -95,30 +87,6 @@ async def test_to_dict(self, chat_photo): assert chat_photo_dict["small_file_unique_id"] == chat_photo.small_file_unique_id assert chat_photo_dict["big_file_unique_id"] == chat_photo.big_file_unique_id - async def test_get_small_file_instance_method(self, monkeypatch, chat_photo): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == chat_photo.small_file_id - - assert check_shortcut_signature(ChatPhoto.get_small_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call( - chat_photo.get_small_file, chat_photo.get_bot(), "get_file" - ) - assert await check_defaults_handling(chat_photo.get_small_file, chat_photo.get_bot()) - - monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion) - assert await chat_photo.get_small_file() - - async def test_get_big_file_instance_method(self, monkeypatch, chat_photo): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == chat_photo.big_file_id - - assert check_shortcut_signature(ChatPhoto.get_big_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(chat_photo.get_big_file, chat_photo.get_bot(), "get_file") - assert await check_defaults_handling(chat_photo.get_big_file, chat_photo.get_bot()) - - monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion) - assert await chat_photo.get_big_file() - def test_equality(self): a = ChatPhoto( Space.chatphoto_small_file_id, @@ -151,6 +119,38 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + async def test_send_with_chat_photo(self, monkeypatch, bot, super_group_id, chat_photo): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.parameters["photo"] == chat_photo.to_dict() + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.set_chat_photo(photo=chat_photo, chat_id=super_group_id) + assert message + + async def test_get_small_file_instance_method(self, monkeypatch, chat_photo): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == chat_photo.small_file_id + + assert check_shortcut_signature(ChatPhoto.get_small_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call( + chat_photo.get_small_file, chat_photo.get_bot(), "get_file" + ) + assert await check_defaults_handling(chat_photo.get_small_file, chat_photo.get_bot()) + + monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion) + assert await chat_photo.get_small_file() + + async def test_get_big_file_instance_method(self, monkeypatch, chat_photo): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == chat_photo.big_file_id + + assert check_shortcut_signature(ChatPhoto.get_big_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(chat_photo.get_big_file, chat_photo.get_bot(), "get_file") + assert await check_defaults_handling(chat_photo.get_big_file, chat_photo.get_bot()) + + monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion) + assert await chat_photo.get_big_file() + class TestChatPhotoReq: async def test_get_and_download(self, bot, chat_photo): diff --git a/tests/test_contact.py b/tests/test_contact.py index c7b1d3c7399..19e18d5394b 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -67,31 +67,6 @@ def test_de_json_all(self, bot): assert contact.last_name == Space.last_name assert contact.user_id == Space.user_id - async def test_send_with_contact(self, monkeypatch, bot, chat_id, contact): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - 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 - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_contact(contact=contact, chat_id=chat_id) - assert message - - async def test_send_contact_without_required(self, bot, chat_id): - with pytest.raises(ValueError, match="Either contact or phone_number and first_name"): - await bot.send_contact(chat_id=chat_id) - - async def test_send_mutually_exclusive(self, bot, chat_id, contact): - with pytest.raises(ValueError, match="Not both"): - await bot.send_contact( - chat_id=chat_id, - contact=contact, - phone_number=contact.phone_number, - first_name=contact.first_name, - ) - def test_to_dict(self, contact): contact_dict = contact.to_dict() @@ -121,6 +96,30 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + async def test_send_contact_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match="Either contact or phone_number and first_name"): + await bot.send_contact(chat_id=chat_id) + + async def test_send_mutually_exclusive(self, bot, chat_id, contact): + with pytest.raises(ValueError, match="Not both"): + await bot.send_contact( + chat_id=chat_id, + contact=contact, + phone_number=contact.phone_number, + first_name=contact.first_name, + ) + + async def test_send_with_contact(self, monkeypatch, bot, chat_id, contact): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.json_parameters + 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 + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_contact(contact=contact, chat_id=chat_id) + class TestContactReq: @pytest.mark.parametrize( diff --git a/tests/test_document.py b/tests/test_document.py index d882553a2e8..88ca100da08 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -80,6 +80,55 @@ def test_expected_values(self, document): assert document.thumb.width == Space.thumb_width assert document.thumb.height == Space.thumb_height + def test_de_json(self, bot, document): + json_dict = { + "file_id": Space.document_file_id, + "file_unique_id": Space.document_file_unique_id, + "thumb": document.thumb.to_dict(), + "file_name": Space.file_name, + "mime_type": Space.mime_type, + "file_size": Space.file_size, + } + test_document = Document.de_json(json_dict, bot) + assert test_document.api_kwargs == {} + + assert test_document.file_id == Space.document_file_id + assert test_document.file_unique_id == Space.document_file_unique_id + assert test_document.thumb == document.thumb + assert test_document.file_name == Space.file_name + assert test_document.mime_type == Space.mime_type + assert test_document.file_size == Space.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_unique_id"] == document.file_unique_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 + + def test_equality(self, document): + a = Document(document.file_id, document.file_unique_id) + b = Document("", document.file_unique_id) + d = Document("", "") + e = Voice(document.file_id, document.file_unique_id, 0) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + + async def test_error_send_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_document(chat_id=chat_id) + @pytest.mark.parametrize("disable_content_type_detection", [True, False, None]) async def test_send_with_document( self, monkeypatch, bot, chat_id, document, disable_content_type_detection @@ -125,39 +174,6 @@ async def make_assertion(_, data, *args, **kwargs): finally: bot._local_mode = False - def test_de_json(self, bot, document): - json_dict = { - "file_id": Space.document_file_id, - "file_unique_id": Space.document_file_unique_id, - "thumb": document.thumb.to_dict(), - "file_name": Space.file_name, - "mime_type": Space.mime_type, - "file_size": Space.file_size, - } - test_document = Document.de_json(json_dict, bot) - assert test_document.api_kwargs == {} - - assert test_document.file_id == Space.document_file_id - assert test_document.file_unique_id == Space.document_file_unique_id - assert test_document.thumb == document.thumb - assert test_document.file_name == Space.file_name - assert test_document.mime_type == Space.mime_type - assert test_document.file_size == Space.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_unique_id"] == document.file_unique_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 - - async def test_error_send_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_document(chat_id=chat_id) - async def test_get_file_instance_method(self, monkeypatch, document): async def make_assertion(*_, **kwargs): return kwargs["file_id"] == document.file_id @@ -169,22 +185,6 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(document.get_bot(), "get_file", make_assertion) assert await document.get_file() - def test_equality(self, document): - a = Document(document.file_id, document.file_unique_id) - b = Document("", document.file_unique_id) - d = Document("", "") - e = Voice(document.file_id, document.file_unique_id, 0) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) - class TestDocumentReq: async def test_error_send_empty_file(self, bot, chat_id): diff --git a/tests/test_file.py b/tests/test_file.py index 99d0f9e3702..65c1c0fcaec 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -125,6 +125,26 @@ def test_to_dict(self, file): assert file_dict["file_path"] == file.file_path assert file_dict["file_size"] == file.file_size + def test_equality(self, bot): + a = File(Space.file_id, Space.file_unique_id, bot) + b = File("", Space.file_unique_id, bot) + c = File(Space.file_id, Space.file_unique_id, None) + d = File("", "", bot) + e = Voice(Space.file_id, Space.file_unique_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) + async def test_download(self, monkeypatch, file): async def test(*args, **kwargs): return Space.file_content @@ -219,22 +239,6 @@ async def test(*args, **kwargs): custom_fobj.seek(0) assert custom_fobj.read() == data_file("image_decrypted.jpg").read_bytes() - @pytest.mark.parametrize( - "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] - ) - async def test_download_custom_path_local_file_encrypted( - self, encrypted_local_file, custom_path_type - ): - file_handle, custom_path = mkstemp() - custom_path = Path(custom_path) - try: - out_file = await encrypted_local_file.download_to_drive(custom_path_type(custom_path)) - assert out_file == custom_path - assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes() - finally: - os.close(file_handle) - custom_path.unlink() - async def test_download_file_obj_local_file_encrypted(self, monkeypatch, encrypted_local_file): async def test(*args, **kwargs): return data_file("image_encrypted.jpg").read_bytes() @@ -262,26 +266,6 @@ async def test(*args, **kwargs): assert buf2[len(buf) :] == buf assert buf2[: len(buf)] == buf - def test_equality(self, bot): - a = File(Space.file_id, Space.file_unique_id, bot) - b = File("", Space.file_unique_id, bot) - c = File(Space.file_id, Space.file_unique_id, None) - d = File("", "", bot) - e = Voice(Space.file_id, Space.file_unique_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) - class TestFileReq: async def test_error_get_empty_file_id(self, bot): @@ -311,6 +295,22 @@ async def test_download_file_obj_local_file(self, local_file): custom_fobj.seek(0) assert custom_fobj.read() == Space.file_content + @pytest.mark.parametrize( + "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] + ) + async def test_download_custom_path_local_file_encrypted( + self, encrypted_local_file, custom_path_type + ): + file_handle, custom_path = mkstemp() + custom_path = Path(custom_path) + try: + out_file = await encrypted_local_file.download_to_drive(custom_path_type(custom_path)) + assert out_file == custom_path + assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes() + finally: + os.close(file_handle) + custom_path.unlink() + async def test_download_local_file_encrypted(self, encrypted_local_file): out_file = await encrypted_local_file.download_to_drive() try: diff --git a/tests/test_game.py b/tests/test_game.py index 9c63cac0a29..85c78956052 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -97,20 +97,6 @@ def test_to_dict(self, game): assert game_dict["text_entities"] == [game.text_entities[0].to_dict()] assert game_dict["animation"] == game.animation.to_dict() - def test_parse_entity(self, game): - entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) - game.text_entities = [entity] - - assert game.parse_text_entity(entity) == "http://google.com" - - 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"} - def test_equality(self): a = Game("title", "description", [PhotoSize("Blah", "unique_id", 640, 360, file_size=0)]) b = Game( @@ -135,3 +121,17 @@ def test_equality(self): assert a != d assert hash(a) != hash(d) + + def test_parse_entity(self, game): + entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) + game.text_entities = [entity] + + assert game.parse_text_entity(entity) == "http://google.com" + + 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_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 1c63e14624d..70bd6331836 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -49,86 +49,6 @@ def test_slot_behaviour(self, inline_keyboard_markup, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - def test_from_button(self): - inline_keyboard_markup = InlineKeyboardMarkup.from_button( - InlineKeyboardButton(text="button1", callback_data="data1") - ).inline_keyboard - assert len(inline_keyboard_markup) == 1 - assert len(inline_keyboard_markup[0]) == 1 - - def test_from_row(self): - inline_keyboard_markup = InlineKeyboardMarkup.from_row( - [ - InlineKeyboardButton(text="button1", callback_data="data1"), - InlineKeyboardButton(text="button1", callback_data="data1"), - ] - ).inline_keyboard - assert len(inline_keyboard_markup) == 1 - assert len(inline_keyboard_markup[0]) == 2 - - def test_from_column(self): - inline_keyboard_markup = InlineKeyboardMarkup.from_column( - [ - InlineKeyboardButton(text="button1", callback_data="data1"), - InlineKeyboardButton(text="button1", callback_data="data1"), - ] - ).inline_keyboard - assert len(inline_keyboard_markup) == 2 - assert len(inline_keyboard_markup[0]) == 1 - assert len(inline_keyboard_markup[1]) == 1 - - def test_expected_values(self, inline_keyboard_markup): - assert inline_keyboard_markup.inline_keyboard == tuple( - tuple(row) for row in Space.inline_keyboard - ) - - def test_wrong_keyboard_inputs(self): - with pytest.raises(ValueError): - InlineKeyboardMarkup( - [[InlineKeyboardButton("b1", "1")], InlineKeyboardButton("b2", "2")] - ) - with pytest.raises(ValueError): - InlineKeyboardMarkup("strings_are_not_allowed") - with pytest.raises(ValueError): - InlineKeyboardMarkup(["strings_are_not_allowed_in_the_rows_either"]) - with pytest.raises(ValueError): - InlineKeyboardMarkup(InlineKeyboardButton("b1", "1")) - - async def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): - async def make_assertion( - url, - data, - reply_to_message_id=None, - disable_notification=None, - reply_markup=None, - timeout=None, - **kwargs, - ): - if reply_markup is not None: - markups = ( - InlineKeyboardMarkup, - ReplyKeyboardMarkup, - ForceReply, - ReplyKeyboardRemove, - ) - if isinstance(reply_markup, markups): - data["reply_markup"] = reply_markup.to_dict() - else: - data["reply_markup"] = reply_markup - - assert bool("'switch_inline_query': ''" in str(data["reply_markup"])) - assert bool("'switch_inline_query_current_chat': ''" in str(data["reply_markup"])) - - inline_keyboard_markup.inline_keyboard[0][0]._unfreeze() - inline_keyboard_markup.inline_keyboard[0][0].callback_data = None - inline_keyboard_markup.inline_keyboard[0][0].switch_inline_query = "" - inline_keyboard_markup.inline_keyboard[0][1]._unfreeze() - inline_keyboard_markup.inline_keyboard[0][1].callback_data = None - inline_keyboard_markup.inline_keyboard[0][1].switch_inline_query_current_chat = "" - - monkeypatch.setattr(bot, "_send_message", make_assertion) - await bot.send_message(123, "test", reply_markup=inline_keyboard_markup) - def test_to_dict(self, inline_keyboard_markup): inline_keyboard_markup_dict = inline_keyboard_markup.to_dict() @@ -224,6 +144,86 @@ def test_equality(self): assert a != g assert hash(a) != hash(g) + def test_from_button(self): + inline_keyboard_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text="button1", callback_data="data1") + ).inline_keyboard + assert len(inline_keyboard_markup) == 1 + assert len(inline_keyboard_markup[0]) == 1 + + def test_from_row(self): + inline_keyboard_markup = InlineKeyboardMarkup.from_row( + [ + InlineKeyboardButton(text="button1", callback_data="data1"), + InlineKeyboardButton(text="button1", callback_data="data1"), + ] + ).inline_keyboard + assert len(inline_keyboard_markup) == 1 + assert len(inline_keyboard_markup[0]) == 2 + + def test_from_column(self): + inline_keyboard_markup = InlineKeyboardMarkup.from_column( + [ + InlineKeyboardButton(text="button1", callback_data="data1"), + InlineKeyboardButton(text="button1", callback_data="data1"), + ] + ).inline_keyboard + assert len(inline_keyboard_markup) == 2 + assert len(inline_keyboard_markup[0]) == 1 + assert len(inline_keyboard_markup[1]) == 1 + + def test_expected_values(self, inline_keyboard_markup): + assert inline_keyboard_markup.inline_keyboard == tuple( + tuple(row) for row in Space.inline_keyboard + ) + + def test_wrong_keyboard_inputs(self): + with pytest.raises(ValueError): + InlineKeyboardMarkup( + [[InlineKeyboardButton("b1", "1")], InlineKeyboardButton("b2", "2")] + ) + with pytest.raises(ValueError): + InlineKeyboardMarkup("strings_are_not_allowed") + with pytest.raises(ValueError): + InlineKeyboardMarkup(["strings_are_not_allowed_in_the_rows_either"]) + with pytest.raises(ValueError): + InlineKeyboardMarkup(InlineKeyboardButton("b1", "1")) + + async def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): + async def make_assertion( + url, + data, + reply_to_message_id=None, + disable_notification=None, + reply_markup=None, + timeout=None, + **kwargs, + ): + if reply_markup is not None: + markups = ( + InlineKeyboardMarkup, + ReplyKeyboardMarkup, + ForceReply, + ReplyKeyboardRemove, + ) + if isinstance(reply_markup, markups): + data["reply_markup"] = reply_markup.to_dict() + else: + data["reply_markup"] = reply_markup + + assert bool("'switch_inline_query': ''" in str(data["reply_markup"])) + assert bool("'switch_inline_query_current_chat': ''" in str(data["reply_markup"])) + + inline_keyboard_markup.inline_keyboard[0][0]._unfreeze() + inline_keyboard_markup.inline_keyboard[0][0].callback_data = None + inline_keyboard_markup.inline_keyboard[0][0].switch_inline_query = "" + inline_keyboard_markup.inline_keyboard[0][1]._unfreeze() + inline_keyboard_markup.inline_keyboard[0][1].callback_data = None + inline_keyboard_markup.inline_keyboard[0][1].switch_inline_query_current_chat = "" + + monkeypatch.setattr(bot, "_send_message", make_assertion) + await bot.send_message(123, "test", reply_markup=inline_keyboard_markup) + class TestInlineKeyborardMarkupReq: async def test_send_message_with_inline_keyboard_markup( diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index a99cd6ee42b..25351f77390 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -81,6 +81,30 @@ def test_to_dict(self, inline_query): assert inline_query_dict["query"] == inline_query.query assert inline_query_dict["offset"] == inline_query.offset + def test_equality(self): + a = InlineQuery(Space.id_, User(1, "", False), "", "") + b = InlineQuery(Space.id_, User(1, "", False), "", "") + c = InlineQuery(Space.id_, User(0, "", False), "", "") + d = InlineQuery(0, User(1, "", False), "", "") + e = Update(Space.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) + + async def test_answer_error(self, inline_query): + with pytest.raises(ValueError, match="mutually exclusive"): + await inline_query.answer(results=[], auto_pagination=True, current_offset="foobar") + async def test_answer(self, monkeypatch, inline_query): async def make_assertion(*_, **kwargs): return kwargs["inline_query_id"] == inline_query.id @@ -96,10 +120,6 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(inline_query.get_bot(), "answer_inline_query", make_assertion) assert await inline_query.answer(results=[]) - async def test_answer_error(self, inline_query): - with pytest.raises(ValueError, match="mutually exclusive"): - await inline_query.answer(results=[], auto_pagination=True, current_offset="foobar") - async def test_answer_auto_pagination(self, monkeypatch, inline_query): async def make_assertion(*_, **kwargs): inline_query_id_matches = kwargs["inline_query_id"] == inline_query.id @@ -108,23 +128,3 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(inline_query.get_bot(), "answer_inline_query", make_assertion) assert await inline_query.answer(results=[], auto_pagination=True) - - def test_equality(self): - a = InlineQuery(Space.id_, User(1, "", False), "", "") - b = InlineQuery(Space.id_, User(1, "", False), "", "") - c = InlineQuery(Space.id_, User(0, "", False), "", "") - d = InlineQuery(0, User(1, "", False), "", "") - e = Update(Space.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_inputmedia.py b/tests/test_inputmedia.py index 98422f0334f..ec62c703f96 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -703,6 +703,36 @@ async def test_send_media_group_all_args(self, bot, raw_bot, chat_id, media_grou ) assert all(mes.has_protected_content for mes in messages) + async def test_edit_message_media(self, bot, raw_bot, chat_id, media_group): + ext_bot = bot + # We need to test 1) below both the bot and raw_bot and setting this up with + # pytest.parametrize appears to be difficult ... + aws = {b.send_media_group(chat_id, media_group) for b in (ext_bot, raw_bot)} + for msg_task in asyncio.as_completed(aws): + messages = await msg_task + cid = messages[-1].chat.id + mid = messages[-1].message_id + copied_media = copy.copy(media_group[0]) + new_message = ( + await messages[-1] + .get_bot() + .edit_message_media(chat_id=cid, message_id=mid, media=media_group[0]) + ) + assert isinstance(new_message, Message) + + # 1) + # make sure that the media was not modified + assert media_group[0].parse_mode == copied_media.parse_mode + + async def test_edit_message_media_new_file(self, bot, chat_id, media_group, thumb_file): + messages = await bot.send_media_group(chat_id, media_group) + cid = messages[-1].chat.id + mid = messages[-1].message_id + new_message = await bot.edit_message_media( + chat_id=cid, message_id=mid, media=InputMediaPhoto(thumb_file) + ) + assert isinstance(new_message, Message) + @pytest.mark.parametrize( "default_bot,custom", [ @@ -794,36 +824,6 @@ async def test_send_media_group_default_parse_mode( assert all(mes.caption is None for mes in other_messages) assert not any(mes.caption_entities for mes in other_messages) - async def test_edit_message_media(self, bot, raw_bot, chat_id, media_group): - ext_bot = bot - # We need to test 1) below both the bot and raw_bot and setting this up with - # pytest.parametrize appears to be difficult ... - aws = {b.send_media_group(chat_id, media_group) for b in (ext_bot, raw_bot)} - for msg_task in asyncio.as_completed(aws): - messages = await msg_task - cid = messages[-1].chat.id - mid = messages[-1].message_id - copied_media = copy.copy(media_group[0]) - new_message = ( - await messages[-1] - .get_bot() - .edit_message_media(chat_id=cid, message_id=mid, media=media_group[0]) - ) - assert isinstance(new_message, Message) - - # 1) - # make sure that the media was not modified - assert media_group[0].parse_mode == copied_media.parse_mode - - async def test_edit_message_media_new_file(self, bot, chat_id, media_group, thumb_file): - messages = await bot.send_media_group(chat_id, media_group) - cid = messages[-1].chat.id - mid = messages[-1].message_id - new_message = await bot.edit_message_media( - chat_id=cid, message_id=mid, media=InputMediaPhoto(thumb_file) - ) - assert isinstance(new_message, Message) - @pytest.mark.parametrize( "default_bot", [{"parse_mode": ParseMode.HTML}], indirect=True, ids=["HTML-Bot"] ) diff --git a/tests/test_location.py b/tests/test_location.py index 157a4d88a94..4c5a0ce6eff 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -71,6 +71,46 @@ def test_de_json(self, bot): assert location.heading == Space.heading assert location.proximity_alert_radius == Space.proximity_alert_radius + def test_to_dict(self, location): + location_dict = location.to_dict() + + assert location_dict["latitude"] == location.latitude + assert location_dict["longitude"] == location.longitude + assert location_dict["horizontal_accuracy"] == location.horizontal_accuracy + assert location_dict["live_period"] == location.live_period + assert location["heading"] == location.heading + assert location["proximity_alert_radius"] == location.proximity_alert_radius + + def test_equality(self): + a = Location(Space.longitude, Space.latitude) + b = Location(Space.longitude, Space.latitude) + d = Location(0, Space.latitude) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != d + assert hash(a) != hash(d) + + async def test_send_location_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match="Either location or latitude and longitude"): + await bot.send_location(chat_id=chat_id) + + async def test_edit_location_without_required(self, bot): + with pytest.raises(ValueError, match="Either location or latitude and longitude"): + await bot.edit_message_live_location(chat_id=2, message_id=3) + + async def test_send_location_with_all_args(self, bot, location): + with pytest.raises(ValueError, match="Not both"): + await bot.send_location(chat_id=1, latitude=2.5, longitude=4.6, location=location) + + async def test_edit_location_with_all_args(self, bot, location): + with pytest.raises(ValueError, match="Not both"): + await bot.edit_message_live_location( + chat_id=1, message_id=7, latitude=2.5, longitude=4.6, location=location + ) + # TODO: Needs improvement with in inline sent live location. async def test_edit_live_inline_message(self, monkeypatch, bot, location): async def make_assertion(url, request_data: RequestData, *args, **kwargs): @@ -119,46 +159,6 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.setattr(bot.request, "post", make_assertion) assert await bot.edit_message_live_location(None, None, location=location) - async def test_send_location_without_required(self, bot, chat_id): - with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.send_location(chat_id=chat_id) - - async def test_edit_location_without_required(self, bot): - with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.edit_message_live_location(chat_id=2, message_id=3) - - async def test_send_location_with_all_args(self, bot, location): - with pytest.raises(ValueError, match="Not both"): - await bot.send_location(chat_id=1, latitude=2.5, longitude=4.6, location=location) - - async def test_edit_location_with_all_args(self, bot, location): - with pytest.raises(ValueError, match="Not both"): - await bot.edit_message_live_location( - chat_id=1, message_id=7, latitude=2.5, longitude=4.6, location=location - ) - - def test_to_dict(self, location): - location_dict = location.to_dict() - - assert location_dict["latitude"] == location.latitude - assert location_dict["longitude"] == location.longitude - assert location_dict["horizontal_accuracy"] == location.horizontal_accuracy - assert location_dict["live_period"] == location.live_period - assert location["heading"] == location.heading - assert location["proximity_alert_radius"] == location.proximity_alert_radius - - def test_equality(self): - a = Location(Space.longitude, Space.latitude) - b = Location(Space.longitude, Space.latitude) - d = Location(0, Space.latitude) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != d - assert hash(a) != hash(d) - class TestLocationReq: @pytest.mark.parametrize( diff --git a/tests/test_message.py b/tests/test_message.py index 284ead40e8e..4eb029b97c8 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -343,6 +343,11 @@ class Space: class TestMessageNoReq: + def test_slot_behaviour(self, message, mro_slots): + for attr in message.__slots__: + assert getattr(message, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(message)) == len(set(mro_slots(message))), "duplicate slot" + def test_all_possibilities_de_json_and_to_dict(self, bot, message_params): new = Message.de_json(message_params.to_dict(), bot) assert new.api_kwargs == {} @@ -354,10 +359,26 @@ def test_all_possibilities_de_json_and_to_dict(self, bot, message_params): for slot in new.__slots__: assert not isinstance(new[slot], dict) - def test_slot_behaviour(self, message, mro_slots): - for attr in message.__slots__: - assert getattr(message, attr, "err") != "err", f"got extra slot '{attr}'" - assert len(mro_slots(message)) == len(set(mro_slots(message))), "duplicate slot" + def test_equality(self): + id_ = 1 + a = Message(id_, Space.date, Space.chat, from_user=Space.from_user) + b = Message(id_, Space.date, Space.chat, from_user=Space.from_user) + c = Message(id_, Space.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) + d = Message(0, Space.date, Space.chat, from_user=Space.from_user) + e = Update(id_) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a != c + assert hash(a) != hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) async def test_parse_entity(self): text = ( @@ -1822,34 +1843,3 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(message.get_bot(), "unpin_all_forum_topic_messages", make_assertion) assert await message.unpin_all_forum_topic_messages() - - def test_equality(self): - id_ = 1 - a = Message( - id_, - Space.date, - Space.chat, - from_user=Space.from_user, - ) - b = Message( - id_, - Space.date, - Space.chat, - from_user=Space.from_user, - ) - c = Message(id_, Space.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) - d = Message(0, Space.date, Space.chat, from_user=Space.from_user) - e = Update(id_) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a != c - assert hash(a) != hash(c) - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) diff --git a/tests/test_passport.py b/tests/test_passport.py index 0d229e3aaba..d2c87c2fa61 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -389,6 +389,36 @@ def test_expected_decrypted_values(self, passport_data): assert email.type == "email" assert email.email == "fb3e3i47zt@dispostable.com" + def test_de_json_and_to_dict(self, bot): + passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot) + assert passport_data.api_kwargs == {} + assert passport_data.to_dict() == RAW_PASSPORT_DATA + + assert passport_data.decrypted_data + assert passport_data.to_dict() == RAW_PASSPORT_DATA + + def test_equality(self, passport_data): + a = PassportData(passport_data.data, passport_data.credentials) + b = PassportData(passport_data.data, passport_data.credentials) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + passport_data.credentials._unfreeze() + passport_data.credentials.hash = "NOTAPROPERHASH" + c = PassportData(passport_data.data, passport_data.credentials) + + assert a != c + assert hash(a) != hash(c) + + def test_bot_init_invalid_key(self, bot): + with pytest.raises(TypeError): + Bot(bot.token, private_key="Invalid key!") + + with pytest.raises(ValueError): + Bot(bot.token, private_key=b"Invalid key!") + def test_all_types(self, passport_data, bot, all_passport_data): credentials = passport_data.decrypted_credentials.to_dict() @@ -424,13 +454,6 @@ def test_all_types(self, passport_data, bot, all_passport_data): assert isinstance(new, PassportData) assert new.decrypted_data - def test_bot_init_invalid_key(self, bot): - with pytest.raises(TypeError): - Bot(bot.token, private_key="Invalid key!") - - with pytest.raises(ValueError): - Bot(bot.token, private_key=b"Invalid key!") - async def test_passport_data_okay_with_non_crypto_bot(self, bot): async with make_bot(token=bot.token) as b: assert PassportData.de_json(RAW_PASSPORT_DATA, bot=b) @@ -508,26 +531,3 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ], ) assert message - - def test_de_json_and_to_dict(self, bot): - passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot) - assert passport_data.api_kwargs == {} - assert passport_data.to_dict() == RAW_PASSPORT_DATA - - assert passport_data.decrypted_data - assert passport_data.to_dict() == RAW_PASSPORT_DATA - - def test_equality(self, passport_data): - a = PassportData(passport_data.data, passport_data.credentials) - b = PassportData(passport_data.data, passport_data.credentials) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - passport_data.credentials._unfreeze() - passport_data.credentials.hash = "NOTAPROPERHASH" - c = PassportData(passport_data.data, passport_data.credentials) - - assert a != c - assert hash(a) != hash(c) diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index c39a2ba7aa5..ee9a2b9ec92 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -67,21 +67,6 @@ def test_to_dict(self, passport_file): assert passport_file_dict["file_size"] == passport_file.file_size assert passport_file_dict["file_date"] == passport_file.file_date - async def test_get_file_instance_method(self, monkeypatch, passport_file): - async def make_assertion(*_, **kwargs): - result = kwargs["file_id"] == passport_file.file_id - # we need to be a bit hacky here, b/c PF.get_file needs Bot.get_file to return a File - return File(file_id=result, file_unique_id=result) - - assert check_shortcut_signature(PassportFile.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call( - passport_file.get_file, passport_file.get_bot(), "get_file" - ) - assert await check_defaults_handling(passport_file.get_file, passport_file.get_bot()) - - monkeypatch.setattr(passport_file.get_bot(), "get_file", make_assertion) - assert (await passport_file.get_file()).file_id == "True" - def test_equality(self): a = PassportFile(Space.file_id, Space.file_unique_id, Space.file_size, Space.file_date) b = PassportFile("", Space.file_unique_id, Space.file_size, Space.file_date) @@ -101,3 +86,18 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + + async def test_get_file_instance_method(self, monkeypatch, passport_file): + async def make_assertion(*_, **kwargs): + result = kwargs["file_id"] == passport_file.file_id + # we need to be a bit hacky here, b/c PF.get_file needs Bot.get_file to return a File + return File(file_id=result, file_unique_id=result) + + assert check_shortcut_signature(PassportFile.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call( + passport_file.get_file, passport_file.get_bot(), "get_file" + ) + assert await check_defaults_handling(passport_file.get_file, passport_file.get_bot()) + + monkeypatch.setattr(passport_file.get_bot(), "get_file", make_assertion) + assert (await passport_file.get_file()).file_id == "True" diff --git a/tests/test_photo.py b/tests/test_photo.py index f1efe2a5ed2..ffec72e8c1e 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -99,44 +99,6 @@ def test_expected_values(self, photo, thumb): assert thumb.height == 90 assert thumb.file_size == 1477 - async def test_send_photo_custom_filename(self, bot, chat_id, photo_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_photo(chat_id, photo_file, filename="custom_filename") - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("photo") == expected - else: - test_flag = isinstance(data.get("photo"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_photo(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - - async def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["photo"] == photo.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_photo(photo=photo, chat_id=chat_id) - assert message - def test_de_json(self, bot, photo): json_dict = { "file_id": photo.file_id, @@ -164,21 +126,6 @@ def test_to_dict(self, photo): assert photo_dict["height"] == photo.height assert photo_dict["file_size"] == photo.file_size - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_photo(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, photo): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == photo.file_id - - assert check_shortcut_signature(PhotoSize.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(photo.get_file, photo.get_bot(), "get_file") - assert await check_defaults_handling(photo.get_file, photo.get_bot()) - - monkeypatch.setattr(photo.get_bot(), "get_file", make_assertion) - assert await photo.get_file() - def test_equality(self, photo): a = PhotoSize(photo.file_id, photo.file_unique_id, Space.width, Space.height) b = PhotoSize("", photo.file_unique_id, Space.width, Space.height) @@ -207,6 +154,57 @@ def test_equality(self, photo): assert a != e assert hash(a) != hash(e) + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_photo(chat_id=chat_id) + + async def test_send_photo_custom_filename(self, bot, chat_id, photo_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_photo(chat_id, photo_file, filename="custom_filename") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("photo") == expected + else: + test_flag = isinstance(data.get("photo"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_photo(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + + async def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["photo"] == photo.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_photo(photo=photo, chat_id=chat_id) + + async def test_get_file_instance_method(self, monkeypatch, photo): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == photo.file_id + + assert check_shortcut_signature(PhotoSize.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(photo.get_file, photo.get_bot(), "get_file") + assert await check_defaults_handling(photo.get_file, photo.get_bot()) + + monkeypatch.setattr(photo.get_bot(), "get_file", make_assertion) + assert await photo.get_file() + class TestPhotoReq: async def test_send_photo_all_args(self, bot, chat_id, photo_file): diff --git a/tests/test_poll.py b/tests/test_poll.py index b27ab4327b6..9fb7b1817f1 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -222,6 +222,21 @@ def test_to_dict(self, poll): assert poll_dict["open_period"] == poll.open_period assert poll_dict["close_date"] == to_timestamp(poll.close_date) + def test_equality(self): + a = Poll(123, "question", ["O1", "O2"], 1, False, True, Poll.REGULAR, True) + b = Poll(123, "question", ["o1", "o2"], 1, True, False, Poll.REGULAR, True) + c = Poll(456, "question", ["o1", "o2"], 1, True, False, Poll.REGULAR, True) + d = PollOption("Text", 1) + + assert a == b + assert hash(a) == hash(b) + + assert a != c + assert hash(a) != hash(c) + + assert a != d + assert hash(a) != hash(d) + def test_enum_init(self): poll = Poll( type="foo", @@ -271,18 +286,3 @@ def test_parse_entities(self, poll): assert poll.parse_explanation_entities(MessageEntity.URL) == {entity: "http://google.com"} assert poll.parse_explanation_entities() == {entity: "http://google.com", entity_2: "h"} - - def test_equality(self): - a = Poll(123, "question", ["O1", "O2"], 1, False, True, Poll.REGULAR, True) - b = Poll(123, "question", ["o1", "o2"], 1, True, False, Poll.REGULAR, True) - c = Poll(456, "question", ["o1", "o2"], 1, True, False, Poll.REGULAR, True) - d = PollOption("Text", 1) - - assert a == b - assert hash(a) == hash(b) - - assert a != c - assert hash(a) != hash(c) - - assert a != d - assert hash(a) != hash(d) diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index e583b53b84d..b592d28e36f 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -93,27 +93,6 @@ def test_to_dict(self, pre_checkout_query): 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() - async def test_answer(self, monkeypatch, pre_checkout_query): - async def make_assertion(*_, **kwargs): - return kwargs["pre_checkout_query_id"] == pre_checkout_query.id - - assert check_shortcut_signature( - PreCheckoutQuery.answer, Bot.answer_pre_checkout_query, ["pre_checkout_query_id"], [] - ) - assert await check_shortcut_call( - pre_checkout_query.answer, - pre_checkout_query.get_bot(), - "answer_pre_checkout_query", - ) - assert await check_defaults_handling( - pre_checkout_query.answer, pre_checkout_query.get_bot() - ) - - monkeypatch.setattr( - pre_checkout_query.get_bot(), "answer_pre_checkout_query", make_assertion - ) - assert await pre_checkout_query.answer(ok=True) - def test_equality(self): a = PreCheckoutQuery( Space.id_, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload @@ -139,3 +118,24 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + + async def test_answer(self, monkeypatch, pre_checkout_query): + async def make_assertion(*_, **kwargs): + return kwargs["pre_checkout_query_id"] == pre_checkout_query.id + + assert check_shortcut_signature( + PreCheckoutQuery.answer, Bot.answer_pre_checkout_query, ["pre_checkout_query_id"], [] + ) + assert await check_shortcut_call( + pre_checkout_query.answer, + pre_checkout_query.get_bot(), + "answer_pre_checkout_query", + ) + assert await check_defaults_handling( + pre_checkout_query.answer, pre_checkout_query.get_bot() + ) + + monkeypatch.setattr( + pre_checkout_query.get_bot(), "answer_pre_checkout_query", make_assertion + ) + assert await pre_checkout_query.answer(ok=True) diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 004272c12fa..8028798e9c8 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -46,41 +46,6 @@ def test_slot_behaviour(self, reply_keyboard_markup, mro_slots): assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - def test_from_button(self): - reply_keyboard_markup = ReplyKeyboardMarkup.from_button( - KeyboardButton(text="button1") - ).keyboard - assert len(reply_keyboard_markup) == 1 - assert len(reply_keyboard_markup[0]) == 1 - - reply_keyboard_markup = ReplyKeyboardMarkup.from_button("button1").keyboard - assert len(reply_keyboard_markup) == 1 - assert len(reply_keyboard_markup[0]) == 1 - - def test_from_row(self): - reply_keyboard_markup = ReplyKeyboardMarkup.from_row( - [KeyboardButton(text="button1"), KeyboardButton(text="button2")] - ).keyboard - assert len(reply_keyboard_markup) == 1 - assert len(reply_keyboard_markup[0]) == 2 - - reply_keyboard_markup = ReplyKeyboardMarkup.from_row(["button1", "button2"]).keyboard - assert len(reply_keyboard_markup) == 1 - assert len(reply_keyboard_markup[0]) == 2 - - def test_from_column(self): - reply_keyboard_markup = ReplyKeyboardMarkup.from_column( - [KeyboardButton(text="button1"), KeyboardButton(text="button2")] - ).keyboard - assert len(reply_keyboard_markup) == 2 - assert len(reply_keyboard_markup[0]) == 1 - assert len(reply_keyboard_markup[1]) == 1 - - reply_keyboard_markup = ReplyKeyboardMarkup.from_column(["button1", "button2"]).keyboard - assert len(reply_keyboard_markup) == 2 - assert len(reply_keyboard_markup[0]) == 1 - assert len(reply_keyboard_markup[1]) == 1 - def test_expected_values(self, reply_keyboard_markup): assert isinstance(reply_keyboard_markup.keyboard, tuple) assert all(isinstance(row, tuple) for row in reply_keyboard_markup.keyboard) @@ -90,16 +55,6 @@ def test_expected_values(self, reply_keyboard_markup): assert reply_keyboard_markup.one_time_keyboard == Space.one_time_keyboard assert reply_keyboard_markup.selective == Space.selective - def test_wrong_keyboard_inputs(self): - with pytest.raises(ValueError): - ReplyKeyboardMarkup([["button1"], 1]) - with pytest.raises(ValueError): - ReplyKeyboardMarkup("strings_are_not_allowed") - with pytest.raises(ValueError): - ReplyKeyboardMarkup(["strings_are_not_allowed_in_the_rows_either"]) - with pytest.raises(ValueError): - ReplyKeyboardMarkup(KeyboardButton("button1")) - def test_to_dict(self, reply_keyboard_markup): reply_keyboard_markup_dict = reply_keyboard_markup.to_dict() @@ -146,6 +101,51 @@ def test_equality(self): assert a != f assert hash(a) != hash(f) + def test_wrong_keyboard_inputs(self): + with pytest.raises(ValueError): + ReplyKeyboardMarkup([["button1"], 1]) + with pytest.raises(ValueError): + ReplyKeyboardMarkup("strings_are_not_allowed") + with pytest.raises(ValueError): + ReplyKeyboardMarkup(["strings_are_not_allowed_in_the_rows_either"]) + with pytest.raises(ValueError): + ReplyKeyboardMarkup(KeyboardButton("button1")) + + def test_from_button(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_button( + KeyboardButton(text="button1") + ).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 1 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_button("button1").keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 1 + + def test_from_row(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_row( + [KeyboardButton(text="button1"), KeyboardButton(text="button2")] + ).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 2 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_row(["button1", "button2"]).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 2 + + def test_from_column(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_column( + [KeyboardButton(text="button1"), KeyboardButton(text="button2")] + ).keyboard + assert len(reply_keyboard_markup) == 2 + assert len(reply_keyboard_markup[0]) == 1 + assert len(reply_keyboard_markup[1]) == 1 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_column(["button1", "button2"]).keyboard + assert len(reply_keyboard_markup) == 2 + assert len(reply_keyboard_markup[0]) == 1 + assert len(reply_keyboard_markup[1]) == 1 + class TestReplyKeyboardMarkupReq: async def test_send_message_with_reply_keyboard_markup( diff --git a/tests/test_requestparameter.py b/tests/test_requestparameter.py index 49f333a0261..a04c6861d5d 100644 --- a/tests/test_requestparameter.py +++ b/tests/test_requestparameter.py @@ -27,6 +27,12 @@ class TestRequestParameterNoReq: + def test_slot_behaviour(self, mro_slots): + inst = RequestParameter("name", "value", [1, 2]) + for attr in inst.__slots__: + assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + def test_init(self): request_parameter = RequestParameter("name", "value", [1, 2]) assert request_parameter.name == "name" @@ -38,12 +44,6 @@ def test_init(self): assert request_parameter.value == "value" assert request_parameter.input_files is None - def test_slot_behaviour(self, mro_slots): - inst = RequestParameter("name", "value", [1, 2]) - for attr in inst.__slots__: - assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" - assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" - @pytest.mark.parametrize( "value, expected", [ diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index 8f988351af4..b2f4b946170 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -73,21 +73,6 @@ def test_to_dict(self, shipping_query): assert shipping_query_dict["from"] == shipping_query.from_user.to_dict() assert shipping_query_dict["shipping_address"] == shipping_query.shipping_address.to_dict() - async def test_answer(self, monkeypatch, shipping_query): - async def make_assertion(*_, **kwargs): - return kwargs["shipping_query_id"] == shipping_query.id - - assert check_shortcut_signature( - ShippingQuery.answer, Bot.answer_shipping_query, ["shipping_query_id"], [] - ) - assert await check_shortcut_call( - shipping_query.answer, shipping_query._bot, "answer_shipping_query" - ) - assert await check_defaults_handling(shipping_query.answer, shipping_query._bot) - - monkeypatch.setattr(shipping_query._bot, "answer_shipping_query", make_assertion) - assert await shipping_query.answer(ok=True) - def test_equality(self): a = ShippingQuery( Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address @@ -111,3 +96,18 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) + + async def test_answer(self, monkeypatch, shipping_query): + async def make_assertion(*_, **kwargs): + return kwargs["shipping_query_id"] == shipping_query.id + + assert check_shortcut_signature( + ShippingQuery.answer, Bot.answer_shipping_query, ["shipping_query_id"], [] + ) + assert await check_shortcut_call( + shipping_query.answer, shipping_query._bot, "answer_shipping_query" + ) + assert await check_defaults_handling(shipping_query.answer, shipping_query._bot) + + monkeypatch.setattr(shipping_query._bot, "answer_shipping_query", make_assertion) + assert await shipping_query.answer(ok=True) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index af653119fe6..d28fb55642c 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -127,6 +127,20 @@ def test_expected_values(self, sticker): # we need to be a premium TG user to send a premium sticker, so the below is not tested # assert sticker.premium_animation == StickerSpace.premium_animation + 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["file_unique_id"] == sticker.file_unique_id + assert sticker_dict["width"] == sticker.width + assert sticker_dict["height"] == sticker.height + assert sticker_dict["is_animated"] == sticker.is_animated + assert sticker_dict["is_video"] == sticker.is_video + assert sticker_dict["file_size"] == sticker.file_size + assert sticker_dict["thumb"] == sticker.thumb.to_dict() + assert sticker_dict["type"] == sticker.type + def test_de_json(self, bot, sticker): json_dict = { "file_id": StickerSpace.sticker_file_id, @@ -158,54 +172,6 @@ def test_de_json(self, bot, sticker): assert json_sticker.type == StickerSpace.type assert json_sticker.custom_emoji_id == StickerSpace.custom_emoji_id - async def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["sticker"] == sticker.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_sticker(sticker=sticker, chat_id=chat_id) - assert message - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_sticker_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("sticker") == expected - else: - test_flag = isinstance(data.get("sticker"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_sticker(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - - 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["file_unique_id"] == sticker.file_unique_id - assert sticker_dict["width"] == sticker.width - assert sticker_dict["height"] == sticker.height - assert sticker_dict["is_animated"] == sticker.is_animated - assert sticker_dict["is_video"] == sticker.is_video - assert sticker_dict["file_size"] == sticker.file_size - assert sticker_dict["thumb"] == sticker.thumb.to_dict() - assert sticker_dict["type"] == sticker.type - - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_sticker(chat_id) - def test_equality(self, sticker): a = Sticker( sticker.file_id, @@ -264,6 +230,39 @@ def test_equality(self, sticker): assert a != e assert hash(a) != hash(e) + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_sticker(chat_id) + + async def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["sticker"] == sticker.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_sticker(sticker=sticker, chat_id=chat_id) + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_sticker_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("sticker") == expected + else: + test_flag = isinstance(data.get("sticker"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_sticker(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + class TestStickerReq: async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): @@ -537,6 +536,47 @@ def test_sticker_set_to_dict(self, sticker_set): assert sticker_set_dict["thumb"] == sticker_set.thumb.to_dict() assert sticker_set_dict["sticker_type"] == sticker_set.sticker_type + def test_equality(self): + a = StickerSet( + SetSpace.name, + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, + ) + b = StickerSet( + SetSpace.name, + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, + ) + c = StickerSet(SetSpace.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) + d = StickerSet( + "blah", + SetSpace.title, + SetSpace.is_animated, + SetSpace.stickers, + SetSpace.is_video, + SetSpace.sticker_type, + ) + e = Audio(SetSpace.name, "", 0, None, None) + + 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) + @pytest.mark.parametrize("local_mode", [True, False]) async def test_upload_sticker_file_local_files(self, monkeypatch, bot, chat_id, local_mode): try: @@ -683,47 +723,6 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(sticker.get_bot(), "get_file", make_assertion) assert await sticker.get_file() - def test_equality(self): - a = StickerSet( - SetSpace.name, - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, - ) - b = StickerSet( - SetSpace.name, - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, - ) - c = StickerSet(SetSpace.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) - d = StickerSet( - "blah", - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, - ) - e = Audio(SetSpace.name, "", 0, None, None) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a == c - assert hash(a) == hash(c) - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) - class TestStickerSetReq: async def test_create_sticker_set( diff --git a/tests/test_update.py b/tests/test_update.py index 08e1dbbcf14..954b18f126a 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -144,6 +144,26 @@ def test_to_dict(self, update): if getattr(update, _type) is not None: assert update_dict[_type] == getattr(update, _type).to_dict() + def test_equality(self): + a = Update(Space.update_id, message=message) + b = Update(Space.update_id, message=message) + c = Update(Space.update_id) + d = Update(0, message=message) + e = User(Space.update_id, "", False) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + def test_effective_chat(self, update): # Test that it's sometimes None per docstring chat = update.effective_chat @@ -190,23 +210,3 @@ def test_effective_message(self, update): assert eff_message.message_id == message.message_id else: assert eff_message is None - - def test_equality(self): - a = Update(Space.update_id, message=message) - b = Update(Space.update_id, message=message) - c = Update(Space.update_id) - d = Update(0, message=message) - e = User(Space.update_id, "", False) - - 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_user.py b/tests/test_user.py index 6feff8abed0..bc6c4713ddc 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -137,6 +137,26 @@ def test_de_json_without_username_and_last_name(self, json_dict, bot): assert user.is_premium == Space.is_premium assert user.added_to_attachment_menu == Space.added_to_attachment_menu + def test_equality(self): + a = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) + b = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) + c = User(Space.id_, Space.first_name, Space.is_bot) + d = User(0, Space.first_name, Space.is_bot, Space.last_name) + e = Update(Space.id_) + + assert a == b + assert hash(a) == hash(b) + assert a is not b + + assert a == c + assert hash(a) == hash(c) + + assert a != d + assert hash(a) != hash(d) + + assert a != e + assert hash(a) != hash(e) + def test_name(self, user): assert user.name == "@username" user.username = None @@ -562,23 +582,3 @@ async def test_mention_markdown_v2(self, user): "the\\{name\\>\u2022", user.id ) assert user.mention_markdown_v2(user.username) == expected.format(user.username, user.id) - - def test_equality(self): - a = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) - b = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) - c = User(Space.id_, Space.first_name, Space.is_bot) - d = User(0, Space.first_name, Space.is_bot, Space.last_name) - e = Update(Space.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_venue.py b/tests/test_venue.py index 48706e8f4b7..f6590c65020 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -75,39 +75,6 @@ def test_de_json(self, bot): assert venue.google_place_id == Space.google_place_id assert venue.google_place_type == Space.google_place_type - async def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - data = request_data.json_parameters - return ( - data["longitude"] == str(Space.location.longitude) - and data["latitude"] == str(Space.location.latitude) - and data["title"] == Space.title - and data["address"] == Space.address - and data["foursquare_id"] == Space.foursquare_id - and data["foursquare_type"] == Space.foursquare_type - and data["google_place_id"] == Space.google_place_id - and data["google_place_type"] == Space.google_place_type - ) - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_venue(chat_id, venue=venue) - assert message - - async def test_send_venue_without_required(self, bot, chat_id): - with pytest.raises(ValueError, match="Either venue or latitude, longitude, address and"): - await bot.send_venue(chat_id=chat_id) - - async def test_send_venue_mutually_exclusive(self, bot, chat_id, venue): - with pytest.raises(ValueError, match="Not both"): - await bot.send_venue( - chat_id=chat_id, - latitude=1, - longitude=1, - address="address", - title="title", - venue=venue, - ) - def test_to_dict(self, venue): venue_dict = venue.to_dict() @@ -140,6 +107,39 @@ def test_equality(self): assert a != d2 assert hash(a) != hash(d2) + async def test_send_venue_without_required(self, bot, chat_id): + with pytest.raises(ValueError, match="Either venue or latitude, longitude, address and"): + await bot.send_venue(chat_id=chat_id) + + async def test_send_venue_mutually_exclusive(self, bot, chat_id, venue): + with pytest.raises(ValueError, match="Not both"): + await bot.send_venue( + chat_id=chat_id, + latitude=1, + longitude=1, + address="address", + title="title", + venue=venue, + ) + + async def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + data = request_data.json_parameters + return ( + data["longitude"] == str(Space.location.longitude) + and data["latitude"] == str(Space.location.latitude) + and data["title"] == Space.title + and data["address"] == Space.address + and data["foursquare_id"] == Space.foursquare_id + and data["foursquare_type"] == Space.foursquare_type + and data["google_place_id"] == Space.google_place_id + and data["google_place_type"] == Space.google_place_type + ) + + monkeypatch.setattr(bot.request, "post", make_assertion) + message = await bot.send_venue(chat_id, venue=venue) + assert message + class TestVenueReq: @pytest.mark.parametrize( diff --git a/tests/test_video.py b/tests/test_video.py index a060a2d40f2..8613ba8e6b0 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -90,46 +90,6 @@ def test_expected_values(self, video): assert video.file_size == Space.file_size assert video.mime_type == Space.mime_type - async def test_send_video_custom_filename(self, bot, chat_id, video_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_video(chat_id, video_file, filename="custom_filename") - - async def test_send_with_video(self, monkeypatch, bot, chat_id, video): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["video"] == video.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_video(chat_id, video=video) - assert message - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_video_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("video") == expected and data.get("thumb") == expected - else: - test_flag = isinstance(data.get("video"), InputFile) and isinstance( - data.get("thumb"), InputFile - ) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_video(chat_id, file, thumb=file) - assert test_flag - finally: - bot._local_mode = False - def test_de_json(self, bot): json_dict = { "file_id": Space.video_file_id, @@ -166,21 +126,6 @@ def test_to_dict(self, video): assert video_dict["file_size"] == video.file_size assert video_dict["file_name"] == video.file_name - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_video(chat_id=chat_id) - - async def test_get_file_instance_method(self, monkeypatch, video): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == video.file_id - - assert check_shortcut_signature(Video.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(video.get_file, video.get_bot(), "get_file") - assert await check_defaults_handling(video.get_file, video.get_bot()) - - monkeypatch.setattr(video.get_bot(), "get_file", make_assertion) - assert await video.get_file() - def test_equality(self, video): a = Video(video.file_id, video.file_unique_id, Space.width, Space.height, Space.duration) b = Video("", video.file_unique_id, Space.width, Space.height, Space.duration) @@ -201,6 +146,60 @@ def test_equality(self, video): assert a != e assert hash(a) != hash(e) + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_video(chat_id=chat_id) + + async def test_send_with_video(self, monkeypatch, bot, chat_id, video): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["video"] == video.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_video(chat_id, video=video) + + async def test_send_video_custom_filename(self, bot, chat_id, video_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_video(chat_id, video_file, filename="custom_filename") + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_video_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("video") == expected and data.get("thumb") == expected + else: + test_flag = isinstance(data.get("video"), InputFile) and isinstance( + data.get("thumb"), InputFile + ) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_video(chat_id, file, thumb=file) + assert test_flag + finally: + bot._local_mode = False + + async def test_get_file_instance_method(self, monkeypatch, video): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == video.file_id + + assert check_shortcut_signature(Video.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(video.get_file, video.get_bot(), "get_file") + assert await check_defaults_handling(video.get_file, video.get_bot()) + + monkeypatch.setattr(video.get_bot(), "get_file", make_assertion) + assert await video.get_file() + class TestVideoReq: async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): diff --git a/tests/test_videonote.py b/tests/test_videonote.py index c88e27c391c..c6029d3c55c 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -82,24 +82,6 @@ def test_expected_values(self, video_note): assert video_note.duration == Space.duration assert video_note.file_size == Space.file_size - async def test_send_video_note_custom_filename( - self, bot, chat_id, video_note_file, monkeypatch - ): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_video_note(chat_id, video_note_file, filename="custom_filename") - - async def test_send_with_video_note(self, monkeypatch, bot, chat_id, video_note): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["video_note"] == video_note.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_video_note(chat_id, video_note=video_note) - assert message - def test_de_json(self, bot): json_dict = { "file_id": Space.videonote_file_id, @@ -127,6 +109,47 @@ def test_to_dict(self, video_note): assert video_note_dict["duration"] == video_note.duration assert video_note_dict["file_size"] == video_note.file_size + def test_equality(self, video_note): + a = VideoNote(video_note.file_id, video_note.file_unique_id, Space.length, Space.duration) + b = VideoNote("", video_note.file_unique_id, Space.length, Space.duration) + c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0) + d = VideoNote("", "", Space.length, Space.duration) + e = Voice(video_note.file_id, video_note.file_unique_id, Space.duration) + + 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) + + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.send_video_note(chat_id=chat_id) + + async def test_send_with_video_note(self, monkeypatch, bot, chat_id, video_note): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["video_note"] == video_note.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_video_note(chat_id, video_note=video_note) + + async def test_send_video_note_custom_filename( + self, bot, chat_id, video_note_file, monkeypatch + ): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_video_note(chat_id, video_note_file, filename="custom_filename") + @pytest.mark.parametrize("local_mode", [True, False]) async def test_send_video_note_local_files(self, monkeypatch, bot, chat_id, local_mode): try: @@ -153,10 +176,6 @@ async def make_assertion(_, data, *args, **kwargs): finally: bot._local_mode = False - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.send_video_note(chat_id=chat_id) - async def test_get_file_instance_method(self, monkeypatch, video_note): async def make_assertion(*_, **kwargs): return kwargs["file_id"] == video_note.file_id @@ -168,26 +187,6 @@ async def make_assertion(*_, **kwargs): monkeypatch.setattr(video_note.get_bot(), "get_file", make_assertion) assert await video_note.get_file() - def test_equality(self, video_note): - a = VideoNote(video_note.file_id, video_note.file_unique_id, Space.length, Space.duration) - b = VideoNote("", video_note.file_unique_id, Space.length, Space.duration) - c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0) - d = VideoNote("", "", Space.length, Space.duration) - e = Voice(video_note.file_id, video_note.file_unique_id, Space.duration) - - assert a == b - assert hash(a) == hash(b) - assert a is not b - - assert a == c - assert hash(a) == hash(c) - - assert a != d - assert hash(a) != hash(d) - - assert a != e - assert hash(a) != hash(e) - class TestVideoNoteReq: async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): diff --git a/tests/test_voice.py b/tests/test_voice.py index 4c5e7c2c92f..0d7b08b9ec1 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -75,44 +75,6 @@ def test_expected_values(self, voice): assert voice.mime_type == Space.mime_type assert voice.file_size == Space.file_size - async def test_send_voice_custom_filename(self, bot, chat_id, voice_file, monkeypatch): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return list(request_data.multipart_data.values())[0][0] == "custom_filename" - - monkeypatch.setattr(bot.request, "post", make_assertion) - - assert await bot.send_voice(chat_id, voice_file, filename="custom_filename") - - async def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): - async def make_assertion(url, request_data: RequestData, *args, **kwargs): - return request_data.json_parameters["voice"] == voice.file_id - - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_voice(chat_id, voice=voice) - assert message - - @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_voice_local_files(self, monkeypatch, bot, chat_id, local_mode): - try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False - file = data_file("telegram.jpg") - expected = file.as_uri() - - async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag - if local_mode: - test_flag = data.get("voice") == expected - else: - test_flag = isinstance(data.get("voice"), InputFile) - - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_voice(chat_id, file) - assert test_flag - finally: - bot._local_mode = False - def test_de_json(self, bot): json_dict = { "file_id": Space.voice_file_id, @@ -140,21 +102,6 @@ def test_to_dict(self, voice): assert voice_dict["mime_type"] == voice.mime_type assert voice_dict["file_size"] == voice.file_size - async def test_error_without_required_args(self, bot, chat_id): - with pytest.raises(TypeError): - await bot.sendVoice(chat_id) - - async def test_get_file_instance_method(self, monkeypatch, voice): - async def make_assertion(*_, **kwargs): - return kwargs["file_id"] == voice.file_id - - assert check_shortcut_signature(Voice.get_file, Bot.get_file, ["file_id"], []) - assert await check_shortcut_call(voice.get_file, voice.get_bot(), "get_file") - assert await check_defaults_handling(voice.get_file, voice.get_bot()) - - monkeypatch.setattr(voice.get_bot(), "get_file", make_assertion) - assert await voice.get_file() - def test_equality(self, voice): a = Voice(voice.file_id, voice.file_unique_id, Space.duration) b = Voice("", voice.file_unique_id, Space.duration) @@ -175,6 +122,58 @@ def test_equality(self, voice): assert a != e assert hash(a) != hash(e) + async def test_error_without_required_args(self, bot, chat_id): + with pytest.raises(TypeError): + await bot.sendVoice(chat_id) + + async def test_send_voice_custom_filename(self, bot, chat_id, voice_file, monkeypatch): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return list(request_data.multipart_data.values())[0][0] == "custom_filename" + + monkeypatch.setattr(bot.request, "post", make_assertion) + + assert await bot.send_voice(chat_id, voice_file, filename="custom_filename") + + async def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): + async def make_assertion(url, request_data: RequestData, *args, **kwargs): + return request_data.json_parameters["voice"] == voice.file_id + + monkeypatch.setattr(bot.request, "post", make_assertion) + assert await bot.send_voice(chat_id, voice=voice) + + @pytest.mark.parametrize("local_mode", [True, False]) + async def test_send_voice_local_files(self, monkeypatch, bot, chat_id, local_mode): + try: + bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local bot API set up + test_flag = False + file = data_file("telegram.jpg") + expected = file.as_uri() + + async def make_assertion(_, data, *args, **kwargs): + nonlocal test_flag + if local_mode: + test_flag = data.get("voice") == expected + else: + test_flag = isinstance(data.get("voice"), InputFile) + + monkeypatch.setattr(bot, "_post", make_assertion) + await bot.send_voice(chat_id, file) + assert test_flag + finally: + bot._local_mode = False + + async def test_get_file_instance_method(self, monkeypatch, voice): + async def make_assertion(*_, **kwargs): + return kwargs["file_id"] == voice.file_id + + assert check_shortcut_signature(Voice.get_file, Bot.get_file, ["file_id"], []) + assert await check_shortcut_call(voice.get_file, voice.get_bot(), "get_file") + assert await check_defaults_handling(voice.get_file, voice.get_bot()) + + monkeypatch.setattr(voice.get_bot(), "get_file", make_assertion) + assert await voice.get_file() + class TestVoiceReq: async def test_send_all_args(self, bot, chat_id, voice_file, voice): From 664c10397a0ee30d37c47bb5a911c5fe4857c66f Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 16 Dec 2022 02:09:29 +0530 Subject: [PATCH 23/77] Adding two missing slot_behaviour tests in test_sticker.py Also add a missing test_to_dict in user.py --- tests/test_sticker.py | 12 ++++++++++++ tests/test_user.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index d28fb55642c..a8954cfe7f3 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -501,6 +501,12 @@ class SetSpace: class TestStickerSetNoReq: + def test_slot_behaviour(self, mro_slots): + inst = StickerSet("this", "is", True, SetSpace.stickers, True, "not") + for attr in inst.__slots__: + assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + def test_de_json(self, bot, sticker): name = f"test_by_{bot.username}" json_dict = { @@ -864,6 +870,12 @@ class MaskSpace: class TestMaskPositionNoReq: + def test_slot_behaviour(self, mask_position, mro_slots): + inst = mask_position + for attr in inst.__slots__: + assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + def test_mask_position_de_json(self, bot): json_dict = { "point": MaskSpace.point, diff --git a/tests/test_user.py b/tests/test_user.py index bc6c4713ddc..c49b3269497 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -137,6 +137,22 @@ def test_de_json_without_username_and_last_name(self, json_dict, bot): assert user.is_premium == Space.is_premium assert user.added_to_attachment_menu == Space.added_to_attachment_menu + def test_to_dict(self, user): + user_dict = user.to_dict() + + assert isinstance(user_dict, dict) + assert user_dict["id"] == user.id + assert user_dict["is_bot"] == user.is_bot + assert user_dict["first_name"] == user.first_name + assert user_dict["last_name"] == user.last_name + assert user_dict["username"] == user.username + assert user_dict["language_code"] == user.language_code + assert user_dict["can_join_groups"] == user.can_join_groups + assert user_dict["can_read_all_group_messages"] == user.can_read_all_group_messages + assert user_dict["supports_inline_queries"] == user.supports_inline_queries + assert user_dict["is_premium"] == user.is_premium + assert user_dict["added_to_attachment_menu"] == user.added_to_attachment_menu + def test_equality(self): a = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) b = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) From b2e292ea6bd24e57d7cdd92dc169843868871411 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 16 Dec 2022 02:19:46 +0530 Subject: [PATCH 24/77] small refactor: use a for loop, fixture, and add another assert --- tests/test_bot.py | 29 ++++++++---------------- tests/test_inputinvoicemessagecontent.py | 24 +------------------- 2 files changed, 10 insertions(+), 43 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index f437040ef6f..76d0b53ab4e 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -397,33 +397,21 @@ def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): @bot_methods() def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): """Check that all bot methods are defined as async def ...""" - meth = getattr(bot_method, "__wrapped__", bot_method) + meth = getattr(bot_method, "__wrapped__", bot_method) # to unwrap the @_log decorator assert inspect.iscoroutinefunction(meth), f"{bot_method_name} must be a coroutine function" @bot_methods() def test_api_kwargs_and_timeouts_present(self, bot_class, bot_method_name, bot_method): """Check that all bot methods have `api_kwargs` and timeout params.""" param_names = inspect.signature(bot_method).parameters.keys() - assert ( - "pool_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `pool_timeout`" - assert ( - "read_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `read_timeout`" - assert ( - "connect_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `connect_timeout`" - assert ( - "write_timeout" in param_names - ), f"{bot_method_name} is missing the parameter `write_timeout`" - assert ( - "api_kwargs" in param_names - ), f"{bot_method_name} is missing the parameter `api_kwargs`" + params = ("pool_timeout", "read_timeout", "connect_timeout", "write_timeout", "api_kwargs") - if bot_class is ExtBot and bot_method_name.replace("_", "").lower() != "getupdates": - assert ( - "rate_limit_args" in param_names - ), f"{bot_method_name} of ExtBot is missing the parameter `rate_limit_args`" + for param in params: + assert param in param_names, f"{bot_method_name} is missing the parameter `{param}`" + + rate_arg = "rate_limit_args" + if bot_method_name.replace("_", "").lower() != "getupdates" and bot_class is ExtBot: + assert rate_arg in param_names, f"{bot_method} is missing the parameter `{rate_arg}`" @bot_methods(ext_bot=False) async def test_defaults_handling( @@ -2105,6 +2093,7 @@ async def test_get_user_profile_photos(self, bot, chat_id): async def test_get_one_user_profile_photo(self, bot, chat_id): user_profile_photos = await bot.get_user_profile_photos(chat_id, offset=0, limit=1) + assert user_profile_photos.total_count == 1 assert user_profile_photos.photos[0][0].file_size == 5403 async def test_edit_message_text(self, bot, message): diff --git a/tests/test_inputinvoicemessagecontent.py b/tests/test_inputinvoicemessagecontent.py index 3672be28806..88c9eaaea65 100644 --- a/tests/test_inputinvoicemessagecontent.py +++ b/tests/test_inputinvoicemessagecontent.py @@ -105,29 +105,7 @@ def test_expected_values(self, input_invoice_message_content): assert input_invoice_message_content.send_email_to_provider == Space.send_email_to_provider assert input_invoice_message_content.is_flexible == Space.is_flexible - def test_suggested_tip_amonuts_always_tuple(self): - input_invoice_message_content = InputInvoiceMessageContent( - title=Space.title, - description=Space.description, - payload=Space.payload, - provider_token=Space.provider_token, - currency=Space.currency, - prices=Space.prices, - max_tip_amount=Space.max_tip_amount, - suggested_tip_amounts=Space.suggested_tip_amounts, - provider_data=Space.provider_data, - photo_url=Space.photo_url, - photo_size=Space.photo_size, - photo_width=Space.photo_width, - photo_height=Space.photo_height, - need_name=Space.need_name, - need_phone_number=Space.need_phone_number, - need_email=Space.need_email, - need_shipping_address=Space.need_shipping_address, - send_phone_number_to_provider=Space.send_phone_number_to_provider, - send_email_to_provider=Space.send_email_to_provider, - is_flexible=Space.is_flexible, - ) + def test_suggested_tip_amonuts_always_tuple(self, input_invoice_message_content): assert isinstance(input_invoice_message_content.suggested_tip_amounts, tuple) assert input_invoice_message_content.suggested_tip_amounts == tuple( int(amount) for amount in Space.suggested_tip_amounts From cc1e45e28115cc8560620a0ec5344477f2a44449 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 16 Dec 2022 03:12:26 +0530 Subject: [PATCH 25/77] delete TestUserNoReq::test_de_json_without_username deleted because they don't really serve any purpose --- tests/test_user.py | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/tests/test_user.py b/tests/test_user.py index c49b3269497..b88e536544c 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -27,7 +27,7 @@ ) -@pytest.fixture(scope="function") +@pytest.fixture(scope="module") def json_dict(): return { "id": Space.id_, @@ -100,43 +100,6 @@ def test_de_json(self, json_dict, bot): assert user.is_premium == Space.is_premium assert user.added_to_attachment_menu == Space.added_to_attachment_menu - def test_de_json_without_username(self, json_dict, bot): - del json_dict["username"] - - user = User.de_json(json_dict, bot) - assert user.api_kwargs == {} - - assert user.id == Space.id_ - assert user.is_bot == Space.is_bot - assert user.first_name == Space.first_name - assert user.last_name == Space.last_name - assert user.username is None - assert user.language_code == Space.language_code - assert user.can_join_groups == Space.can_join_groups - assert user.can_read_all_group_messages == Space.can_read_all_group_messages - assert user.supports_inline_queries == Space.supports_inline_queries - assert user.is_premium == Space.is_premium - assert user.added_to_attachment_menu == Space.added_to_attachment_menu - - def test_de_json_without_username_and_last_name(self, json_dict, bot): - del json_dict["username"] - del json_dict["last_name"] - - user = User.de_json(json_dict, bot) - assert user.api_kwargs == {} - - assert user.id == Space.id_ - assert user.is_bot == Space.is_bot - assert user.first_name == Space.first_name - assert user.last_name is None - assert user.username is None - assert user.language_code == Space.language_code - assert user.can_join_groups == Space.can_join_groups - assert user.can_read_all_group_messages == Space.can_read_all_group_messages - assert user.supports_inline_queries == Space.supports_inline_queries - assert user.is_premium == Space.is_premium - assert user.added_to_attachment_menu == Space.added_to_attachment_menu - def test_to_dict(self, user): user_dict = user.to_dict() From 6ea3515eb13bf4d01e63cd5a094bee7463b73177 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 16 Dec 2022 04:25:59 +0530 Subject: [PATCH 26/77] Add a README for tests and add some comments to requirements-dev.txt --- requirements-dev.txt | 7 +++--- tests/README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 tests/README.md diff --git a/requirements-dev.txt b/requirements-dev.txt index b06bf6bc29d..558dbc931e8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,9 +1,10 @@ -pre-commit +pre-commit # needed for pre-commit hooks in the git commit command +# For the test suite pytest==7.2.0 -pytest-asyncio==0.20.3 +pytest-asyncio==0.20.3 # needed for async tests pytest-xdist==3.1.0 # xdist runs tests in parallel - flaky # Used for flaky tests (flaky decorator) beautifulsoup4 # used in test_official for parsing tg docs + wheel # required for building the wheels for releases diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000000..8c696b249f7 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,51 @@ +## Testing in PTB + +PTB uses [pytest](https://docs.pytest.org/en/latest/) for testing. To run the tests, you need to +have pytest installed along with a few other dependencies. You can find the list of dependencies +in the `requirements-dev.txt` file in the root of the repository. + +### Running tests + +To run the entire test suite, you can use the following command: + + $ pytest + +This will run all the tests, including the ones which make a request to the Telegram servers, which +may take a long time (about > 13 mins). To run only the tests that don't require a connection, you +can run the following command: + + $ pytest -m no_req + +To further speed up the tests, you can run them in parallel using the `-n` flag: + + $ pytest -n auto + +This will result in a significant speedup, but may cause some tests to fail. If you want to run +the failed tests in isolation, you can use the `--lf` flag: + + $ pytest --lf + + +### Writing tests + +PTB has a separate test file for every file in the `telegram.*` namespace. Further, the tests for +the `telegram` module are split into two classes, based on whether the test methods in them make a +request or not. When writing tests, make sure to split them into these two classes, and make sure +to name the test class as: `TestXXXNoReq` for tests that don't make a request, and `TestXXXReq` for +tests that do. + +Writing tests is a creative process, where you can design your test however you'd like, but there +are a few conventions that you should follow: + +- Each new test class needs a `test_slot_behaviour`, `test_to_dict`, `test_de_json` and + `test_equality` (in most cases). + +- Make use of pytest's fixtures and parametrize wherever possible. Having knowledge of pytest's + tooling can help you as well. You can look at the existing tests for examples. + +We also have another marker, `@pytest.mark.dev`, which is used to mark tests that you want to run selectively. +Use as follows: + + $ pytest -m dev + +That's it! If you have any questions, feel free to ask them in the [PTB dev group](https://t.me/pythontelegrambotdev). \ No newline at end of file From 4b55ee567ae31bef0f7a0a200daf50351829c8bf Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 17 Dec 2022 00:19:11 +0530 Subject: [PATCH 27/77] hopefully fix tests on GH CI The tests were failing because of 1) Change of fixture to a broader scope, 2) some tests (in)directly modifying state of the fixture, 3) unfortunate execution order of tests which triggered the bug when tests are run with 2 workers --- tests/test_audio.py | 3 ++- tests/test_bot.py | 13 +++---------- tests/test_document.py | 3 ++- tests/test_sticker.py | 14 +++++++++++++- tests/test_video.py | 3 ++- tests/test_videonote.py | 3 ++- tests/test_voice.py | 3 ++- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tests/test_audio.py b/tests/test_audio.py index a1f69de6aa6..e3e08fb1012 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -227,11 +227,12 @@ async def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): assert message.audio.thumb.height == Space.thumb_height assert message.has_protected_content - async def test_get_and_download(self, bot, audio): + async def test_get_and_download(self, bot, chat_id, audio): path = Path("telegram.mp3") if path.is_file(): path.unlink() + audio = (await bot.send_audio(chat_id, audio.file_id, read_timeout=50)).audio new_file = await bot.get_file(audio.file_id) assert new_file.file_size == Space.file_size diff --git a/tests/test_bot.py b/tests/test_bot.py index 76d0b53ab4e..c22df861ec9 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -94,17 +94,10 @@ def to_camel_case(snake_str): return components[0] + "".join(x.title() for x in components[1:]) -@pytest.fixture(scope="class") -async def message(bot, chat_id): - to_reply_to = await bot.send_message( - chat_id, "Text", disable_web_page_preview=True, disable_notification=True - ) +@pytest.fixture(scope="function") +async def message(bot, chat_id): # mostly used in tests for edit_message out = await bot.send_message( - chat_id, - "Text", - reply_to_message_id=to_reply_to.message_id, - disable_web_page_preview=True, - disable_notification=True, + chat_id, "Text", disable_web_page_preview=True, disable_notification=True ) out._unfreeze() return out diff --git a/tests/test_document.py b/tests/test_document.py index 88ca100da08..1e3b569428e 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -196,11 +196,12 @@ async def test_error_send_empty_file_id(self, bot, chat_id): with pytest.raises(TelegramError): await bot.send_document(chat_id=chat_id, document="") - async def test_get_and_download(self, bot, document): + async def test_get_and_download(self, bot, document, chat_id): path = Path("telegram.png") if path.is_file(): path.unlink() + document = (await bot.send_document(chat_id, document, read_timeout=50)).document new_file = await bot.get_file(document.file_id) assert new_file.file_size == document.file_size diff --git a/tests/test_sticker.py b/tests/test_sticker.py index a8954cfe7f3..5227130b3f8 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -294,11 +294,12 @@ async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): assert message.sticker.thumb.height == sticker.thumb.height assert message.sticker.thumb.file_size == sticker.thumb.file_size - async def test_get_and_download(self, bot, sticker): + async def test_get_and_download(self, bot, sticker, chat_id): path = Path("telegram.webp") if path.is_file(): path.unlink() + sticker = (await bot.send_sticker(chat_id, sticker, read_timeout=50)).sticker new_file = await bot.get_file(sticker.file_id) assert new_file.file_size == sticker.file_size @@ -780,6 +781,7 @@ async def test_bot_methods_1_png(self, bot, chat_id, sticker_file): file = await bot.upload_sticker_file(chat_id, f) assert file + await asyncio.sleep(1) tasks = asyncio.gather( bot.add_sticker_to_set( chat_id, f"test_by_{bot.username}", png_sticker=file.file_id, emojis="😄" @@ -795,6 +797,7 @@ async def test_bot_methods_1_png(self, bot, chat_id, sticker_file): assert all(await tasks) async def test_bot_methods_1_tgs(self, bot, chat_id): + await asyncio.sleep(1) assert await bot.add_sticker_to_set( chat_id, f"animated_test_by_{bot.username}", @@ -803,24 +806,29 @@ async def test_bot_methods_1_tgs(self, bot, chat_id): ) async def test_bot_methods_1_webm(self, bot, chat_id): + await asyncio.sleep(1) with data_file("telegram_video_sticker.webm").open("rb") as f: assert await bot.add_sticker_to_set( chat_id, f"video_test_by_{bot.username}", webm_sticker=f, emojis="🤔" ) async def test_bot_methods_2_png(self, bot, sticker_set): + await asyncio.sleep(1) file_id = sticker_set.stickers[0].file_id assert await bot.set_sticker_position_in_set(file_id, 1) async def test_bot_methods_2_tgs(self, bot, animated_sticker_set): + await asyncio.sleep(1) file_id = animated_sticker_set.stickers[0].file_id assert await bot.set_sticker_position_in_set(file_id, 1) async def test_bot_methods_2_webm(self, bot, video_sticker_set): + await asyncio.sleep(1) file_id = video_sticker_set.stickers[0].file_id assert await bot.set_sticker_position_in_set(file_id, 1) async def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): + await asyncio.sleep(1) assert await bot.set_sticker_set_thumb( f"test_by_{bot.username}", chat_id, sticker_set_thumb_file ) @@ -828,6 +836,7 @@ async def test_bot_methods_3_png(self, bot, chat_id, sticker_set_thumb_file): async def test_bot_methods_3_tgs( self, bot, chat_id, animated_sticker_file, animated_sticker_set ): + await asyncio.sleep(1) animated_test = f"animated_test_by_{bot.username}" file_id = animated_sticker_set.stickers[-1].file_id tasks = asyncio.gather( @@ -845,14 +854,17 @@ def test_bot_methods_3_webm(self, bot, chat_id, video_sticker_file, video_sticke pass async def test_bot_methods_4_png(self, bot, sticker_set): + await asyncio.sleep(1) file_id = sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) async def test_bot_methods_4_tgs(self, bot, animated_sticker_set): + await asyncio.sleep(1) file_id = animated_sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) async def test_bot_methods_4_webm(self, bot, video_sticker_set): + await asyncio.sleep(1) file_id = video_sticker_set.stickers[-1].file_id assert await bot.delete_sticker_from_set(file_id) diff --git a/tests/test_video.py b/tests/test_video.py index 8613ba8e6b0..3bd0b045211 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -236,11 +236,12 @@ async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): assert message.video.file_name == Space.file_name assert message.has_protected_content - async def test_get_and_download(self, bot, video): + async def test_get_and_download(self, bot, video, chat_id): path = Path("telegram.mp4") if path.is_file(): path.unlink() + video = (await bot.send_video(chat_id, video.file_id, read_timeout=50)).video new_file = await bot.get_file(video.file_id) assert new_file.file_size == Space.file_size diff --git a/tests/test_videonote.py b/tests/test_videonote.py index c6029d3c55c..0d314cd8d00 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -214,11 +214,12 @@ async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, th assert message.video_note.thumb.height == Space.thumb_height assert message.has_protected_content - async def test_get_and_download(self, bot, video_note): + async def test_get_and_download(self, bot, video_note, chat_id): path = Path("telegram2.mp4") if path.is_file(): path.unlink() + video_note = (await bot.send_video_note(chat_id, video_note, read_timeout=50)).video_note new_file = await bot.get_file(video_note.file_id) assert new_file.file_size == Space.file_size diff --git a/tests/test_voice.py b/tests/test_voice.py index 0d7b08b9ec1..858b56c6604 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -198,11 +198,12 @@ async def test_send_all_args(self, bot, chat_id, voice_file, voice): assert message.caption == Space.caption.replace("*", "") assert message.has_protected_content - async def test_get_and_download(self, bot, voice): + async def test_get_and_download(self, bot, voice, chat_id): path = Path("telegram.ogg") if path.is_file(): path.unlink() + voice = (await bot.send_voice(chat_id, voice, read_timeout=50)).voice new_file = await bot.get_file(voice.file_id) assert new_file.file_size == voice.file_size From b3e9e8d8e97422a21182d10059e71d435eceb34c Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 17 Dec 2022 22:38:54 +0530 Subject: [PATCH 28/77] Hopefully fix tests on py3.10+ Happened since py3.10+ bots have a different key name in their bot_info(), leading to an incorrect cached value --- tests/bots.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/bots.py b/tests/bots.py index 4ed5160a5ac..977d078d410 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -45,21 +45,28 @@ BOTS = json.loads(base64.b64decode(BOTS).decode("utf-8")) JOB_INDEX = int(JOB_INDEX) -FALLBACKS = json.loads(base64.b64decode(FALLBACKS).decode("utf-8")) +FALLBACKS = json.loads(base64.b64decode(FALLBACKS).decode("utf-8")) # type: list[dict[str, str]] -def get(name, fallback): +def get(key, fallback): # If we have TOKEN, PAYMENT_PROVIDER_TOKEN, CHAT_ID, SUPER_GROUP_ID, # CHANNEL_ID, BOT_NAME, or BOT_USERNAME in the environment, then use that - val = os.getenv(name.upper()) + val = os.getenv(key.upper()) if val: return val # If we're running as a github action then fetch bots from the repo secrets if GITHUB_ACTION is not None and BOTS is not None and JOB_INDEX is not None: try: - return BOTS[JOB_INDEX][name] - except (KeyError, IndexError): + return BOTS[JOB_INDEX][key] + except KeyError: + # py3.10 bots and later are saved with a different key + if key == "bot_username": + return BOTS[JOB_INDEX]["username"] + elif key == "bot_name": + return BOTS[JOB_INDEX]["name"] + raise + except IndexError: pass # Otherwise go with the fallback From 4ea871eba81708e41bcd04d5caf760044f903308 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 17 Dec 2022 23:05:32 +0530 Subject: [PATCH 29/77] Hotfix to make the tests run discovered make_mock_user would call get_bot() again, which means there was a 50% chance a new bot would have cached. Now we store it the made bot globally and return it instead. --- tests/bots.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/bots.py b/tests/bots.py index 977d078d410..9a1e24d4f3b 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -47,6 +47,8 @@ FALLBACKS = json.loads(base64.b64decode(FALLBACKS).decode("utf-8")) # type: list[dict[str, str]] +chosen_bot = {} + def get(key, fallback): # If we have TOKEN, PAYMENT_PROVIDER_TOKEN, CHAT_ID, SUPER_GROUP_ID, @@ -65,7 +67,6 @@ def get(key, fallback): return BOTS[JOB_INDEX]["username"] elif key == "bot_name": return BOTS[JOB_INDEX]["name"] - raise except IndexError: pass @@ -74,4 +75,8 @@ def get(key, fallback): def get_bot(): - return {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} + global chosen_bot + if chosen_bot: + return chosen_bot + chosen_bot = {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} + return chosen_bot From 4f69b52ca4b7b5519fdde2c79cf8575de15b4be6 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 18 Dec 2022 03:58:56 +0530 Subject: [PATCH 30/77] add a flaky marker to test_signal_handler --- tests/test_application.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_application.py b/tests/test_application.py index a2659d8eab6..2b7149a9c61 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -1944,6 +1944,7 @@ async def raise_method(*args, **kwargs): assert len(recwarn) == 0 + @pytest.mark.flaky(3, 1) # We could run into a flood error from run_webhook def test_signal_handlers(self, app, monkeypatch): # this test should make sure that signal handlers are set by default on Linux + Mac, # and not on Windows. From c8fab413872b2577e40299ce20ac25f7e4dfd87a Mon Sep 17 00:00:00 2001 From: Hinrich Mahler <22366557+Bibo-Joshi@users.noreply.github.com> Date: Sun, 18 Dec 2022 14:43:04 +0100 Subject: [PATCH 31/77] Update keys for bot data --- .github/workflows/test.yml | 2 +- tests/bots.py | 22 ++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e1809bc7acb..02f1dc5a596 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -83,7 +83,7 @@ jobs: exit ${status} env: JOB_INDEX: ${{ strategy.job-index }} - BOTS: W3sidG9rZW4iOiAiNjk2MTg4NzMyOkFBR1Z3RUtmSEhsTmpzY3hFRE5LQXdraEdzdFpfa28xbUMwIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WldGaU1UUmxNbVF5TnpNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzkwOTgzOTk3IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzI3X2JvdCJ9LCB7InRva2VuIjogIjY3MTQ2ODg4NjpBQUdQR2ZjaVJJQlVORmU4MjR1SVZkcTdKZTNfWW5BVE5HdyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpHWXdPVGxrTXpNeE4yWTIiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ0NjAyMjUyMiIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zNF9ib3QifSwgeyJ0b2tlbiI6ICI2MjkzMjY1Mzg6QUFGUnJaSnJCN29CM211ekdzR0pYVXZHRTVDUXpNNUNVNG8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNbU01WVdKaFl6a3hNMlUxIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAzLjUiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDE0OTY5MTc3NTAiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX2NweXRob25fMzVfYm90In0sIHsidG9rZW4iOiAiNjQwMjA4OTQzOkFBRmhCalFwOXFtM1JUeFN6VXBZekJRakNsZS1Kano1aGNrIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WXpoa1pUZzFOamMxWXpWbCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMy42IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzMzODcxNDYxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM2X2JvdCJ9LCB7InRva2VuIjogIjY5NTEwNDA4ODpBQUhmenlsSU9qU0lJUy1lT25JMjB5MkUyMEhvZEhzZnotMCIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk9HUTFNRGd3WmpJd1pqRmwiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNyIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ3ODI5MzcxNCIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zN19ib3QifSwgeyJ0b2tlbiI6ICI2OTE0MjM1NTQ6QUFGOFdrakNaYm5IcVBfaTZHaFRZaXJGRWxackdhWU9oWDAiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZamM1TlRoaU1tUXlNV1ZoIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgUHlQeSAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzNjM5MzI1NzMiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX3B5cHlfMjdfYm90In0sIHsidG9rZW4iOiAiNjg0MzM5OTg0OkFBRk1nRUVqcDAxcjVyQjAwN3lDZFZOc2c4QWxOc2FVLWNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TVRBek1UWTNNR1V5TmpnMCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIFB5UHkgMy41IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDA3ODM2NjA1IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19weXB5XzM1X2JvdCJ9LCB7InRva2VuIjogIjY5MDA5MTM0NzpBQUZMbVI1cEFCNVljcGVfbU9oN3pNNEpGQk9oMHozVDBUbyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpEaGxOekU1TURrd1lXSmkiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMy40IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjc5NjAwMDI2IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2FwcHZleW9yX2NweXRob25fMzRfYm90In0sIHsidG9rZW4iOiAiNjk0MzA4MDUyOkFBRUIyX3NvbkNrNTVMWTlCRzlBTy1IOGp4aVBTNTVvb0JBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WW1aaVlXWm1NakpoWkdNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gQXBwVmV5b3IgdXNpbmcgQ1B5dGhvbiAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEyOTMwNzkxNjUiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICIxMDU1Mzk3NDcxOkFBRzE4bkJfUzJXQXd1SjNnN29oS0JWZ1hYY2VNbklPeVNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpBd056QXpZalZpTkdOayIsICJuYW1lIjogIlBUQiB0ZXN0cyBbMF0iLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDExODU1MDk2MzYiLCAidXNlcm5hbWUiOiAicHRiXzBfYm90In0sIHsidG9rZW4iOiAiMTA0NzMyNjc3MTpBQUY4bk90ODFGcFg4bGJidno4VWV3UVF2UmZUYkZmQnZ1SSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllUVTFOVEk0WkdSallqbGkiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzFdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDg0Nzk3NjEyIiwgInVzZXJuYW1lIjogInB0Yl8xX2JvdCJ9LCB7InRva2VuIjogIjk3MTk5Mjc0NTpBQUdPa09hVzBOSGpnSXY1LTlqUWJPajR2R3FkaFNGLVV1cyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk5XWmtNV1ZoWWpsallqVTUiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzJdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDAyMjU1MDcwIiwgInVzZXJuYW1lIjogInB0Yl8yX2JvdCJ9LCB7InRva2VuIjogIjU1MTg2NDU0MTE6QUFHdzBxaEs3ZTRHbmoxWjJjc1BBQzdaYWtvTWs1NkVKZmsiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNRE0wT1RCbE9UUXpNVEU1IiwgIm5hbWUiOiAiUFRCIFRlc3QgQm90IFszXSIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTgwMzgxMDE5NiIsICJ1c2VybmFtZSI6ICJwdGJfdGVzdF8wM19ib3QifSwgeyJ0b2tlbiI6ICI1NzM3MDE4MzU2OkFBSDEzOFN1aUtRRjBMRENXc2ZnV2VYZmpKNWQ2M2tDV0xBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TjJWaVpqUmxaak01TlRNdyIsICJuYW1lIjogIlBUQiBUZXN0IEJvdCBbNF0iLCAidXNlcm5hbWUiOiAicHRiX3Rlc3RfMDRfYm90IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxODQyNDM5NjQxIn0sIHsidG9rZW4iOiAiNTc0NDY0NDUyMjpBQUVBZHNyRjBoQzZwNkhVTzBQMDFROGJfakNoVTUyWEctTSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpqSmtZVGd5TmpnMlpHRTAiLCAibmFtZSI6ICJQVEIgVGVzdCBCb3QgWzVdIiwgInVzZXJuYW1lIjogInB0Yl90ZXN0XzA1X2JvdCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTg1NTM2MDk4NiJ9XQ== + BOTS: W3sidG9rZW4iOiAiNjk2MTg4NzMyOkFBR1Z3RUtmSEhsTmpzY3hFRE5LQXdraEdzdFpfa28xbUMwIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WldGaU1UUmxNbVF5TnpNeSIsICJuYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzOTA5ODM5OTciLCAidXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICI2NzE0Njg4ODY6QUFHUEdmY2lSSUJVTkZlODI0dUlWZHE3SmUzX1luQVROR3ciLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpaR1l3T1Rsa016TXhOMlkyIiwgIm5hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ0NjAyMjUyMiIsICJ1c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM0X2JvdCJ9LCB7InRva2VuIjogIjYyOTMyNjUzODpBQUZSclpKckI3b0IzbXV6R3NHSlhVdkdFNUNRek01Q1U0byIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk1tTTVZV0poWXpreE0yVTEiLCAibmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMy41IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDk2OTE3NzUwIiwgInVzZXJuYW1lIjogIkBwdGJfdHJhdmlzX2NweXRob25fMzVfYm90In0sIHsidG9rZW4iOiAiNjQwMjA4OTQzOkFBRmhCalFwOXFtM1JUeFN6VXBZekJRakNsZS1Kano1aGNrIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WXpoa1pUZzFOamMxWXpWbCIsICJuYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAzLjYiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzMzM4NzE0NjEiLCAidXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zNl9ib3QifSwgeyJ0b2tlbiI6ICI2OTUxMDQwODg6QUFIZnp5bElPalNJSVMtZU9uSTIweTJFMjBIb2RIc2Z6LTAiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpPR1ExTURnd1pqSXdaakZsIiwgIm5hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNyIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ3ODI5MzcxNCIsICJ1c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM3X2JvdCJ9LCB7InRva2VuIjogIjY5MTQyMzU1NDpBQUY4V2tqQ1pibkhxUF9pNkdoVFlpckZFbFpyR2FZT2hYMCIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllqYzVOVGhpTW1ReU1XVmgiLCAibmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIFB5UHkgMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzYzOTMyNTczIiwgInVzZXJuYW1lIjogIkBwdGJfdHJhdmlzX3B5cHlfMjdfYm90In0sIHsidG9rZW4iOiAiNjg0MzM5OTg0OkFBRk1nRUVqcDAxcjVyQjAwN3lDZFZOc2c4QWxOc2FVLWNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TVRBek1UWTNNR1V5TmpnMCIsICJuYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgUHlQeSAzLjUiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDE0MDc4MzY2MDUiLCAidXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfcHlweV8zNV9ib3QifSwgeyJ0b2tlbiI6ICI2OTAwOTEzNDc6QUFGTG1SNXBBQjVZY3BlX21PaDd6TTRKRkJPaDB6M1QwVG8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpaRGhsTnpFNU1Ea3dZV0ppIiwgIm5hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMy40IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjc5NjAwMDI2IiwgInVzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8zNF9ib3QifSwgeyJ0b2tlbiI6ICI2OTQzMDgwNTI6QUFFQjJfc29uQ2s1NUxZOUJHOUFPLUg4anhpUFM1NW9vQkEiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZbVppWVdabU1qSmhaR015IiwgIm5hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjkzMDc5MTY1IiwgInVzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICIxMDU1Mzk3NDcxOkFBRzE4bkJfUzJXQXd1SjNnN29oS0JWZ1hYY2VNbklPeVNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpBd056QXpZalZpTkdOayIsICJuYW1lIjogIlBUQiB0ZXN0cyBbMF0iLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDExODU1MDk2MzYiLCAidXNlcm5hbWUiOiAicHRiXzBfYm90In0sIHsidG9rZW4iOiAiMTA0NzMyNjc3MTpBQUY4bk90ODFGcFg4bGJidno4VWV3UVF2UmZUYkZmQnZ1SSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllUVTFOVEk0WkdSallqbGkiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzFdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDg0Nzk3NjEyIiwgInVzZXJuYW1lIjogInB0Yl8xX2JvdCJ9LCB7InRva2VuIjogIjk3MTk5Mjc0NTpBQUdPa09hVzBOSGpnSXY1LTlqUWJPajR2R3FkaFNGLVV1cyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk5XWmtNV1ZoWWpsallqVTUiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzJdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDAyMjU1MDcwIiwgInVzZXJuYW1lIjogInB0Yl8yX2JvdCJ9LCB7InRva2VuIjogIjU1MTg2NDU0MTE6QUFHdzBxaEs3ZTRHbmoxWjJjc1BBQzdaYWtvTWs1NkVKZmsiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNRE0wT1RCbE9UUXpNVEU1IiwgIm5hbWUiOiAiUFRCIFRlc3QgQm90IFszXSIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTgwMzgxMDE5NiIsICJ1c2VybmFtZSI6ICJwdGJfdGVzdF8wM19ib3QifSwgeyJ0b2tlbiI6ICI1NzM3MDE4MzU2OkFBSDEzOFN1aUtRRjBMRENXc2ZnV2VYZmpKNWQ2M2tDV0xBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TjJWaVpqUmxaak01TlRNdyIsICJuYW1lIjogIlBUQiBUZXN0IEJvdCBbNF0iLCAidXNlcm5hbWUiOiAicHRiX3Rlc3RfMDRfYm90IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxODQyNDM5NjQxIn0sIHsidG9rZW4iOiAiNTc0NDY0NDUyMjpBQUVBZHNyRjBoQzZwNkhVTzBQMDFROGJfakNoVTUyWEctTSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpqSmtZVGd5TmpnMlpHRTAiLCAibmFtZSI6ICJQVEIgVGVzdCBCb3QgWzVdIiwgInVzZXJuYW1lIjogInB0Yl90ZXN0XzA1X2JvdCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTg1NTM2MDk4NiJ9XQ== TEST_WITH_OPT_DEPS : "false" TEST_BUILD: "true" shell: bash --noprofile --norc {0} diff --git a/tests/bots.py b/tests/bots.py index 9a1e24d4f3b..928761cf26f 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -29,13 +29,13 @@ "W3sidG9rZW4iOiAiNTc5Njk0NzE0OkFBRnBLOHc2emtrVXJENHhTZVl3RjNNTzhlLTRHcm1jeTdjIiwgInBheW1lbnRfc" "HJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpRME5qWmxOekk1WWpKaSIsICJjaGF0X2lkIjogIjY3NTY2Nj" "IyNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTMxMDkxMTEzNSIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTYxOTE" - "1OTQwNCIsICJjaGFubmVsX2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0" - "cyBmYWxsYmFjayAxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzFfYm90In0sIHsidG9rZW4iOiAiNTU4M" - "Tk0MDY2OkFBRndEUElGbHpHVWxDYVdIdFRPRVg0UkZyWDh1OURNcWZvIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOi" - "AiMjg0Njg1MDYzOlRFU1Q6WWpFd09EUXdNVEZtTkRjeSIsICJjaGF0X2lkIjogIjY3NTY2NjIyNCIsICJzdXBlcl9ncm9" - "1cF9pZCI6ICItMTAwMTIyMTIxNjgzMCIsICJmb3J1bV9ncm91cF9pZCI6ICItMTAwMTYxOTE1OTQwNCIsICJjaGFubmVs" - "X2lkIjogIkBweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAyIiwgI" - "mJvdF91c2VybmFtZSI6ICJAcHRiX2ZhbGxiYWNrXzJfYm90In1d " + "1OTQwNCIsICJjaGFubmVsX2lkIjogIk BweXRob250ZWxlZ3JhbWJvdHRlc3RzIiwgIm5hbWUiOiAiUFRCIHRlc3RzIGZ" + "hbGxiYWNrIDEiLCAidXNlcm5hbWUiOiAiQHB0Yl9mYWxsYmFja18xX2JvdCJ9LCB7InRva2VuIjogIjU1ODE5NDA2NjpB" + "QUZ3RFBJRmx6R1VsQ2FXSHRUT0VYNFJGclg4dTlETXFmbyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4N" + "TA2MzpURVNUOllqRXdPRFF3TVRGbU5EY3kiLCAiY2hhdF9pZCI6ICI2NzU2NjYyMj QiLCAic3VwZXJfZ3JvdXBfaWQiO" + "iAiLTEwMDEyMjEyMTY4MzAiLCAiZm9ydW1fZ3JvdXBfaWQiOiAiLTEwMDE2MTkxNTk0MDQiLCAiY2hhbm5lbF9pZCI6IC" + "JAcHl0aG9udGVsZWdyYW1ib3R0ZXN0cyIsICJuYW1lIjogIlBUQiB0ZXN0cyBmYWxsYmFjayAyIiwgInVzZXJuYW1lIjo" + "gIkBwdGJfZmFsbGJhY2tfMl9ib3QifV0=" ) GITHUB_ACTION = os.getenv("GITHUB_ACTION", None) @@ -61,13 +61,7 @@ def get(key, fallback): if GITHUB_ACTION is not None and BOTS is not None and JOB_INDEX is not None: try: return BOTS[JOB_INDEX][key] - except KeyError: - # py3.10 bots and later are saved with a different key - if key == "bot_username": - return BOTS[JOB_INDEX]["username"] - elif key == "bot_name": - return BOTS[JOB_INDEX]["name"] - except IndexError: + except (IndexError, KeyError): pass # Otherwise go with the fallback From 8fa504f5cb15a208ffdf1ee27e5225ccbbcb0548 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 18 Dec 2022 19:38:41 +0530 Subject: [PATCH 32/77] remove env var fetching of bots --- tests/bots.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/bots.py b/tests/bots.py index 928761cf26f..588548c8ff6 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -51,12 +51,6 @@ def get(key, fallback): - # If we have TOKEN, PAYMENT_PROVIDER_TOKEN, CHAT_ID, SUPER_GROUP_ID, - # CHANNEL_ID, BOT_NAME, or BOT_USERNAME in the environment, then use that - val = os.getenv(key.upper()) - if val: - return val - # If we're running as a github action then fetch bots from the repo secrets if GITHUB_ACTION is not None and BOTS is not None and JOB_INDEX is not None: try: From 7f5996e2b1d518a37024845e449b90a5a26744e5 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 20 Dec 2022 01:23:46 +0530 Subject: [PATCH 33/77] Experiment: Try making Job Queue tests more stable --- tests/test_jobqueue.py | 99 +++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 16d80216f27..02112aa9c97 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -20,8 +20,6 @@ import calendar import datetime as dtm import logging -import os -import platform import time import pytest @@ -68,11 +66,6 @@ def test_init_job(self): @pytest.mark.skipif( not TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is installed" ) -@pytest.mark.skipif( - os.getenv("GITHUB_ACTIONS", False) and platform.system() in ["Windows", "Darwin"], - reason="On Windows & MacOS precise timings are not accurate.", -) -@pytest.mark.flaky(10, 1) # Timings aren't quite perfect class TestJobQueue: result = 0 job_time = 0 @@ -83,6 +76,12 @@ def reset(self): self.result = 0 self.job_time = 0 self.received_error = None + self.done_with_cb = asyncio.Event() + + async def wait_for_cbs(self, number: int = 1): + for _ in range(number): + await self.done_with_cb.wait() + self.done_with_cb.clear() async def job_run_once(self, context): if ( @@ -94,7 +93,9 @@ async def job_run_once(self, context): and context.user_data is None and isinstance(context.bot_data, dict) ): - self.result += 1 + if not self.done_with_cb.is_set(): + self.result += 1 + self.done_with_cb.set() async def job_with_exception(self, context): raise Exception("Test Error") @@ -102,12 +103,16 @@ async def job_with_exception(self, context): async def job_remove_self(self, context): self.result += 1 context.job.schedule_removal() + self.done_with_cb.set() async def job_run_once_with_data(self, context): self.result += context.job.data + if hasattr(self, "done_with_cb"): + self.done_with_cb.set() async def job_datetime_tests(self, context): self.job_time = time.time() + self.done_with_cb.set() async def error_handler_context(self, update, context): self.received_error = ( @@ -116,6 +121,7 @@ async def error_handler_context(self, update, context): context.user_data, context.chat_data, ) + self.done_with_cb.set() async def error_handler_raise_error(self, *args): raise Exception("Failing bigly") @@ -138,7 +144,7 @@ def test_application_weakref(self, bot): async def test_run_once(self, job_queue): job_queue.run_once(self.job_run_once, 0.1) - await asyncio.sleep(0.2) + await self.wait_for_cbs() assert self.result == 1 async def test_run_once_timezone(self, job_queue, timezone): @@ -147,24 +153,24 @@ async def test_run_once_timezone(self, job_queue, timezone): # of an xpass when the test is run in a timezone with the same UTC offset when = dtm.datetime.now(timezone) job_queue.run_once(self.job_run_once, when) - await asyncio.sleep(0.1) + await self.wait_for_cbs() assert self.result == 1 async def test_job_with_data(self, job_queue): job_queue.run_once(self.job_run_once_with_data, 0.1, data=5) - await asyncio.sleep(0.2) + await self.wait_for_cbs() assert self.result == 5 async def test_run_repeating(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.1) - await asyncio.sleep(0.25) + await self.wait_for_cbs(2) assert self.result == 2 async def test_run_repeating_first(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.5, first=0.2) await asyncio.sleep(0.15) assert self.result == 0 - await asyncio.sleep(0.1) + await self.wait_for_cbs() assert self.result == 1 async def test_run_repeating_first_timezone(self, job_queue, timezone): @@ -172,24 +178,23 @@ async def test_run_repeating_first_timezone(self, job_queue, timezone): job_queue.run_repeating( self.job_run_once, 0.5, first=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.2) ) - await asyncio.sleep(0.15) assert self.result == 0 - await asyncio.sleep(0.2) + await self.wait_for_cbs() assert self.result == 1 async def test_run_repeating_last(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.25, last=0.4) - await asyncio.sleep(0.3) + await self.wait_for_cbs() assert self.result == 1 - await asyncio.sleep(0.4) + await asyncio.sleep(0.3) assert self.result == 1 async def test_run_repeating_last_timezone(self, job_queue, timezone): - """Test correct scheduling of job when passing a timezone-aware datetime as ``first``""" + """Test correct scheduling of job when passing a timezone-aware datetime as ``last``""" job_queue.run_repeating( self.job_run_once, 0.25, last=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.4) ) - await asyncio.sleep(0.3) + await self.wait_for_cbs() assert self.result == 1 await asyncio.sleep(0.4) assert self.result == 1 @@ -200,19 +205,19 @@ async def test_run_repeating_last_before_first(self, job_queue): async def test_run_repeating_timedelta(self, job_queue): job_queue.run_repeating(self.job_run_once, dtm.timedelta(seconds=0.1)) - await asyncio.sleep(0.25) + await self.wait_for_cbs(2) assert self.result == 2 async def test_run_custom(self, job_queue): job_queue.run_custom(self.job_run_once, {"trigger": "interval", "seconds": 0.2}) - await asyncio.sleep(0.5) + await self.wait_for_cbs(2) assert self.result == 2 async def test_multiple(self, job_queue): job_queue.run_once(self.job_run_once, 0.1) job_queue.run_once(self.job_run_once, 0.2) job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.55) + await self.wait_for_cbs(4) assert self.result == 4 async def test_disabled(self, job_queue): @@ -228,7 +233,7 @@ async def test_disabled(self, job_queue): j1.enabled = True - await asyncio.sleep(0.6) + await self.wait_for_cbs(1) assert self.result == 1 @@ -236,7 +241,7 @@ async def test_schedule_removal(self, job_queue): j1 = job_queue.run_once(self.job_run_once, 0.3) j2 = job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.25) + await self.wait_for_cbs(1) j1.schedule_removal() j2.schedule_removal() @@ -248,7 +253,8 @@ async def test_schedule_removal(self, job_queue): async def test_schedule_removal_from_within(self, job_queue): job_queue.run_repeating(self.job_remove_self, 0.1) - await asyncio.sleep(0.5) + await self.wait_for_cbs(1) + await asyncio.sleep(0.3) assert self.result == 1 @@ -256,14 +262,15 @@ async def test_longer_first(self, job_queue): job_queue.run_once(self.job_run_once, 0.2) job_queue.run_once(self.job_run_once, 0.1) - await asyncio.sleep(0.15) + await self.wait_for_cbs(1) + await asyncio.sleep(0.05) assert self.result == 1 async def test_error(self, job_queue): job_queue.run_repeating(self.job_with_exception, 0.1) job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.3) + await self.wait_for_cbs(1) assert self.result == 1 async def test_in_application(self, bot_info): @@ -274,7 +281,7 @@ async def test_in_application(self, bot_info): assert app.job_queue.scheduler.running app.job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.3) + await self.wait_for_cbs(1) assert self.result == 1 await app.stop() assert not app.job_queue.scheduler.running @@ -287,7 +294,7 @@ async def test_time_unit_int(self, job_queue): expected_time = time.time() + delta job_queue.run_once(self.job_datetime_tests, delta) - await asyncio.sleep(0.6) + await self.wait_for_cbs() assert pytest.approx(self.job_time) == expected_time async def test_time_unit_dt_timedelta(self, job_queue): @@ -297,17 +304,17 @@ async def test_time_unit_dt_timedelta(self, job_queue): expected_time = time.time() + interval.total_seconds() job_queue.run_once(self.job_datetime_tests, interval) - await asyncio.sleep(0.6) + await self.wait_for_cbs() assert pytest.approx(self.job_time) == expected_time async def test_time_unit_dt_datetime(self, job_queue): # Testing running at a specific datetime delta, now = dtm.timedelta(seconds=0.5), dtm.datetime.now(UTC) when = now + delta - expected_time = (now + delta).timestamp() + expected_time = when.timestamp() job_queue.run_once(self.job_datetime_tests, when) - await asyncio.sleep(0.6) + await self.wait_for_cbs() assert self.job_time == pytest.approx(expected_time) async def test_time_unit_dt_time_today(self, job_queue): @@ -318,7 +325,7 @@ async def test_time_unit_dt_time_today(self, job_queue): expected_time = expected_time.timestamp() job_queue.run_once(self.job_datetime_tests, when) - await asyncio.sleep(0.6) + await self.wait_for_cbs() assert self.job_time == pytest.approx(expected_time) async def test_time_unit_dt_time_tomorrow(self, job_queue): @@ -342,7 +349,7 @@ async def test_run_daily(self, job_queue, recwarn): expected_reschedule_time = (now + dtm.timedelta(seconds=delta, days=1)).timestamp() job_queue.run_daily(self.job_run_once, time_of_day) - await asyncio.sleep(delta + 0.1) + await self.wait_for_cbs() assert self.result == 1 scheduled_time = job_queue.jobs()[0].next_t.timestamp() assert scheduled_time == pytest.approx(expected_reschedule_time) @@ -395,7 +402,7 @@ async def test_run_monthly(self, job_queue, timezone): expected_reschedule_time = expected_reschedule_time.timestamp() job_queue.run_monthly(self.job_run_once, time_of_day, day) - await asyncio.sleep(delta + 0.1) + await self.wait_for_cbs() assert self.result == 1 scheduled_time = job_queue.jobs()[0].next_t.timestamp() assert scheduled_time == pytest.approx(expected_reschedule_time, rel=1e-3) @@ -428,7 +435,7 @@ async def test_default_tzinfo(self, tz_bot): when = dtm.datetime.now(tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=0.1) jq.run_once(self.job_run_once, when.time()) - await asyncio.sleep(0.15) + await self.wait_for_cbs() assert self.result == 1 await jq.stop() @@ -437,8 +444,11 @@ async def test_get_jobs(self, job_queue): callback = self.job_run_once job1 = job_queue.run_once(callback, 10, name="name1") + await asyncio.sleep(0.03) job2 = job_queue.run_once(callback, 10, name="name1") + await asyncio.sleep(0.03) job3 = job_queue.run_once(callback, 10, name="name2") + await asyncio.sleep(0.03) assert job_queue.jobs() == (job1, job2, job3) assert job_queue.get_jobs_by_name("name1") == (job1, job2) @@ -453,20 +463,20 @@ async def test_job_run(self, app): async def test_enable_disable_job(self, job_queue): job = job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.5) + await self.wait_for_cbs(2) assert self.result == 2 job.enabled = False assert not job.enabled - await asyncio.sleep(0.5) + await asyncio.sleep(0.25) assert self.result == 2 job.enabled = True assert job.enabled - await asyncio.sleep(0.5) + await self.wait_for_cbs(2) assert self.result == 4 async def test_remove_job(self, job_queue): job = job_queue.run_repeating(self.job_run_once, 0.2) - await asyncio.sleep(0.5) + await self.wait_for_cbs(2) assert self.result == 2 assert not job.removed job.schedule_removal() @@ -497,7 +507,7 @@ async def test_process_error_context(self, job_queue, app): app.add_error_handler(self.error_handler_context) job = job_queue.run_once(self.job_with_exception, 0.1, chat_id=42, user_id=43) - await asyncio.sleep(0.15) + await self.wait_for_cbs() assert self.received_error[0] == "Test Error" assert self.received_error[1] is job self.received_error = None @@ -573,9 +583,10 @@ async def callback(context): context.chat_data, type(context.bot_data), ) + self.done_with_cb.set() job_queue.run_once(callback, 0.1) - await asyncio.sleep(0.15) + await self.wait_for_cbs() assert self.result == (CustomContext, None, None, int) async def test_attribute_error(self): @@ -600,8 +611,8 @@ async def callback(_): if wait: assert not task.done() ready_event.set() - await asyncio.sleep(0.1) + await task # no CancelledError here (see source code of JobQueue.stop for details) assert task.done() else: - await asyncio.sleep(0.1) + await task # unfortunately we will get a CancelledError here assert task.done() From 1baebf2e12ea09ef4e2957809abfdce896668049 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 20 Dec 2022 19:21:55 +0530 Subject: [PATCH 34/77] Experiment 1 cont: Attempt to stablize job queue tests on macos --- tests/test_jobqueue.py | 44 +++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 02112aa9c97..3e39d11d1af 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -42,7 +42,7 @@ class CustomContext(CallbackContext): @pytest.fixture(scope="function") -async def job_queue(bot, app): +async def job_queue(app): jq = JobQueue() jq.set_application(app) await jq.start() @@ -77,12 +77,18 @@ def reset(self): self.job_time = 0 self.received_error = None self.done_with_cb = asyncio.Event() + self.done_with_err_cb = asyncio.Event() async def wait_for_cbs(self, number: int = 1): for _ in range(number): await self.done_with_cb.wait() self.done_with_cb.clear() + async def wait_for_err_cbs(self, number: int = 1): + for _ in range(number): + await self.done_with_err_cb.wait() + self.done_with_err_cb.clear() + async def job_run_once(self, context): if ( isinstance(context, CallbackContext) @@ -98,7 +104,11 @@ async def job_run_once(self, context): self.done_with_cb.set() async def job_with_exception(self, context): - raise Exception("Test Error") + try: + raise Exception("Test Error") + finally: + if not self.done_with_err_cb.is_set(): + self.done_with_err_cb.set() async def job_remove_self(self, context): self.result += 1 @@ -107,7 +117,7 @@ async def job_remove_self(self, context): async def job_run_once_with_data(self, context): self.result += context.job.data - if hasattr(self, "done_with_cb"): + if not self.done_with_cb.is_set(): self.done_with_cb.set() async def job_datetime_tests(self, context): @@ -124,7 +134,11 @@ async def error_handler_context(self, update, context): self.done_with_cb.set() async def error_handler_raise_error(self, *args): - raise Exception("Failing bigly") + try: + raise Exception("Failing bigly") + finally: + if not self.done_with_cb.is_set(): + self.done_with_cb.set() def test_slot_behaviour(self, job_queue, mro_slots): for attr in job_queue.__slots__: @@ -263,14 +277,14 @@ async def test_longer_first(self, job_queue): job_queue.run_once(self.job_run_once, 0.1) await self.wait_for_cbs(1) - await asyncio.sleep(0.05) assert self.result == 1 async def test_error(self, job_queue): job_queue.run_repeating(self.job_with_exception, 0.1) job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(1) + await self.wait_for_err_cbs() + await self.wait_for_cbs() assert self.result == 1 async def test_in_application(self, bot_info): @@ -444,7 +458,7 @@ async def test_get_jobs(self, job_queue): callback = self.job_run_once job1 = job_queue.run_once(callback, 10, name="name1") - await asyncio.sleep(0.03) + await asyncio.sleep(0.03) # To stablize tests on windows job2 = job_queue.run_once(callback, 10, name="name1") await asyncio.sleep(0.03) job3 = job_queue.run_once(callback, 10, name="name2") @@ -456,9 +470,9 @@ async def test_get_jobs(self, job_queue): async def test_job_run(self, app): job = app.job_queue.run_repeating(self.job_run_once, 0.02) - await asyncio.sleep(0.05) - assert self.result == 0 - await job.run(app) + await asyncio.sleep(0.05) # the job queue has not started yet + assert self.result == 0 # so the job will not run + await job.run(app) # but this will force it to run assert self.result == 1 async def test_enable_disable_job(self, job_queue): @@ -507,6 +521,7 @@ async def test_process_error_context(self, job_queue, app): app.add_error_handler(self.error_handler_context) job = job_queue.run_once(self.job_with_exception, 0.1, chat_id=42, user_id=43) + await self.wait_for_err_cbs() await self.wait_for_cbs() assert self.received_error[0] == "Test Error" assert self.received_error[1] is job @@ -522,7 +537,7 @@ async def test_process_error_context(self, job_queue, app): self.received_error = None job = job_queue.run_once(self.job_with_exception, 0.1) - await asyncio.sleep(0.15) + await self.wait_for_err_cbs() assert self.received_error is None await job.run(app) assert self.received_error is None @@ -532,7 +547,8 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.1) - await asyncio.sleep(0.15) + await self.wait_for_err_cbs() + await self.wait_for_cbs() assert len(caplog.records) == 1 rec = caplog.records[-1] assert "An error was raised and an uncaught" in rec.getMessage() @@ -540,6 +556,7 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): await job.run(app) + await self.wait_for_err_cbs() assert len(caplog.records) == 1 rec = caplog.records[-1] assert "uncaught error was raised while handling" in rec.getMessage() @@ -551,7 +568,8 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.1) - await asyncio.sleep(0.15) + await self.wait_for_err_cbs() + await asyncio.sleep(0.1) # sleep for a bit so that caplog fixture registers an error assert len(caplog.records) == 1 rec = caplog.records[-1] assert "No error handlers are registered" in rec.getMessage() From a608e488b34b12a02be9af408c8a9a107ade66d4 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 20 Dec 2022 19:48:21 +0530 Subject: [PATCH 35/77] Experiment 1 cont: stablilize another test on macos --- tests/test_jobqueue.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 3e39d11d1af..b07109aac41 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -70,6 +70,7 @@ class TestJobQueue: result = 0 job_time = 0 received_error = None + # we have 2 more variables which define in `reset` since it needs to be on the same event loop @pytest.fixture(autouse=True) def reset(self): @@ -252,10 +253,11 @@ async def test_disabled(self, job_queue): assert self.result == 1 async def test_schedule_removal(self, job_queue): - j1 = job_queue.run_once(self.job_run_once, 0.3) + j1 = job_queue.run_once(self.job_run_once, 0.5) j2 = job_queue.run_repeating(self.job_run_once, 0.2) await self.wait_for_cbs(1) + assert self.result == 1 j1.schedule_removal() j2.schedule_removal() From 67b2ba2a8aa7553a2103b10f5002325dd2b67dc9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 20 Dec 2022 21:21:51 +0530 Subject: [PATCH 36/77] Experiment 1 end: use asyncio.wait_for so tests cannot hang --- tests/test_jobqueue.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index b07109aac41..fcca08d70e5 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -81,14 +81,26 @@ def reset(self): self.done_with_err_cb = asyncio.Event() async def wait_for_cbs(self, number: int = 1): - for _ in range(number): - await self.done_with_cb.wait() - self.done_with_cb.clear() + async def _wait_for_cbs(): + for _ in range(number): + await self.done_with_cb.wait() + self.done_with_cb.clear() + + try: + await asyncio.wait_for(_wait_for_cbs(), 10) + except asyncio.TimeoutError: # just in case, don't want to hang the tests + pass async def wait_for_err_cbs(self, number: int = 1): - for _ in range(number): - await self.done_with_err_cb.wait() - self.done_with_err_cb.clear() + async def _wait_for_err_cbs(): + for _ in range(number): + await self.done_with_err_cb.wait() + self.done_with_err_cb.clear() + + try: + await asyncio.wait_for(_wait_for_err_cbs(), 10) + except asyncio.TimeoutError: # just in case, don't want to hang the tests + pass async def job_run_once(self, context): if ( From 5c778d1a650a4aef80baee41be2458dd05c52358 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 20 Dec 2022 21:25:44 +0530 Subject: [PATCH 37/77] Experiment 2: Make GH CI use 10 workers with loadgroup --- .github/workflows/test.yml | 6 +++--- tests/test_bot.py | 5 +++++ tests/test_sticker.py | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 02f1dc5a596..b45929a2849 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,9 +76,9 @@ jobs: # Test the rest export TEST_WITH_OPT_DEPS='true' pip install -r requirements-opts.txt - # `-n auto --dist loadfile` uses pytest-xdist to run each test file on a different CPU - # worker - pytest -v --cov --cov-append -n auto --dist loadfile + # `-n 10 --dist=loadgroup` uses pytest-xdist to run distribute each tests across + # 10 CPUs. Tests marked with `xdist_group` run in the same worker (in order). + pytest -v --cov --cov-append -n 10 --dist=loadgroup status=$(( $? > status ? $? : status)) exit ${status} env: diff --git a/tests/test_bot.py b/tests/test_bot.py index c22df861ec9..d2242b84036 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2396,6 +2396,7 @@ async def test_send_game_default_protect_content(self, default_bot, chat_id, val protected = await default_bot.send_game(chat_id, "test_game", protect_content=val) assert protected.has_protected_content is val + @pytest.mark.xdist_group("game") @xfail async def test_set_game_score_1(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods @@ -2415,6 +2416,7 @@ async def test_set_game_score_1(self, bot, chat_id): assert message.game.animation.file_unique_id == game.game.animation.file_unique_id assert message.game.text != game.game.text + @pytest.mark.xdist_group("game") @xfail async def test_set_game_score_2(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods @@ -2437,6 +2439,7 @@ async def test_set_game_score_2(self, bot, chat_id): assert message.game.animation.file_unique_id == game.game.animation.file_unique_id assert message.game.text == game.game.text + @pytest.mark.xdist_group("game") @xfail async def test_set_game_score_3(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods @@ -2451,6 +2454,7 @@ async def test_set_game_score_3(self, bot, chat_id): user_id=chat_id, score=score, chat_id=game.chat_id, message_id=game.message_id ) + @pytest.mark.xdist_group("game") @xfail async def test_set_game_score_4(self, bot, chat_id): # NOTE: numbering of methods assures proper order between test_set_game_scoreX methods @@ -2478,6 +2482,7 @@ async def test_set_game_score_4(self, bot, chat_id): game2 = await bot.send_game(chat_id, game_short_name) assert str(score) in game2.game.text + @pytest.mark.xdist_group("game") @xfail async def test_get_game_high_scores(self, bot, chat_id): # We need a game to get the scores for diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 5227130b3f8..a86ad8f50d2 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -731,6 +731,7 @@ async def make_assertion(*_, **kwargs): assert await sticker.get_file() +@pytest.mark.xdist_group("stickerset") class TestStickerSetReq: async def test_create_sticker_set( self, bot, chat_id, sticker_file, animated_sticker_file, video_sticker_file From 050f650a2bc85a4d795749bde44556e379507af1 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:37:09 +0400 Subject: [PATCH 38/77] mark job queue tests as flaky --- tests/test_jobqueue.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 93ad00d0d2d..43c2eb47606 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -66,6 +66,8 @@ def test_init_job(self): @pytest.mark.skipif( not TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is installed" ) +# needed if we run pytest -n=number > no. of CPUs & since asyncio.Events aren't thread-safe. +@pytest.mark.flaky(4, 1) class TestJobQueue: result = 0 job_time = 0 From d7c09a165a675f1c196e238ea5d7b985f500ee65 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:48:05 +0400 Subject: [PATCH 39/77] attempt to fix potential race condition in test_passport.py --- tests/test_passport.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_passport.py b/tests/test_passport.py index f538ba50605..720a370b05a 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -405,9 +405,10 @@ def test_equality(self, passport_data): assert hash(a) == hash(b) assert a is not b - passport_data.credentials._unfreeze() - passport_data.credentials.hash = "NOTAPROPERHASH" - c = PassportData(passport_data.data, passport_data.credentials) + new_pp_data = deepcopy(passport_data) + new_pp_data.credentials._unfreeze() + new_pp_data.credentials.hash = "NOTAPROPERHASH" + c = PassportData(new_pp_data.data, new_pp_data.credentials) assert a != c assert hash(a) != hash(c) From e37ab7e5b5e4c950d08e43df94d976f2ccc493dd Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 19:21:03 +0400 Subject: [PATCH 40/77] attempt to fix the error: 'free variable input_video referenced before assignment in enclosing scope --- tests/test_inputmedia.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index c53dc7764df..af89b10e06e 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -553,6 +553,7 @@ async def test_send_media_group_with_thumbs( self, bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 ): async def make_assertion(method, url, request_data: RequestData, *args, **kwargs): + nonlocal input_video files = request_data.multipart_data video_check = files[input_video.media.attach_name] == input_video.media.field_tuple thumb_check = files[input_video.thumb.attach_name] == input_video.thumb.field_tuple From 3bdd98128a4f678c21f747b088df2ba0a2e9e21a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 19:59:51 +0400 Subject: [PATCH 41/77] fix error while collecting tests in test_datetime.py solved by removing parametrize --- tests/test_datetime.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/tests/test_datetime.py b/tests/test_datetime.py index e668b54eab9..4076170c52b 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -27,16 +27,17 @@ # sample time specification values categorised into absolute / delta / time-of-day from tests.conftest import TEST_WITH_OPT_DEPS -ABSOLUTE_TIME_SPECS = [ - dtm.datetime.now(tz=dtm.timezone(dtm.timedelta(hours=-7))).replace(second=0, microsecond=0), - dtm.datetime.utcnow().replace(second=0, microsecond=0), -] DELTA_TIME_SPECS = [dtm.timedelta(hours=3, seconds=42, milliseconds=2), 30, 7.5] TIME_OF_DAY_TIME_SPECS = [ dtm.time(12, 42, tzinfo=dtm.timezone(dtm.timedelta(hours=-7))), dtm.time(12, 42), ] RELATIVE_TIME_SPECS = DELTA_TIME_SPECS + TIME_OF_DAY_TIME_SPECS + +ABSOLUTE_TIME_SPECS = [ + dtm.datetime.now(tz=dtm.timezone(dtm.timedelta(hours=-7))), + dtm.datetime.utcnow(), +] TIME_SPECS = ABSOLUTE_TIME_SPECS + RELATIVE_TIME_SPECS """ @@ -95,12 +96,14 @@ def test_to_float_timestamp_absolute_no_reference(self): with pytest.raises(ValueError): tg_dtm.to_float_timestamp(dtm.datetime(2019, 11, 11), reference_timestamp=123) - @pytest.mark.parametrize("time_spec", DELTA_TIME_SPECS, ids=str) - def test_to_float_timestamp_delta(self, time_spec): + def test_to_float_timestamp_delta(self): """Conversion from a 'delta' time specification to timestamp""" reference_t = 0 - delta = time_spec.total_seconds() if hasattr(time_spec, "total_seconds") else time_spec - assert tg_dtm.to_float_timestamp(time_spec, reference_t) == reference_t + delta + for i in DELTA_TIME_SPECS: + delta = i.total_seconds() if hasattr(i, "total_seconds") else i + assert ( + tg_dtm.to_float_timestamp(i, reference_t) == reference_t + delta + ), f"failed for {i}" def test_to_float_timestamp_time_of_day(self): """Conversion from time-of-day specification to timestamp""" @@ -128,22 +131,22 @@ def test_to_float_timestamp_time_of_day_timezone(self, timezone): ref_t + (-utc_offset.total_seconds() % (24 * 60 * 60)) ) - @pytest.mark.parametrize("time_spec", RELATIVE_TIME_SPECS, ids=str) - def test_to_float_timestamp_default_reference(self, time_spec): + def test_to_float_timestamp_default_reference(self): """The reference timestamp for relative time specifications should default to now""" - now = time.time() - assert tg_dtm.to_float_timestamp(time_spec) == pytest.approx( - tg_dtm.to_float_timestamp(time_spec, reference_timestamp=now) - ) + for i in RELATIVE_TIME_SPECS: + now = time.time() + assert tg_dtm.to_float_timestamp(i) == pytest.approx( + tg_dtm.to_float_timestamp(i, reference_timestamp=now) + ), f"Failed for {i}" def test_to_float_timestamp_error(self): with pytest.raises(TypeError, match="Defaults"): tg_dtm.to_float_timestamp(Defaults()) - @pytest.mark.parametrize("time_spec", TIME_SPECS, ids=str) - def test_to_timestamp(self, time_spec): + def test_to_timestamp(self): # delegate tests to `to_float_timestamp` - assert tg_dtm.to_timestamp(time_spec) == int(tg_dtm.to_float_timestamp(time_spec)) + for i in TIME_SPECS: + assert tg_dtm.to_timestamp(i) == int(tg_dtm.to_float_timestamp(i)), f"Failed for {i}" def test_to_timestamp_none(self): # this 'convenience' behaviour has been left left for backwards compatibility From 402aa03ce8c9152940ae91aebf138d22d2d6d714 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 20:08:31 +0400 Subject: [PATCH 42/77] why tests no run? --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d77f51e9ed..44e8b784876 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,9 +76,9 @@ jobs: # Test the rest export TEST_WITH_OPT_DEPS='true' pip install -r requirements-opts.txt - # `-n 10 --dist=loadgroup` uses pytest-xdist to run distribute each tests across - # 10 CPUs. Tests marked with `xdist_group` run in the same worker (in order). - pytest -v --cov --cov-append -n 10 --dist=loadgroup + # `-n 11 --dist=loadgroup` uses pytest-xdist to run distribute each tests across + # 11 CPUs. Tests marked with `xdist_group` run in the same worker (in order). + pytest -v --cov --cov-append -n 11 --dist=loadgroup status=$(( $? > status ? $? : status)) exit ${status} env: From 024315b77aa99eefde9e4abd813158c5ef1d7a33 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 22:32:35 +0400 Subject: [PATCH 43/77] change scope of real_topic back to function --- tests/test_forum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_forum.py b/tests/test_forum.py index 2e430767e2e..2e2d941c688 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -55,7 +55,7 @@ async def forum_topic_object(forum_group_id, emoji_id): ) -@pytest.fixture(scope="module") +@pytest.fixture(scope="function") async def real_topic(bot, emoji_id, forum_group_id): result = await bot.create_forum_topic( chat_id=forum_group_id, From f3c671dc6da3bfee8ebd8c11fee33d6e91c6e4f2 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 22:35:24 +0400 Subject: [PATCH 44/77] Experiment 2 end: Revert back to -n auto, but keep --dist=loadgroup --- .github/workflows/test.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44e8b784876..680debc218b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -76,9 +76,11 @@ jobs: # Test the rest export TEST_WITH_OPT_DEPS='true' pip install -r requirements-opts.txt - # `-n 11 --dist=loadgroup` uses pytest-xdist to run distribute each tests across - # 11 CPUs. Tests marked with `xdist_group` run in the same worker (in order). - pytest -v --cov --cov-append -n 11 --dist=loadgroup + # `-n auto --dist=loadgroup` uses pytest-xdist to run distribute each tests across + # available CPUs. Tests marked with `xdist_group` run in the same worker (in order). + # Increasing number of workers has no effect on test duration, but it seems to increase + # flakyness. + pytest -v --cov --cov-append -n auto --dist=loadgroup status=$(( $? > status ? $? : status)) exit ${status} env: From dc847dfe51d5d8f60ceff750d99dc17ef17b041a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 23:10:00 +0400 Subject: [PATCH 45/77] Experiment 3: Run tests of optional dependencies in one go --- .github/workflows/test.yml | 44 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 680debc218b..b69e785dbf6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,44 +42,26 @@ jobs: # The first & second one are achieved by mocking the corresponding import # See test_helpers.py & test_no_passport.py for details run: | - # Test without passport - pytest -v --cov -k test_no_passport.py + # We test without optional dependencies first. + TO_TEST="test_no_passport.py or + test_datetime.py or + test_defaults.py or + test_jobqueue.py or + test_applicationbuilder.py or + test_ratelimiter.py or + test_updater.py or + test_callbackdatacache.py or + test_request.py" + pytest -v --cov -k "${TO_TEST}" status=$? - # test without pytz - pytest -v --cov --cov-append -k test_datetime.py - status=$(( $? > status ? $? : status)) - pytest -v --cov --cov-append -k test_defaults.py - status=$(( $? > status ? $? : status)) - - # test without pytz & jobqueue - pytest -v --cov --cov-append -k test_jobqueue.py - pytest -v --cov --cov-append -k test_applicationbuilder.py - status=$(( $? > status ? $? : status)) - - # Test without ratelimiter - pytest -v --cov --cov-append -k test_ratelimiter.py - status=$(( $? > status ? $? : status)) - - # Test without webhooks - pytest -v --cov --cov-append -k test_updater.py - status=$(( $? > status ? $? : status)) - - # Test without callback-data - pytest -v --cov --cov-append -k test_callbackdatacache.py - status=$(( $? > status ? $? : status)) - - # Test without socks - pytest -v --cov --cov-append -k test_request.py - status=$(( $? > status ? $? : status)) - # Test the rest export TEST_WITH_OPT_DEPS='true' pip install -r requirements-opts.txt # `-n auto --dist=loadgroup` uses pytest-xdist to run distribute each tests across # available CPUs. Tests marked with `xdist_group` run in the same worker (in order). - # Increasing number of workers has no effect on test duration, but it seems to increase - # flakyness. + # Increasing number of workers has little effect on test duration, but it seems to + # increase flakyness. pytest -v --cov --cov-append -n auto --dist=loadgroup status=$(( $? > status ? $? : status)) exit ${status} From 744308d095667c0315eb199259f6436876a695c9 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 23:26:39 +0400 Subject: [PATCH 46/77] run getUpdates and webhook tests in same worker --- tests/test_bot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_bot.py b/tests/test_bot.py index c3a29622781..6e63b9fd444 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2281,6 +2281,7 @@ async def test_edit_reply_markup(self, bot, message): async def test_edit_reply_markup_inline(self): pass + @pytest.mark.xdist_group("getUpdates_and_webhook") # TODO: Actually send updates to the test bot so this can be tested properly async def test_get_updates(self, bot): await bot.delete_webhook() # make sure there is no webhook set if webhook tests failed @@ -2290,6 +2291,7 @@ async def test_get_updates(self, bot): if updates: assert isinstance(updates[0], Update) + @pytest.mark.xdist_group("getUpdates_and_webhook") @pytest.mark.parametrize("use_ip", [True, False]) # local file path as file_input is tested below in test_set_webhook_params @pytest.mark.parametrize("file_input", ["bytes", "file_handle"]) From 72e0a6ebccc0dddb14d3b42c99ab25e475a57cc7 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 23:33:47 +0400 Subject: [PATCH 47/77] Experiment 3 cont: make the variable in a single line --- .github/workflows/test.yml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b69e785dbf6..bce9e73f7a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,15 +43,7 @@ jobs: # See test_helpers.py & test_no_passport.py for details run: | # We test without optional dependencies first. - TO_TEST="test_no_passport.py or - test_datetime.py or - test_defaults.py or - test_jobqueue.py or - test_applicationbuilder.py or - test_ratelimiter.py or - test_updater.py or - test_callbackdatacache.py or - test_request.py" + TO_TEST="test_no_passport.py or test_datetime.py or test_defaults.py or test_jobqueue.py or test_applicationbuilder.py or test_ratelimiter.py or test_updater.py or test_callbackdatacache.py or test_request.py" pytest -v --cov -k "${TO_TEST}" status=$? From ebad4e49dad5e7ef5f283d7f6c8b1e645c53ea6e Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 3 Jan 2023 23:52:12 +0400 Subject: [PATCH 48/77] increase sleep duration in test_conversation_timout --- tests/test_conversationhandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_conversationhandler.py b/tests/test_conversationhandler.py index f56924ae0e6..86ae194d338 100644 --- a/tests/test_conversationhandler.py +++ b/tests/test_conversationhandler.py @@ -1253,7 +1253,7 @@ async def test_conversation_timeout(self, app, bot, user1): await app.process_update(Update(update_id=2, message=brew_message)) assert handler.check_update(Update(0, message=pour_coffee_message)) # assert handler.conversations.get((self.group.id, user1.id)) == self.BREWING - await asyncio.sleep(0.7) + await asyncio.sleep(0.75) assert handler.check_update(Update(0, message=start_message)) # assert handler.conversations.get((self.group.id, user1.id)) is None From 2510df80f414893a2a1ea3119e32270c3d22632e Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 4 Jan 2023 22:09:57 +0400 Subject: [PATCH 49/77] fix potential race condition while unpinning message --- tests/test_bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index 6e63b9fd444..e21abac5ac7 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2814,6 +2814,7 @@ async def test_pin_and_unpin_message(self, bot, super_group_id): bot.unpin_chat_message(chat_id=super_group_id, read_timeout=10), # unpins most recent ) assert all(await tasks) + assert all([i.done() for i in tasks]) assert await bot.unpin_all_chat_messages(super_group_id, read_timeout=10) # get_sticker_set, upload_sticker_file, create_new_sticker_set, add_sticker_to_set, @@ -3170,10 +3171,10 @@ async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): chat = await bot.get_chat(super_group_id) assert chat.pinned_message == message assert chat.pinned_message.reply_markup == reply_markup + assert await message.unpin() # (not placed in finally block since msg can be unbound) finally: bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - await bot.unpin_all_chat_messages(super_group_id) async def test_arbitrary_callback_data_get_chat_no_pinned_message( self, super_group_id, cdc_bot From 03501e439bfc8486bf8475469c44611278ea0916 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Jan 2023 17:34:28 +0530 Subject: [PATCH 50/77] make test_get_chat_arbitrary_callback_data use channel_id for testing --- tests/test_bot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index e21abac5ac7..6feddddf8ca 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -3151,7 +3151,7 @@ async def test_replace_callback_data_copy_message(self, cdc_bot, chat_id): bot.callback_data_cache.clear_callback_data() bot.callback_data_cache.clear_callback_queries() - async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): + async def test_get_chat_arbitrary_callback_data(self, channel_id, cdc_bot): bot = cdc_bot try: @@ -3160,7 +3160,7 @@ async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): ) message = await bot.send_message( - super_group_id, text="get_chat_arbitrary_callback_data", reply_markup=reply_markup + channel_id, text="get_chat_arbitrary_callback_data", reply_markup=reply_markup ) await message.pin() @@ -3168,7 +3168,7 @@ async def test_get_chat_arbitrary_callback_data(self, super_group_id, cdc_bot): data = list(bot.callback_data_cache._keyboard_data[keyboard].button_data.values())[0] assert data == "callback_data" - chat = await bot.get_chat(super_group_id) + chat = await bot.get_chat(channel_id) assert chat.pinned_message == message assert chat.pinned_message.reply_markup == reply_markup assert await message.unpin() # (not placed in finally block since msg can be unbound) From 891ed29334ab9adc4674eff732f3cda1b3880b80 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:30:44 +0530 Subject: [PATCH 51/77] Address review of fc5aea4: Use `TestXXXWith(out)Request` Also add CSI comments to pytest_collection_modifyitems and apply a ruff related change in tests/test_updater.py --- tests/README.md | 2 +- tests/conftest.py | 26 ++++++++++++------- tests/test_animation.py | 4 +-- tests/test_audio.py | 4 +-- tests/test_bot.py | 4 +-- tests/test_botcommand.py | 2 +- tests/test_botcommandscope.py | 2 +- tests/test_callbackquery.py | 2 +- tests/test_chat.py | 2 +- tests/test_chatadministratorrights.py | 2 +- tests/test_chatinvitelink.py | 2 +- tests/test_chatjoinrequest.py | 2 +- tests/test_chatlocation.py | 2 +- tests/test_chatmember.py | 2 +- tests/test_chatmemberupdated.py | 2 +- tests/test_chatpermissions.py | 2 +- tests/test_chatphoto.py | 4 +-- tests/test_choseninlineresult.py | 2 +- tests/test_constants.py | 4 +-- tests/test_contact.py | 4 +-- tests/test_dice.py | 2 +- tests/test_document.py | 4 +-- tests/test_encryptedcredentials.py | 2 +- tests/test_encryptedpassportelement.py | 2 +- tests/test_file.py | 4 +-- tests/test_forcereply.py | 4 +-- tests/test_forum.py | 10 +++---- tests/test_game.py | 2 +- tests/test_gamehighscore.py | 2 +- tests/test_inlinekeyboardbutton.py | 2 +- tests/test_inlinekeyboardmarkup.py | 4 +-- tests/test_inlinequery.py | 2 +- tests/test_inlinequeryresultarticle.py | 2 +- tests/test_inlinequeryresultaudio.py | 2 +- tests/test_inlinequeryresultcachedaudio.py | 2 +- tests/test_inlinequeryresultcacheddocument.py | 2 +- tests/test_inlinequeryresultcachedgif.py | 2 +- tests/test_inlinequeryresultcachedmpeg4gif.py | 2 +- tests/test_inlinequeryresultcachedphoto.py | 2 +- tests/test_inlinequeryresultcachedsticker.py | 2 +- tests/test_inlinequeryresultcachedvideo.py | 2 +- tests/test_inlinequeryresultcachedvoice.py | 2 +- tests/test_inlinequeryresultcontact.py | 2 +- tests/test_inlinequeryresultdocument.py | 2 +- tests/test_inlinequeryresultgame.py | 2 +- tests/test_inlinequeryresultgif.py | 2 +- tests/test_inlinequeryresultlocation.py | 2 +- tests/test_inlinequeryresultmpeg4gif.py | 2 +- tests/test_inlinequeryresultphoto.py | 2 +- tests/test_inlinequeryresultvenue.py | 2 +- tests/test_inlinequeryresultvideo.py | 2 +- tests/test_inlinequeryresultvoice.py | 2 +- tests/test_inputcontactmessagecontent.py | 2 +- tests/test_inputfile.py | 4 +-- tests/test_inputinvoicemessagecontent.py | 2 +- tests/test_inputlocationmessagecontent.py | 2 +- tests/test_inputmedia.py | 14 +++++----- tests/test_inputtextmessagecontent.py | 2 +- tests/test_inputvenuemessagecontent.py | 2 +- tests/test_invoice.py | 4 +-- tests/test_keyboardbutton.py | 2 +- tests/test_keyboardbuttonpolltype.py | 2 +- tests/test_labeledprice.py | 2 +- tests/test_location.py | 4 +-- tests/test_loginurl.py | 2 +- tests/test_menubutton.py | 2 +- tests/test_message.py | 2 +- tests/test_messageautodeletetimerchanged.py | 2 +- tests/test_messageentity.py | 2 +- tests/test_messageid.py | 4 +-- tests/test_no_passport.py | 2 +- tests/test_orderinfo.py | 2 +- tests/test_passport.py | 2 +- tests/test_passportelementerrordatafield.py | 2 +- tests/test_passportelementerrorfile.py | 2 +- tests/test_passportelementerrorfiles.py | 2 +- tests/test_passportelementerrorfrontside.py | 2 +- tests/test_passportelementerrorreverseside.py | 2 +- tests/test_passportelementerrorselfie.py | 2 +- ...est_passportelementerrortranslationfile.py | 2 +- ...st_passportelementerrortranslationfiles.py | 2 +- tests/test_passportelementerrorunspecified.py | 2 +- tests/test_passportfile.py | 2 +- tests/test_photo.py | 4 +-- tests/test_poll.py | 6 ++--- tests/test_precheckoutquery.py | 2 +- tests/test_proximityalerttriggered.py | 2 +- tests/test_replykeyboardmarkup.py | 4 +-- tests/test_replykeyboardremove.py | 4 +-- tests/test_request.py | 6 ++--- tests/test_requestdata.py | 2 +- tests/test_requestparameter.py | 2 +- tests/test_sentwebappmessage.py | 2 +- tests/test_shippingaddress.py | 2 +- tests/test_shippingoption.py | 2 +- tests/test_shippingquery.py | 2 +- tests/test_sticker.py | 10 +++---- tests/test_successfulpayment.py | 2 +- tests/test_update.py | 2 +- tests/test_updater.py | 2 +- tests/test_user.py | 2 +- tests/test_userprofilephotos.py | 2 +- tests/test_venue.py | 4 +-- tests/test_video.py | 4 +-- tests/test_videochat.py | 8 +++--- tests/test_videonote.py | 4 +-- tests/test_voice.py | 4 +-- tests/test_webappdata.py | 2 +- tests/test_webappinfo.py | 2 +- tests/test_webhookinfo.py | 2 +- 110 files changed, 167 insertions(+), 161 deletions(-) diff --git a/tests/README.md b/tests/README.md index 8c696b249f7..c0ec78f4aa1 100644 --- a/tests/README.md +++ b/tests/README.md @@ -31,7 +31,7 @@ the failed tests in isolation, you can use the `--lf` flag: PTB has a separate test file for every file in the `telegram.*` namespace. Further, the tests for the `telegram` module are split into two classes, based on whether the test methods in them make a request or not. When writing tests, make sure to split them into these two classes, and make sure -to name the test class as: `TestXXXNoReq` for tests that don't make a request, and `TestXXXReq` for +to name the test class as: `TestXXXWithoutRequest` for tests that don't make a request, and `TestXXXReq` for tests that do. Writing tests is a creative process, where you can design your test however you'd like, but there diff --git a/tests/conftest.py b/tests/conftest.py index 8e2fe5c546e..79dbaeaf783 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -59,18 +59,24 @@ def pytest_runtestloop(session: pytest.Session): def pytest_collection_modifyitems(items: List[pytest.Item]): - """Here we add a flaky marker to all request making tests and the no_req marker to the rest.""" - for item in items: - parent = item.parent - if parent is None: + """Here we add a flaky marker to all request making tests and a (no_)req marker to the rest.""" + for item in items: # items are the test methods + parent = item.parent # Get the parent of the item (class, or module if defined outside) + if parent is None: # should never happen, but just in case return - if ( - "NoReq" not in parent.name - and parent.name.endswith("Req") - and not parent.get_closest_marker(name="flaky") - ): + if ( # Check if the class name ends with 'WithRequest' and if it has no flaky marker + parent.name.endswith("WithRequest") + and not parent.get_closest_marker( # get_closest_marker gets pytest.marks with `name` + name="flaky" + ) # don't add/override any previously set markers + and not parent.get_closest_marker(name="req") + ): # Add the flaky marker with a rerun filter to the class parent.add_marker(pytest.mark.flaky(3, 1, rerun_filter=no_rerun_after_xfail_or_flood)) - elif parent.name.endswith("NoReq") and not parent.get_closest_marker(name="no_req"): + parent.add_marker(pytest.mark.req) + # Add the no_req marker to all classes that end with 'WithoutRequest' and don't have it + elif parent.name.endswith("WithoutRequest") and not parent.get_closest_marker( + name="no_req" + ): parent.add_marker(pytest.mark.no_req) diff --git a/tests/test_animation.py b/tests/test_animation.py index b56ac491f1d..dd8143d00fe 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -63,7 +63,7 @@ class Space: caption = "Test *animation*" -class TestAnimationNoReq: +class TestAnimationWithoutRequest: def test_slot_behaviour(self, animation, mro_slots): for attr in animation.__slots__: assert getattr(animation, attr, "err") != "err", f"got extra slot '{attr}'" @@ -189,7 +189,7 @@ async def make_assertion(*_, **kwargs): assert await animation.get_file() -class TestAnimationReq: +class TestAnimationWithRequest: async def test_send_all_args(self, bot, chat_id, animation_file, animation, thumb_file): message = await bot.send_animation( chat_id, diff --git a/tests/test_audio.py b/tests/test_audio.py index 840ed243662..fd0ac52ca20 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -64,7 +64,7 @@ class Space: audio_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestAudioNoReq: +class TestAudioWithoutRequest: def test_slot_behaviour(self, audio, mro_slots): for attr in audio.__slots__: assert getattr(audio, attr, "err") != "err", f"got extra slot '{attr}'" @@ -194,7 +194,7 @@ async def make_assertion(*_, **kwargs): assert await audio.get_file() -class TestAudioReq: +class TestAudioWithRequest: async def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): message = await bot.send_audio( chat_id, diff --git a/tests/test_bot.py b/tests/test_bot.py index 6feddddf8ca..be9f545c263 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -192,7 +192,7 @@ def __init__( self.disable_web_page_preview = disable_web_page_preview -class TestBotNoReq: +class TestBotWithoutRequest: @pytest.mark.parametrize("bot_class", [Bot, ExtBot]) def test_slot_behaviour(self, bot_class, bot, mro_slots): inst = bot_class(bot.token) @@ -1636,7 +1636,7 @@ async def post(*args, **kwargs): bot.callback_data_cache.clear_callback_queries() -class TestBotReq: +class TestBotWithRequest: """ Most are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot diff --git a/tests/test_botcommand.py b/tests/test_botcommand.py index 6a5b65f7c20..80b529042cf 100644 --- a/tests/test_botcommand.py +++ b/tests/test_botcommand.py @@ -27,7 +27,7 @@ def bot_command(): return BotCommand(command="start", description="A command") -class TestBotCommandNoReq: +class TestBotCommandWithoutRequest: command = "start" description = "A command" diff --git a/tests/test_botcommandscope.py b/tests/test_botcommandscope.py index 07386d2d3a8..78472f07684 100644 --- a/tests/test_botcommandscope.py +++ b/tests/test_botcommandscope.py @@ -115,7 +115,7 @@ def bot_command_scope(scope_class_and_type, chat_id): # All the scope types are very similar, so we test everything via parametrization -class TestBotCommandScopeNoReq: +class TestBotCommandScopeWithoutRequest: def test_slot_behaviour(self, bot_command_scope, mro_slots): for attr in bot_command_scope.__slots__: assert getattr(bot_command_scope, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 9a8dd0206cf..c3fe5c61eb2 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -58,7 +58,7 @@ class Space: game_short_name = "the_game" -class TestCallbackQueryNoReq: +class TestCallbackQueryWithoutRequest: @staticmethod def skip_params(callback_query: CallbackQuery): if callback_query.inline_message_id: diff --git a/tests/test_chat.py b/tests/test_chat.py index a75bc1c0d3b..fd34ccf41e5 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -88,7 +88,7 @@ class Space: has_hidden_members = True -class TestChatNoReq: +class TestChatWithoutRequest: def test_slot_behaviour(self, chat, mro_slots): for attr in chat.__slots__: assert getattr(chat, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_chatadministratorrights.py b/tests/test_chatadministratorrights.py index 54b56563b02..310fe9f4ec0 100644 --- a/tests/test_chatadministratorrights.py +++ b/tests/test_chatadministratorrights.py @@ -39,7 +39,7 @@ def chat_admin_rights(): ) -class TestChatAdministratorRightsNoReq: +class TestChatAdministratorRightsWithoutRequest: def test_slot_behaviour(self, chat_admin_rights, mro_slots): inst = chat_admin_rights for attr in inst.__slots__: diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 7aebda42a3b..275cf266be7 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -55,7 +55,7 @@ class Space: pending_join_request_count = 42 -class TestChatInviteLinkNoReq: +class TestChatInviteLinkWithoutRequest: def test_slot_behaviour(self, mro_slots, invite_link): for attr in invite_link.__slots__: assert getattr(invite_link, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_chatjoinrequest.py b/tests/test_chatjoinrequest.py index eed3278667f..b2048d2195b 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -61,7 +61,7 @@ class Space: ) -class TestChatJoinRequestNoReq: +class TestChatJoinRequestWithoutRequest: def test_slot_behaviour(self, chat_join_request, mro_slots): inst = chat_join_request for attr in inst.__slots__: diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index 12a930d3b1b..422e5074a72 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -32,7 +32,7 @@ class Space: address = "The Shire" -class TestChatLocationNoReq: +class TestChatLocationWithoutRequest: def test_slot_behaviour(self, chat_location, mro_slots): inst = chat_location for attr in inst.__slots__: diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index 51a5a12f4e7..14269eeb154 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -175,7 +175,7 @@ def chat_member_type(request): ], indirect=True, ) -class TestChatMemberTypesNoReq: +class TestChatMemberTypesWithoutRequest: def test_slot_behaviour(self, chat_member_type, mro_slots): inst = chat_member_type for attr in inst.__slots__: diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index d5c55564066..6aaf898f5b2 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -86,7 +86,7 @@ class Space: new_status = ChatMember.ADMINISTRATOR -class TestChatMemberUpdatedNoReq: +class TestChatMemberUpdatedWithoutRequest: def test_slot_behaviour(self, mro_slots, chat_member_updated): action = chat_member_updated for attr in action.__slots__: diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index efa19bdc1dd..eb70028c7ad 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -49,7 +49,7 @@ class Space: can_manage_topics = None -class TestChatPermissionsNoReq: +class TestChatPermissionsWithoutRequest: def test_slot_behaviour(self, chat_permissions, mro_slots): inst = chat_permissions for attr in inst.__slots__: diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index 2279e065e2a..78de123b62d 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -58,7 +58,7 @@ class Space: chatphoto_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.jpg" -class TestChatPhotoNoReq: +class TestChatPhotoWithoutRequest: def test_slot_behaviour(self, chat_photo, mro_slots): for attr in chat_photo.__slots__: assert getattr(chat_photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -152,7 +152,7 @@ async def make_assertion(*_, **kwargs): assert await chat_photo.get_big_file() -class TestChatPhotoReq: +class TestChatPhotoWithRequest: async def test_get_and_download(self, bot, chat_photo): jpg_file = Path("telegram.jpg") if jpg_file.is_file(): diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index a0341a58117..9a2a25e35c6 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -39,7 +39,7 @@ class Space: query = "query text" -class TestChosenInlineResultNoReq: +class TestChosenInlineResultWithoutRequest: def test_slot_behaviour(self, chosen_inline_result, mro_slots): inst = chosen_inline_result for attr in inst.__slots__: diff --git a/tests/test_constants.py b/tests/test_constants.py index 9c5fe745112..bfe4f82f17a 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -35,7 +35,7 @@ class IntEnumTest(IntEnum): BAR = 2 -class TestConstantsNoReq: +class TestConstantsWithoutRequest: """Also test _utils.enum.StringEnum on the fly because tg.constants is currently the only place where that class is used.""" @@ -128,7 +128,7 @@ def test_bot_api_version_info(self): assert vi[1] == vi.minor -class TestConstantsReq: +class TestConstantsWithRequest: async def test_max_message_length(self, bot, chat_id): tasks = asyncio.gather( bot.send_message(chat_id, text="a" * constants.MessageLimit.MAX_TEXT_LENGTH), diff --git a/tests/test_contact.py b/tests/test_contact.py index 074ca170c63..49b317927f2 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -38,7 +38,7 @@ class Space: user_id = 23 -class TestContactNoReq: +class TestContactWithoutRequest: def test_slot_behaviour(self, contact, mro_slots): for attr in contact.__slots__: assert getattr(contact, attr, "err") != "err", f"got extra slot '{attr}'" @@ -121,7 +121,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.send_contact(contact=contact, chat_id=chat_id) -class TestContactReq: +class TestContactWithRequest: @pytest.mark.parametrize( "default_bot,custom", [ diff --git a/tests/test_dice.py b/tests/test_dice.py index a3ffc828263..b621f049b35 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -31,7 +31,7 @@ class Space: value = 4 -class TestDiceNoReq: +class TestDiceWithoutRequest: def test_slot_behaviour(self, dice, mro_slots): for attr in dice.__slots__: assert getattr(dice, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_document.py b/tests/test_document.py index 1e8d8b2d376..15643f35acd 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -59,7 +59,7 @@ class Space: document_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestDocumentNoReq: +class TestDocumentWithoutRequest: def test_slot_behaviour(self, document, mro_slots): for attr in document.__slots__: assert getattr(document, attr, "err") != "err", f"got extra slot '{attr}'" @@ -186,7 +186,7 @@ async def make_assertion(*_, **kwargs): assert await document.get_file() -class TestDocumentReq: +class TestDocumentWithRequest: async def test_error_send_empty_file(self, bot, chat_id): with open(os.devnull, "rb") as f: with pytest.raises(TelegramError): diff --git a/tests/test_encryptedcredentials.py b/tests/test_encryptedcredentials.py index 11b12df09c5..a3f5a6ee59e 100644 --- a/tests/test_encryptedcredentials.py +++ b/tests/test_encryptedcredentials.py @@ -33,7 +33,7 @@ class Space: secret = "secret" -class TestEncryptedCredentialsNoReq: +class TestEncryptedCredentialsWithoutRequest: def test_slot_behaviour(self, encrypted_credentials, mro_slots): inst = encrypted_credentials for attr in inst.__slots__: diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index 7a840e3a7bd..c14c859c3d1 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -49,7 +49,7 @@ class Space: selfie = PassportFile("file_id", 50, 0, 25) -class TestEncryptedPassportElementNoReq: +class TestEncryptedPassportElementWithoutRequest: def test_slot_behaviour(self, encrypted_passport_element, mro_slots): inst = encrypted_passport_element for attr in inst.__slots__: diff --git a/tests/test_file.py b/tests/test_file.py index fc34cb9a01a..a6cfb054c54 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -95,7 +95,7 @@ class Space: file_content = "Saint-Saëns".encode() # Intentionally contains unicode chars. -class TestFileNoReq: +class TestFileWithoutRequest: def test_slot_behaviour(self, file, mro_slots): for attr in file.__slots__: assert getattr(file, attr, "err") != "err", f"got extra slot '{attr}'" @@ -267,7 +267,7 @@ async def test(*args, **kwargs): assert buf2[: len(buf)] == buf -class TestFileReq: +class TestFileWithRequest: async def test_error_get_empty_file_id(self, bot): with pytest.raises(TelegramError): await bot.get_file(file_id="") diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index 67fae9405ef..1e9870558ae 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -33,7 +33,7 @@ class Space: input_field_placeholder = "force replies can be annoying if not used properly" -class TestForceReplyNoReq: +class TestForceReplyWithoutRequest: def test_slot_behaviour(self, force_reply, mro_slots): for attr in force_reply.__slots__: assert getattr(force_reply, attr, "err") != "err", f"got extra slot '{attr}'" @@ -68,7 +68,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestForceReplyReq: +class TestForceReplyWithRequest: async def test_send_message_with_force_reply(self, bot, chat_id, force_reply): message = await bot.send_message(chat_id, "text", reply_markup=force_reply) assert message.text == "text" diff --git a/tests/test_forum.py b/tests/test_forum.py index 2e2d941c688..67001ae6ca8 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -72,7 +72,7 @@ async def real_topic(bot, emoji_id, forum_group_id): assert result is True, "Topic was not deleted" -class TestForumTopicNoReq: +class TestForumTopicWithoutRequest: def test_slot_behaviour(self, mro_slots, forum_topic_object): inst = forum_topic_object for attr in inst.__slots__: @@ -152,7 +152,7 @@ def test_equality(self, emoji_id, forum_group_id): assert hash(a) != hash(e) -class TestForumMethodsReq: +class TestForumMethodsWithRequest: async def test_create_forum_topic(self, real_topic): result = real_topic assert isinstance(result, ForumTopic) @@ -306,7 +306,7 @@ def topic_created(): return ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR) -class TestForumTopicCreatedNoReq: +class TestForumTopicCreatedWithoutRequest: def test_slot_behaviour(self, topic_created, mro_slots): for attr in topic_created.__slots__: assert getattr(topic_created, attr, "err") != "err", f"got extra slot '{attr}'" @@ -355,7 +355,7 @@ def test_equality(self, emoji_id): assert hash(a) != hash(d) -class TestForumTopicClosedNoReq: +class TestForumTopicClosedWithoutRequest: def test_slot_behaviour(self, mro_slots): action = ForumTopicClosed() for attr in action.__slots__: @@ -373,7 +373,7 @@ def test_to_dict(self): assert action_dict == {} -class TestForumTopicReopenedNoReq: +class TestForumTopicReopenedWithoutRequest: def test_slot_behaviour(self, mro_slots): action = ForumTopicReopened() for attr in action.__slots__: diff --git a/tests/test_game.py b/tests/test_game.py index 3192fdbd640..753b35dc888 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -48,7 +48,7 @@ class Space: animation = Animation("blah", "unique_id", 320, 180, 1) -class TestGameNoReq: +class TestGameWithoutRequest: def test_slot_behaviour(self, game, mro_slots): for attr in game.__slots__: assert getattr(game, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py index ba2a9545386..7c14d179883 100644 --- a/tests/test_gamehighscore.py +++ b/tests/test_gamehighscore.py @@ -33,7 +33,7 @@ class Space: score = 42 -class TestGameHighScoreNoReq: +class TestGameHighScoreWithoutRequest: def test_slot_behaviour(self, game_highscore, mro_slots): for attr in game_highscore.__slots__: assert getattr(game_highscore, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index 0a62f7d251a..331bbfe9eee 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -49,7 +49,7 @@ class Space: web_app = WebAppInfo(url="https://example.com") -class TestInlineKeyboardButtonNoReq: +class TestInlineKeyboardButtonWithoutRequest: def test_slot_behaviour(self, inline_keyboard_button, mro_slots): inst = inline_keyboard_button for attr in inst.__slots__: diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index f5c3bfc61c7..344ecfcac32 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -42,7 +42,7 @@ class Space: ] -class TestInlineKeyboardMarkupNoReq: +class TestInlineKeyboardMarkupWithoutRequest: def test_slot_behaviour(self, inline_keyboard_markup, mro_slots): inst = inline_keyboard_markup for attr in inst.__slots__: @@ -225,7 +225,7 @@ async def make_assertion( await bot.send_message(123, "test", reply_markup=inline_keyboard_markup) -class TestInlineKeyborardMarkupReq: +class TestInlineKeyborardMarkupWithRequest: async def test_send_message_with_inline_keyboard_markup( self, bot, chat_id, inline_keyboard_markup ): diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 18ca4b76504..67f86e62627 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -48,7 +48,7 @@ class Space: location = Location(8.8, 53.1) -class TestInlineQueryNoReq: +class TestInlineQueryWithoutRequest: def test_slot_behaviour(self, inline_query, mro_slots): for attr in inline_query.__slots__: assert getattr(inline_query, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index 2d2e485b614..f0d26705dac 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -58,7 +58,7 @@ class Space: thumb_width = 15 -class TestInlineQueryResultArticleNoReq: +class TestInlineQueryResultArticleWithoutRequest: def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): inst = inline_query_result_article for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index dc66062a16e..a1f6c4bebf3 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -59,7 +59,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultAudioNoReq: +class TestInlineQueryResultAudioWithoutRequest: def test_slot_behaviour(self, inline_query_result_audio, mro_slots): inst = inline_query_result_audio for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index 1b56e40cbe4..ec65ea79f88 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -53,7 +53,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedAudioNoReq: +class TestInlineQueryResultCachedAudioWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): inst = inline_query_result_cached_audio for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 562631e30fa..2e9b7c62405 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -57,7 +57,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedDocumentNoReq: +class TestInlineQueryResultCachedDocumentWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): inst = inline_query_result_cached_document for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index 9029e13cdba..376eaeed4e8 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedGifNoReq: +class TestInlineQueryResultCachedGifWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): inst = inline_query_result_cached_gif for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index 99f7104c71f..9be3d166a33 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedMpeg4GifNoReq: +class TestInlineQueryResultCachedMpeg4GifWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): inst = inline_query_result_cached_mpeg4_gif for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 406de176a94..29984f6aea1 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedPhotoNoReq: +class TestInlineQueryResultCachedPhotoWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): inst = inline_query_result_cached_photo for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index 28b786527fb..0415b550fc5 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -45,7 +45,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedStickerNoReq: +class TestInlineQueryResultCachedStickerWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): inst = inline_query_result_cached_sticker for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index 119c0a5e200..ac365539742 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedVideoNoReq: +class TestInlineQueryResultCachedVideoWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): inst = inline_query_result_cached_video for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index cca5e3aaa5e..7b9bdcc7ed9 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedVoiceNoReq: +class TestInlineQueryResultCachedVoiceWithoutRequest: def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): inst = inline_query_result_cached_voice for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index 159c5b73844..17e65b533c6 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -55,7 +55,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultContactNoReq: +class TestInlineQueryResultContactWithoutRequest: def test_slot_behaviour(self, inline_query_result_contact, mro_slots): inst = inline_query_result_contact for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index e465b2a5fba..836748adf40 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultDocumentNoReq: +class TestInlineQueryResultDocumentWithoutRequest: def test_slot_behaviour(self, inline_query_result_document, mro_slots): inst = inline_query_result_document for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py index c32f394be6f..0ca69ba0169 100644 --- a/tests/test_inlinequeryresultgame.py +++ b/tests/test_inlinequeryresultgame.py @@ -42,7 +42,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultGameNoReq: +class TestInlineQueryResultGameWithoutRequest: def test_slot_behaviour(self, inline_query_result_game, mro_slots): inst = inline_query_result_game for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 1d2db594f39..6d3dd7e255e 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultGifNoReq: +class TestInlineQueryResultGifWithoutRequest: def test_slot_behaviour(self, inline_query_result_gif, mro_slots): inst = inline_query_result_gif for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 9fd07f1e66f..4d0eedd3e03 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -63,7 +63,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultLocationNoReq: +class TestInlineQueryResultLocationWithoutRequest: def test_slot_behaviour(self, inline_query_result_location, mro_slots): inst = inline_query_result_location for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 0ba32b66265..7ab728c22b3 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultMpeg4GifNoReq: +class TestInlineQueryResultMpeg4GifWithoutRequest: def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): inst = inline_query_result_mpeg4_gif for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 61fff4e1729..99e02bf2e1f 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -63,7 +63,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultPhotoNoReq: +class TestInlineQueryResultPhotoWithoutRequest: def test_slot_behaviour(self, inline_query_result_photo, mro_slots): inst = inline_query_result_photo for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index de9cebdd00f..fdd5ba907a5 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -65,7 +65,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVenueNoReq: +class TestInlineQueryResultVenueWithoutRequest: def test_slot_behaviour(self, inline_query_result_venue, mro_slots): inst = inline_query_result_venue for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index a0f5daec1dc..23fb1ee65cd 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -66,7 +66,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVideoNoReq: +class TestInlineQueryResultVideoWithoutRequest: def test_slot_behaviour(self, inline_query_result_video, mro_slots): inst = inline_query_result_video for attr in inst.__slots__: diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index 117f2156332..c0ea7837fe0 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVoiceNoReq: +class TestInlineQueryResultVoiceWithoutRequest: def test_slot_behaviour(self, inline_query_result_voice, mro_slots): inst = inline_query_result_voice for attr in inst.__slots__: diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index 70f4d495e92..a4d0ec5f2a7 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -32,7 +32,7 @@ class Space: last_name = "last name" -class TestInputContactMessageContentNoReq: +class TestInputContactMessageContentWithoutRequest: def test_slot_behaviour(self, input_contact_message_content, mro_slots): inst = input_contact_message_content for attr in inst.__slots__: diff --git a/tests/test_inputfile.py b/tests/test_inputfile.py index 7dee831a79c..b215c907f28 100644 --- a/tests/test_inputfile.py +++ b/tests/test_inputfile.py @@ -31,7 +31,7 @@ def png_file(): return data_file("game.png") -class TestInputFileNoReq: +class TestInputFileWithoutRequest: def test_slot_behaviour(self, mro_slots): inst = InputFile(BytesIO(b"blah"), filename="tg.jpg") for attr in inst.__slots__: @@ -140,7 +140,7 @@ def read(self): ) -class TestInputFileReq: +class TestInputFileWithRequest: async def test_send_bytes(self, bot, chat_id): # We test this here and not at the respective test modules because it's not worth # duplicating the test for the different methods diff --git a/tests/test_inputinvoicemessagecontent.py b/tests/test_inputinvoicemessagecontent.py index c1aa3c79ebb..cd464ec58c2 100644 --- a/tests/test_inputinvoicemessagecontent.py +++ b/tests/test_inputinvoicemessagecontent.py @@ -71,7 +71,7 @@ class Space: is_flexible = True -class TestInputInvoiceMessageContentNoReq: +class TestInputInvoiceMessageContentWithoutRequest: def test_slot_behaviour(self, input_invoice_message_content, mro_slots): inst = input_invoice_message_content for attr in inst.__slots__: diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index 5c3d2b61560..2df1a289d2e 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -42,7 +42,7 @@ class Space: proximity_alert_radius = 999 -class TestInputLocationMessageContentNoReq: +class TestInputLocationMessageContentWithoutRequest: def test_slot_behaviour(self, input_location_message_content, mro_slots): inst = input_location_message_content for attr in inst.__slots__: diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index af89b10e06e..caeae0c350e 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -138,7 +138,7 @@ class VideoSpace: has_spoiler = True -class TestInputMediaVideoNoReq: +class TestInputMediaVideoWithoutRequest: def test_slot_behaviour(self, input_media_video, mro_slots): inst = input_media_video for attr in inst.__slots__: @@ -211,7 +211,7 @@ class PhotoSpace: has_spoiler = True -class TestInputMediaPhotoNoReq: +class TestInputMediaPhotoWithoutRequest: def test_slot_behaviour(self, input_media_photo, mro_slots): inst = input_media_photo for attr in inst.__slots__: @@ -272,7 +272,7 @@ class AnimationSpace: has_spoiler = True -class TestInputMediaAnimationNoReq: +class TestInputMediaAnimationWithoutRequest: def test_slot_behaviour(self, input_media_animation, mro_slots): inst = input_media_animation for attr in inst.__slots__: @@ -339,7 +339,7 @@ class AudioSpace: caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] -class TestInputMediaAudioNoReq: +class TestInputMediaAudioWithoutRequest: def test_slot_behaviour(self, input_media_audio, mro_slots): inst = input_media_audio for attr in inst.__slots__: @@ -408,7 +408,7 @@ class DocumentSpace: disable_content_type_detection = True -class TestInputMediaDocumentNoReq: +class TestInputMediaDocumentWithoutRequest: def test_slot_behaviour(self, input_media_document, mro_slots): inst = input_media_document for attr in inst.__slots__: @@ -499,7 +499,7 @@ def media_group_no_caption_only_parse_mode(photo, thumb): # noqa: F811 ] -class TestSendMediaGroupNoReq: +class TestSendMediaGroupWithoutRequest: async def test_send_media_group_throws_error_with_group_caption_and_individual_captions( self, bot, @@ -594,7 +594,7 @@ def __len__(self): return len(self.items) -class TestSendMediaGroupReq: +class TestSendMediaGroupWithRequest: async def test_send_media_group_photo(self, bot, chat_id, media_group): messages = await bot.send_media_group(chat_id, media_group) assert isinstance(messages, tuple) diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 86223df86f0..55f73c3257e 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -39,7 +39,7 @@ class Space: disable_web_page_preview = True -class TestInputTextMessageContentNoReq: +class TestInputTextMessageContentWithoutRequest: def test_slot_behaviour(self, input_text_message_content, mro_slots): inst = input_text_message_content for attr in inst.__slots__: diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index 08c9b2bb4ab..5c46a7698dc 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -46,7 +46,7 @@ class Space: google_place_type = "google place type" -class TestInputVenueMessageContentNoReq: +class TestInputVenueMessageContentWithoutRequest: def test_slot_behaviour(self, input_venue_message_content, mro_slots): inst = input_venue_message_content for attr in inst.__slots__: diff --git a/tests/test_invoice.py b/tests/test_invoice.py index ca27d8c32a6..510a3f1f06a 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -49,7 +49,7 @@ class Space: suggested_tip_amounts = [13, 42] -class TestInvoiceNoReq: +class TestInvoiceWithoutRequest: def test_slot_behaviour(self, invoice, mro_slots): for attr in invoice.__slots__: assert getattr(invoice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -182,7 +182,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestInvoiceReq: +class TestInvoiceWithRequest: async def test_send_required_args_only(self, bot, chat_id, provider_token): send_inv_task = asyncio.create_task( bot.send_invoice( diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index cdf4a98b202..58c86cdff1f 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -40,7 +40,7 @@ class Space: web_app = WebAppInfo(url="https://example.com") -class TestKeyboardButtonNoReq: +class TestKeyboardButtonWithoutRequest: def test_slot_behaviour(self, keyboard_button, mro_slots): inst = keyboard_button for attr in inst.__slots__: diff --git a/tests/test_keyboardbuttonpolltype.py b/tests/test_keyboardbuttonpolltype.py index fe7f7b8e4f4..f9fa3f298d9 100644 --- a/tests/test_keyboardbuttonpolltype.py +++ b/tests/test_keyboardbuttonpolltype.py @@ -30,7 +30,7 @@ class Space: type = Poll.QUIZ -class TestKeyboardButtonPollTypeNoReq: +class TestKeyboardButtonPollTypeWithoutRequest: def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): inst = keyboard_button_poll_type for attr in inst.__slots__: diff --git a/tests/test_labeledprice.py b/tests/test_labeledprice.py index 7b41811faa8..e8492c7ecd9 100644 --- a/tests/test_labeledprice.py +++ b/tests/test_labeledprice.py @@ -31,7 +31,7 @@ class Space: amount = 100 -class TestLabeledPriceNoReq: +class TestLabeledPriceWithoutRequest: def test_slot_behaviour(self, labeled_price, mro_slots): inst = labeled_price for attr in inst.__slots__: diff --git a/tests/test_location.py b/tests/test_location.py index 3f84a91a448..cd8f7d4f8cf 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -46,7 +46,7 @@ class Space: proximity_alert_radius = 50 -class TestLocationNoReq: +class TestLocationWithoutRequest: def test_slot_behaviour(self, location, mro_slots): for attr in location.__slots__: assert getattr(location, attr, "err") != "err", f"got extra slot '{attr}'" @@ -160,7 +160,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.edit_message_live_location(None, None, location=location) -class TestLocationReq: +class TestLocationWithRequest: @pytest.mark.parametrize( "default_bot,custom", [ diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index 889bf047426..7d735b248ea 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -38,7 +38,7 @@ class Space: request_write_access = True -class TestLoginUrlNoReq: +class TestLoginUrlWithoutRequest: def test_slot_behaviour(self, login_url, mro_slots): for attr in login_url.__slots__: assert getattr(login_url, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_menubutton.py b/tests/test_menubutton.py index 73b12cb59e3..e725b4de590 100644 --- a/tests/test_menubutton.py +++ b/tests/test_menubutton.py @@ -95,7 +95,7 @@ class Space: # All the scope types are very similar, so we test everything via parametrization -class TestMenuButtonNoReq: +class TestMenuButtonWithoutRequest: def test_slot_behaviour(self, menu_button, mro_slots): for attr in menu_button.__slots__: assert getattr(menu_button, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_message.py b/tests/test_message.py index 95c016e9c48..debf44eaf9e 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -342,7 +342,7 @@ class Space: ) -class TestMessageNoReq: +class TestMessageWithoutRequest: def test_slot_behaviour(self, message, mro_slots): for attr in message.__slots__: assert getattr(message, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_messageautodeletetimerchanged.py b/tests/test_messageautodeletetimerchanged.py index 6a8923bfd24..31a3ecd67e4 100644 --- a/tests/test_messageautodeletetimerchanged.py +++ b/tests/test_messageautodeletetimerchanged.py @@ -19,7 +19,7 @@ from telegram import MessageAutoDeleteTimerChanged, VideoChatEnded -class TestMessageAutoDeleteTimerChangedNoReq: +class TestMessageAutoDeleteTimerChangedWithoutRequest: message_auto_delete_time = 100 def test_slot_behaviour(self, mro_slots): diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index da5e1714343..49f1c76479e 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -44,7 +44,7 @@ class Space: url = "url" -class TestMessageEntityNoReq: +class TestMessageEntityWithoutRequest: def test_slot_behaviour(self, message_entity, mro_slots): inst = message_entity for attr in inst.__slots__: diff --git a/tests/test_messageid.py b/tests/test_messageid.py index ed614f6de4c..f10250b3def 100644 --- a/tests/test_messageid.py +++ b/tests/test_messageid.py @@ -22,10 +22,10 @@ @pytest.fixture(scope="module") def message_id(): - return MessageId(message_id=TestMessageIdNoReq.m_id) + return MessageId(message_id=TestMessageIdWithoutRequest.m_id) -class TestMessageIdNoReq: +class TestMessageIdWithoutRequest: m_id = 1234 def test_slot_behaviour(self, message_id, mro_slots): diff --git a/tests/test_no_passport.py b/tests/test_no_passport.py index a46f54510f2..9648422dba2 100644 --- a/tests/test_no_passport.py +++ b/tests/test_no_passport.py @@ -36,7 +36,7 @@ @pytest.mark.skipif( TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed" ) -class TestNoPassportNoReq: +class TestNoPassportWithoutRequest: def test_bot_init(self, bot_info): with pytest.raises(RuntimeError, match="passport"): bot.Bot(bot_info["token"], private_key=1, private_key_password=2) diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index bbb84c91bce..3d9ec178d79 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -33,7 +33,7 @@ class Space: shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestOrderInfoNoReq: +class TestOrderInfoWithoutRequest: def test_slot_behaviour(self, order_info, mro_slots): for attr in order_info.__slots__: assert getattr(order_info, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_passport.py b/tests/test_passport.py index 720a370b05a..4bca9536d3d 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -242,7 +242,7 @@ class Space: driver_license_selfie_credentials_secret = "tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E=" -class TestPassportNoReq: +class TestPassportWithoutRequest: def test_slot_behaviour(self, passport_data, mro_slots): inst = passport_data for attr in inst.__slots__: diff --git a/tests/test_passportelementerrordatafield.py b/tests/test_passportelementerrordatafield.py index 2dd8d906d93..4aff2f1cb5f 100644 --- a/tests/test_passportelementerrordatafield.py +++ b/tests/test_passportelementerrordatafield.py @@ -39,7 +39,7 @@ class Space: message = "Error message" -class TestPassportElementErrorDataFieldNoReq: +class TestPassportElementErrorDataFieldWithoutRequest: def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): inst = passport_element_error_data_field for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorfile.py b/tests/test_passportelementerrorfile.py index ff6ca793ccc..cd1a668498a 100644 --- a/tests/test_passportelementerrorfile.py +++ b/tests/test_passportelementerrorfile.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorFileNoReq: +class TestPassportElementErrorFileWithoutRequest: def test_slot_behaviour(self, passport_element_error_file, mro_slots): inst = passport_element_error_file for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorfiles.py b/tests/test_passportelementerrorfiles.py index bda87437219..c43d53a8c79 100644 --- a/tests/test_passportelementerrorfiles.py +++ b/tests/test_passportelementerrorfiles.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorFilesNoReq: +class TestPassportElementErrorFilesWithoutRequest: def test_slot_behaviour(self, passport_element_error_files, mro_slots): inst = passport_element_error_files for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorfrontside.py b/tests/test_passportelementerrorfrontside.py index 10818ec7a01..dd3ec765390 100644 --- a/tests/test_passportelementerrorfrontside.py +++ b/tests/test_passportelementerrorfrontside.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorFrontSideNoReq: +class TestPassportElementErrorFrontSideWithoutRequest: def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): inst = passport_element_error_front_side for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorreverseside.py b/tests/test_passportelementerrorreverseside.py index 514a37d97ec..f239af073b9 100644 --- a/tests/test_passportelementerrorreverseside.py +++ b/tests/test_passportelementerrorreverseside.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorReverseSideNoReq: +class TestPassportElementErrorReverseSideWithoutRequest: def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): inst = passport_element_error_reverse_side for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorselfie.py b/tests/test_passportelementerrorselfie.py index c5e587fcbe4..b8c8c7c4eb3 100644 --- a/tests/test_passportelementerrorselfie.py +++ b/tests/test_passportelementerrorselfie.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorSelfieNoReq: +class TestPassportElementErrorSelfieWithoutRequest: def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): inst = passport_element_error_selfie for attr in inst.__slots__: diff --git a/tests/test_passportelementerrortranslationfile.py b/tests/test_passportelementerrortranslationfile.py index b3b00737bf0..f0aa2c1ee01 100644 --- a/tests/test_passportelementerrortranslationfile.py +++ b/tests/test_passportelementerrortranslationfile.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorTranslationFileNoReq: +class TestPassportElementErrorTranslationFileWithoutRequest: def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots): inst = passport_element_error_translation_file for attr in inst.__slots__: diff --git a/tests/test_passportelementerrortranslationfiles.py b/tests/test_passportelementerrortranslationfiles.py index b67d622eebb..954031b985a 100644 --- a/tests/test_passportelementerrortranslationfiles.py +++ b/tests/test_passportelementerrortranslationfiles.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorTranslationFilesNoReq: +class TestPassportElementErrorTranslationFilesWithoutRequest: def test_slot_behaviour(self, passport_element_error_translation_files, mro_slots): inst = passport_element_error_translation_files for attr in inst.__slots__: diff --git a/tests/test_passportelementerrorunspecified.py b/tests/test_passportelementerrorunspecified.py index e26dccc1655..5b6c106817e 100644 --- a/tests/test_passportelementerrorunspecified.py +++ b/tests/test_passportelementerrorunspecified.py @@ -33,7 +33,7 @@ class Space: message = "Error message" -class TestPassportElementErrorUnspecifiedNoReq: +class TestPassportElementErrorUnspecifiedWithoutRequest: def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): inst = passport_element_error_unspecified for attr in inst.__slots__: diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index 9df07922b51..c49133cc02a 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -45,7 +45,7 @@ class Space: file_date = 1532879128 -class TestPassportFileNoReq: +class TestPassportFileWithoutRequest: def test_slot_behaviour(self, passport_file, mro_slots): inst = passport_file for attr in inst.__slots__: diff --git a/tests/test_photo.py b/tests/test_photo.py index fa5af15891d..bcc5cc05146 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -71,7 +71,7 @@ class Space: file_size = [29176, 27662] -class TestPhotoNoReq: +class TestPhotoWithoutRequest: def test_slot_behaviour(self, photo, mro_slots): for attr in photo.__slots__: assert getattr(photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -206,7 +206,7 @@ async def make_assertion(*_, **kwargs): assert await photo.get_file() -class TestPhotoReq: +class TestPhotoWithRequest: async def test_send_photo_all_args(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, diff --git a/tests/test_poll.py b/tests/test_poll.py index 9691423a742..f7813c141ce 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -36,7 +36,7 @@ class PollOptionSpace: voter_count = 3 -class TestPollOptionNoReq: +class TestPollOptionWithoutRequest: def test_slot_behaviour(self, poll_option, mro_slots): for attr in poll_option.__slots__: assert getattr(poll_option, attr, "err") != "err", f"got extra slot '{attr}'" @@ -88,7 +88,7 @@ class PollAnswerSpace: option_ids = [2] -class TestPollAnswerNoReq: +class TestPollAnswerWithoutRequest: def test_de_json(self): json_dict = { "poll_id": PollAnswerSpace.poll_id, @@ -168,7 +168,7 @@ class PollSpace: close_date = datetime.now(timezone.utc) -class TestPollNoReq: +class TestPollWithoutRequest: def test_de_json(self, bot): json_dict = { "id": PollSpace.id_, diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index f0f4b66112b..124c3584070 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -52,7 +52,7 @@ class Space: order_info = OrderInfo() -class TestPreCheckoutQueryNoReq: +class TestPreCheckoutQueryWithoutRequest: def test_slot_behaviour(self, pre_checkout_query, mro_slots): inst = pre_checkout_query for attr in inst.__slots__: diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index 5e295d398f5..78008c34be2 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -36,7 +36,7 @@ class Space: distance = 42 -class TestProximityAlertTriggeredNoReq: +class TestProximityAlertTriggeredWithoutRequest: def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): inst = proximity_alert_triggered for attr in inst.__slots__: diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 4a814385018..b10b2dbff51 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -41,7 +41,7 @@ class Space: is_persistent = True -class TestReplyKeyboardMarkupNoReq: +class TestReplyKeyboardMarkupWithoutRequest: def test_slot_behaviour(self, reply_keyboard_markup, mro_slots): inst = reply_keyboard_markup for attr in inst.__slots__: @@ -151,7 +151,7 @@ def test_from_column(self): assert len(reply_keyboard_markup[1]) == 1 -class TestReplyKeyboardMarkupReq: +class TestReplyKeyboardMarkupWithRequest: async def test_send_message_with_reply_keyboard_markup( self, bot, chat_id, reply_keyboard_markup ): diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index 51751bc238e..db37015852b 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -31,7 +31,7 @@ class Space: selective = True -class TestReplyKeyboardRemoveNoReq: +class TestReplyKeyboardRemoveWithoutRequest: def test_slot_behaviour(self, reply_keyboard_remove, mro_slots): inst = reply_keyboard_remove for attr in inst.__slots__: @@ -51,7 +51,7 @@ def test_to_dict(self, reply_keyboard_remove): assert reply_keyboard_remove_dict["selective"] == reply_keyboard_remove.selective -class TestReplyKeyboardRemoveReq: +class TestReplyKeyboardRemoveWithRequest: async def test_send_message_with_reply_keyboard_remove( self, bot, chat_id, reply_keyboard_remove ): diff --git a/tests/test_request.py b/tests/test_request.py index 5e3885a4cfa..66f9d4e017a 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -80,7 +80,7 @@ async def test_init(self, bot): HTTPXRequest(proxy_url="socks5://foo") -class TestRequestNoReq: +class TestRequestWithoutRequest: test_flag = None @pytest.fixture(autouse=True) @@ -321,7 +321,7 @@ async def make_assertion(*args, **kwargs): assert self.test_flag == (1, 2, 3, 4) -class TestHTTPXRequestNoReq: +class TestHTTPXRequestWithoutRequest: test_flag = None @pytest.fixture(autouse=True) @@ -564,7 +564,7 @@ async def request(_, **kwargs): ) -class TestHTTPXRequestReq: +class TestHTTPXRequestWithRequest: async def test_do_request_wait_for_pool(self, httpx_request): """The pool logic is buried rather deeply in httpxcore, so we make actual requests here instead of mocking""" diff --git a/tests/test_requestdata.py b/tests/test_requestdata.py index 386931149a1..ad45e063e36 100644 --- a/tests/test_requestdata.py +++ b/tests/test_requestdata.py @@ -129,7 +129,7 @@ def mixed_rqs(mixed_params) -> RequestData: ) -class TestRequestDataNoReq: +class TestRequestDataWithoutRequest: def test_slot_behaviour(self, simple_rqs, mro_slots): for attr in simple_rqs.__slots__: assert getattr(simple_rqs, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_requestparameter.py b/tests/test_requestparameter.py index ab3028a8223..12c55c007e1 100644 --- a/tests/test_requestparameter.py +++ b/tests/test_requestparameter.py @@ -27,7 +27,7 @@ from tests.conftest import data_file -class TestRequestParameterNoReq: +class TestRequestParameterWithoutRequest: def test_slot_behaviour(self, mro_slots): inst = RequestParameter("name", "value", [1, 2]) for attr in inst.__slots__: diff --git a/tests/test_sentwebappmessage.py b/tests/test_sentwebappmessage.py index ab5975b49b3..dae0f0bfabd 100644 --- a/tests/test_sentwebappmessage.py +++ b/tests/test_sentwebappmessage.py @@ -31,7 +31,7 @@ class Space: inline_message_id = "123" -class TestSentWebAppMessageNoReq: +class TestSentWebAppMessageWithoutRequest: def test_slot_behaviour(self, sent_web_app_message, mro_slots): inst = sent_web_app_message for attr in inst.__slots__: diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 8d4a527b1be..4d4a9bcdd29 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -42,7 +42,7 @@ class Space: post_code = "WC1" -class TestShippingAddressNoReq: +class TestShippingAddressWithoutRequest: def test_slot_behaviour(self, shipping_address, mro_slots): inst = shipping_address for attr in inst.__slots__: diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 099faba2155..16e059b8515 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -32,7 +32,7 @@ class Space: prices = [LabeledPrice("Fish Container", 100), LabeledPrice("Premium Fish Container", 1000)] -class TestShippingOptionNoReq: +class TestShippingOptionWithoutRequest: def test_slot_behaviour(self, shipping_option, mro_slots): inst = shipping_option for attr in inst.__slots__: diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index 81f80ecaa0b..a5df651724a 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -41,7 +41,7 @@ class Space: shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestShippingQueryNoReq: +class TestShippingQueryWithoutRequest: def test_slot_behaviour(self, shipping_query, mro_slots): inst = shipping_query for attr in inst.__slots__: diff --git a/tests/test_sticker.py b/tests/test_sticker.py index f843bf9031c..ec61fbf1fd4 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -95,7 +95,7 @@ class StickerSpace: premium_animation = File("this_is_an_id", "this_is_an_unique_id") -class TestStickerNoReq: +class TestStickerWithoutRequest: def test_slot_behaviour(self, sticker, mro_slots): for attr in sticker.__slots__: assert getattr(sticker, attr, "err") != "err", f"got extra slot '{attr}'" @@ -264,7 +264,7 @@ async def make_assertion(_, data, *args, **kwargs): bot._local_mode = False -class TestStickerReq: +class TestStickerWithRequest: async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): message = await bot.send_sticker( chat_id, sticker=sticker_file, disable_notification=False, protect_content=True @@ -501,7 +501,7 @@ class SetSpace: contains_masks = True -class TestStickerSetNoReq: +class TestStickerSetWithoutRequest: def test_slot_behaviour(self, mro_slots): inst = StickerSet("this", "is", True, SetSpace.stickers, True, "not") for attr in inst.__slots__: @@ -732,7 +732,7 @@ async def make_assertion(*_, **kwargs): @pytest.mark.xdist_group("stickerset") -class TestStickerSetReq: +class TestStickerSetWithRequest: async def test_create_sticker_set( self, bot, chat_id, sticker_file, animated_sticker_file, video_sticker_file ): @@ -882,7 +882,7 @@ class MaskSpace: scale = 2 -class TestMaskPositionNoReq: +class TestMaskPositionWithoutRequest: def test_slot_behaviour(self, mask_position, mro_slots): inst = mask_position for attr in inst.__slots__: diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index b77b2a464bf..64dc53600e5 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -44,7 +44,7 @@ class Space: provider_payment_charge_id = "provider_payment_charge_id" -class TestSuccessfulPaymentNoReq: +class TestSuccessfulPaymentWithoutRequest: def test_slot_behaviour(self, successful_payment, mro_slots): inst = successful_payment for attr in inst.__slots__: diff --git a/tests/test_update.py b/tests/test_update.py index 3f4e7efdcb2..24a3b257dcf 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -105,7 +105,7 @@ class Space: update_id = 868573637 -class TestUpdateNoReq: +class TestUpdateWithoutRequest: def test_slot_behaviour(self, mro_slots): update = Update(Space.update_id) for attr in update.__slots__: diff --git a/tests/test_updater.py b/tests/test_updater.py index b33e5787e87..35fbd866504 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -529,7 +529,7 @@ async def test_webhook_basic( # that depends on this distinction works if ext_bot and not isinstance(updater.bot, ExtBot): updater.bot = ExtBot(updater.bot.token) - if not ext_bot and not type(updater.bot) is Bot: + if not ext_bot and type(updater.bot) is not Bot: updater.bot = DictBot(updater.bot.token) async def delete_webhook(*args, **kwargs): diff --git a/tests/test_user.py b/tests/test_user.py index c50f6611426..5b9831c3afc 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -78,7 +78,7 @@ class Space: added_to_attachment_menu = False -class TestUserNoReq: +class TestUserWithoutRequest: def test_slot_behaviour(self, user, mro_slots): for attr in user.__slots__: assert getattr(user, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index 86c32b9ab29..7eea9912da7 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -33,7 +33,7 @@ class Space: ] -class TestUserProfilePhotosNoReq: +class TestUserProfilePhotosWithoutRequest: def test_slot_behaviour(self, mro_slots): inst = UserProfilePhotos(Space.total_count, Space.photos) for attr in inst.__slots__: diff --git a/tests/test_venue.py b/tests/test_venue.py index bc01d43f1a7..55c9e7138ef 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -48,7 +48,7 @@ class Space: google_place_type = "google place type" -class TestVenueNoReq: +class TestVenueWithoutRequest: def test_slot_behaviour(self, venue, mro_slots): for attr in venue.__slots__: assert getattr(venue, attr, "err") != "err", f"got extra slot '{attr}'" @@ -141,7 +141,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert message -class TestVenueReq: +class TestVenueWithRequest: @pytest.mark.parametrize( "default_bot,custom", [ diff --git a/tests/test_video.py b/tests/test_video.py index cfc8eeae4fa..55ae4780594 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -63,7 +63,7 @@ class Space: video_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoNoReq: +class TestVideoWithoutRequest: def test_slot_behaviour(self, video, mro_slots): for attr in video.__slots__: assert getattr(video, attr, "err") != "err", f"got extra slot '{attr}'" @@ -201,7 +201,7 @@ async def make_assertion(*_, **kwargs): assert await video.get_file() -class TestVideoReq: +class TestVideoWithRequest: async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): message = await bot.send_video( chat_id, diff --git a/tests/test_videochat.py b/tests/test_videochat.py index d4237385b7f..8ebd2136e35 100644 --- a/tests/test_videochat.py +++ b/tests/test_videochat.py @@ -40,7 +40,7 @@ def user2(): return User(first_name="Mister Test", id=124, is_bot=False) -class TestVideoChatStartedNoReq: +class TestVideoChatStartedWithoutRequest: def test_slot_behaviour(self, mro_slots): action = VideoChatStarted() for attr in action.__slots__: @@ -58,7 +58,7 @@ def test_to_dict(self): assert video_chat_dict == {} -class TestVideoChatEndedNoReq: +class TestVideoChatEndedWithoutRequest: duration = 100 def test_slot_behaviour(self, mro_slots): @@ -97,7 +97,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestVideoChatParticipantsInvitedNoReq: +class TestVideoChatParticipantsInvitedWithoutRequest: def test_slot_behaviour(self, mro_slots, user1): action = VideoChatParticipantsInvited([user1]) for attr in action.__slots__: @@ -148,7 +148,7 @@ def test_equality(self, user1, user2): assert hash(a) != hash(e) -class TestVideoChatScheduledNoReq: +class TestVideoChatScheduledWithoutRequest: start_date = dtm.datetime.now(dtm.timezone.utc) def test_slot_behaviour(self, mro_slots): diff --git a/tests/test_videonote.py b/tests/test_videonote.py index 9f16b6a45f6..16835a8727a 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -57,7 +57,7 @@ class Space: videonote_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoNoteNoReq: +class TestVideoNoteWithoutRequest: def test_slot_behaviour(self, video_note, mro_slots): for attr in video_note.__slots__: assert getattr(video_note, attr, "err") != "err", f"got extra slot '{attr}'" @@ -188,7 +188,7 @@ async def make_assertion(*_, **kwargs): assert await video_note.get_file() -class TestVideoNoteReq: +class TestVideoNoteWithRequest: async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): message = await bot.send_video_note( chat_id, diff --git a/tests/test_voice.py b/tests/test_voice.py index 53ed6f01383..934b2d7cc54 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -56,7 +56,7 @@ class Space: voice_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVoiceNoReq: +class TestVoiceWithoutRequest: def test_slot_behaviour(self, voice, mro_slots): for attr in voice.__slots__: assert getattr(voice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -175,7 +175,7 @@ async def make_assertion(*_, **kwargs): assert await voice.get_file() -class TestVoiceReq: +class TestVoiceWithRequest: async def test_send_all_args(self, bot, chat_id, voice_file, voice): message = await bot.send_voice( chat_id, diff --git a/tests/test_webappdata.py b/tests/test_webappdata.py index 175f5190ec2..d822723e717 100644 --- a/tests/test_webappdata.py +++ b/tests/test_webappdata.py @@ -32,7 +32,7 @@ class Space: button_text = "button_text" -class TestWebAppDataNoReq: +class TestWebAppDataWithoutRequest: def test_slot_behaviour(self, web_app_data, mro_slots): for attr in web_app_data.__slots__: assert getattr(web_app_data, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_webappinfo.py b/tests/test_webappinfo.py index 1b87eaa2b87..cec25822d93 100644 --- a/tests/test_webappinfo.py +++ b/tests/test_webappinfo.py @@ -31,7 +31,7 @@ class Space: url = "https://www.example.com" -class TestWebAppInfoNoReq: +class TestWebAppInfoWithoutRequest: def test_slot_behaviour(self, web_app_info, mro_slots): for attr in web_app_info.__slots__: assert getattr(web_app_info, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index a4a8cf583c6..c93f362273e 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -50,7 +50,7 @@ class Space: last_synchronization_error_date = time.time() -class TestWebhookInfoNoReq: +class TestWebhookInfoWithoutRequest: def test_slot_behaviour(self, webhook_info, mro_slots): for attr in webhook_info.__slots__: assert getattr(webhook_info, attr, "err") != "err", f"got extra slot '{attr}'" From 6aa539ff363b5dac25e26fb9151220115e0f0c80 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Thu, 12 Jan 2023 22:18:20 +0530 Subject: [PATCH 52/77] make tz_bot fixture use default_bots dictionary as cache instead --- tests/conftest.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 79dbaeaf783..59f7f729e7a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -240,17 +240,15 @@ async def default_bot(request, bot_info): return default_bot -tz_bots = {} - - @pytest.fixture(scope="session") async def tz_bot(timezone, bot_info): + defaults = Defaults(tzinfo=timezone) try: # If the bot is already created, return it. Saves time since get_me is not called again. - return tz_bots[timezone] + return default_bots[defaults] except KeyError: - default_bot = make_bot(bot_info, defaults=Defaults(tzinfo=timezone)) + default_bot = make_bot(bot_info, defaults=defaults) await default_bot.initialize() - tz_bots[timezone] = default_bot + default_bots[defaults] = default_bot return default_bot From 0588363512cdf6919d68b1d2e995043cb8a803bc Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Jan 2023 01:23:53 +0530 Subject: [PATCH 53/77] Address review of fc5aea4: Change Space to suggested name instead --- tests/test_animation.py | 68 +++--- tests/test_audio.py | 84 +++---- tests/test_callbackquery.py | 54 ++--- tests/test_chat.py | 138 +++++------ tests/test_chatinvitelink.py | 82 +++---- tests/test_chatjoinrequest.py | 38 +-- tests/test_chatlocation.py | 20 +- tests/test_chatmemberupdated.py | 8 +- tests/test_chatpermissions.py | 40 ++-- tests/test_chatphoto.py | 40 ++-- tests/test_choseninlineresult.py | 30 +-- tests/test_contact.py | 43 ++-- tests/test_dice.py | 8 +- tests/test_document.py | 48 ++-- tests/test_encryptedcredentials.py | 26 +- tests/test_encryptedpassportelement.py | 46 ++-- tests/test_file.py | 83 ++++--- tests/test_forcereply.py | 14 +- tests/test_game.py | 52 ++-- tests/test_gamehighscore.py | 20 +- tests/test_inlinekeyboardbutton.py | 72 +++--- tests/test_inlinekeyboardmarkup.py | 12 +- tests/test_inlinequery.py | 42 ++-- tests/test_inlinequeryresultarticle.py | 56 ++--- tests/test_inlinequeryresultaudio.py | 58 ++--- tests/test_inlinequeryresultcachedaudio.py | 46 ++-- tests/test_inlinequeryresultcacheddocument.py | 56 +++-- tests/test_inlinequeryresultcachedgif.py | 52 ++-- tests/test_inlinequeryresultcachedmpeg4gif.py | 50 ++-- tests/test_inlinequeryresultcachedphoto.py | 54 ++--- tests/test_inlinequeryresultcachedsticker.py | 32 +-- tests/test_inlinequeryresultcachedvideo.py | 54 ++--- tests/test_inlinequeryresultcachedvoice.py | 50 ++-- tests/test_inlinequeryresultcontact.py | 52 ++-- tests/test_inlinequeryresultdocument.py | 72 +++--- tests/test_inlinequeryresultgame.py | 28 +-- tests/test_inlinequeryresultgif.py | 70 +++--- tests/test_inlinequeryresultlocation.py | 68 +++--- tests/test_inlinequeryresultmpeg4gif.py | 70 +++--- tests/test_inlinequeryresultphoto.py | 66 +++--- tests/test_inlinequeryresultvenue.py | 72 +++--- tests/test_inlinequeryresultvideo.py | 76 +++--- tests/test_inlinequeryresultvoice.py | 58 ++--- tests/test_inputcontactmessagecontent.py | 16 +- tests/test_inputinvoicemessagecontent.py | 222 +++++++++--------- tests/test_inputlocationmessagecontent.py | 30 ++- tests/test_inputmedia.py | 190 +++++++-------- tests/test_inputtextmessagecontent.py | 22 +- tests/test_inputvenuemessagecontent.py | 36 +-- tests/test_invoice.py | 136 +++++------ tests/test_keyboardbutton.py | 44 ++-- tests/test_keyboardbuttonpolltype.py | 8 +- tests/test_labeledprice.py | 10 +- tests/test_location.py | 46 ++-- tests/test_loginurl.py | 30 ++- tests/test_menubutton.py | 20 +- tests/test_message.py | 138 +++++------ tests/test_messageentity.py | 12 +- tests/test_orderinfo.py | 27 ++- tests/test_passport.py | 64 ++--- tests/test_passportelementerrordatafield.py | 36 +-- tests/test_passportelementerrorfile.py | 30 ++- tests/test_passportelementerrorfiles.py | 30 ++- tests/test_passportelementerrorfrontside.py | 30 ++- tests/test_passportelementerrorreverseside.py | 30 ++- tests/test_passportelementerrorselfie.py | 30 ++- ...est_passportelementerrortranslationfile.py | 32 ++- ...st_passportelementerrortranslationfiles.py | 32 ++- tests/test_passportelementerrorunspecified.py | 30 ++- tests/test_passportfile.py | 28 +-- tests/test_photo.py | 48 ++-- tests/test_poll.py | 124 +++++----- tests/test_precheckoutquery.py | 54 ++--- tests/test_proximityalerttriggered.py | 26 +- tests/test_replykeyboardmarkup.py | 24 +- tests/test_replykeyboardremove.py | 12 +- tests/test_sentwebappmessage.py | 16 +- tests/test_shippingaddress.py | 92 ++++---- tests/test_shippingoption.py | 24 +- tests/test_shippingquery.py | 41 ++-- tests/test_sticker.py | 217 ++++++++--------- tests/test_successfulpayment.py | 74 +++--- tests/test_update.py | 20 +- tests/test_user.py | 82 +++---- tests/test_userprofilephotos.py | 20 +- tests/test_venue.py | 74 +++--- tests/test_video.py | 80 +++---- tests/test_videonote.py | 52 ++-- tests/test_voice.py | 48 ++-- tests/test_webappdata.py | 20 +- tests/test_webappinfo.py | 16 +- tests/test_webhookinfo.py | 88 +++---- 92 files changed, 2437 insertions(+), 2382 deletions(-) diff --git a/tests/test_animation.py b/tests/test_animation.py index dd8143d00fe..b093f6ca790 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -48,7 +48,7 @@ async def animation(bot, chat_id): ).animation -class Space: +class TestAnimationBase: animation_file_id = "CgADAQADngIAAuyVeEez0xRovKi9VAI" animation_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" width = 320 @@ -63,7 +63,7 @@ class Space: caption = "Test *animation*" -class TestAnimationWithoutRequest: +class TestAnimationWithoutRequest(TestAnimationBase): def test_slot_behaviour(self, animation, mro_slots): for attr in animation.__slots__: assert getattr(animation, attr, "err") != "err", f"got extra slot '{attr}'" @@ -77,29 +77,29 @@ def test_creation(self, animation): assert animation.file_unique_id != "" def test_expected_values(self, animation): - assert animation.mime_type == Space.mime_type - assert animation.file_name.startswith("game.gif") == Space.file_name.startswith("game.gif") + assert animation.mime_type == self.mime_type + assert animation.file_name.startswith("game.gif") == self.file_name.startswith("game.gif") assert isinstance(animation.thumb, PhotoSize) def test_de_json(self, bot, animation): json_dict = { - "file_id": Space.animation_file_id, - "file_unique_id": Space.animation_file_unique_id, - "width": Space.width, - "height": Space.height, - "duration": Space.duration, + "file_id": self.animation_file_id, + "file_unique_id": self.animation_file_unique_id, + "width": self.width, + "height": self.height, + "duration": self.duration, "thumb": animation.thumb.to_dict(), - "file_name": Space.file_name, - "mime_type": Space.mime_type, - "file_size": Space.file_size, + "file_name": self.file_name, + "mime_type": self.mime_type, + "file_size": self.file_size, } animation = Animation.de_json(json_dict, bot) assert animation.api_kwargs == {} - assert animation.file_id == Space.animation_file_id - assert animation.file_unique_id == Space.animation_file_unique_id - assert animation.file_name == Space.file_name - assert animation.mime_type == Space.mime_type - assert animation.file_size == Space.file_size + assert animation.file_id == self.animation_file_id + assert animation.file_unique_id == self.animation_file_unique_id + assert animation.file_name == self.file_name + assert animation.mime_type == self.mime_type + assert animation.file_size == self.file_size def test_to_dict(self, animation): animation_dict = animation.to_dict() @@ -117,17 +117,15 @@ def test_to_dict(self, animation): def test_equality(self): a = Animation( - Space.animation_file_id, - Space.animation_file_unique_id, - Space.height, - Space.width, - Space.duration, - ) - b = Animation( - "", Space.animation_file_unique_id, Space.height, Space.width, Space.duration + self.animation_file_id, + self.animation_file_unique_id, + self.height, + self.width, + self.duration, ) + b = Animation("", self.animation_file_unique_id, self.height, self.width, self.duration) d = Animation("", "", 0, 0, 0) - e = Voice(Space.animation_file_id, Space.animation_file_unique_id, 0) + e = Voice(self.animation_file_id, self.animation_file_unique_id, 0) assert a == b assert hash(a) == hash(b) @@ -189,15 +187,15 @@ async def make_assertion(*_, **kwargs): assert await animation.get_file() -class TestAnimationWithRequest: +class TestAnimationWithRequest(TestAnimationBase): async def test_send_all_args(self, bot, chat_id, animation_file, animation, thumb_file): message = await bot.send_animation( chat_id, animation_file, - duration=Space.duration, - width=Space.width, - height=Space.height, - caption=Space.caption, + duration=self.duration, + width=self.width, + height=self.height, + caption=self.caption, parse_mode="Markdown", disable_notification=False, protect_content=True, @@ -213,8 +211,8 @@ async def test_send_all_args(self, bot, chat_id, animation_file, animation, thum assert message.animation.file_name == animation.file_name assert message.animation.mime_type == animation.mime_type assert message.animation.file_size == animation.file_size - assert message.animation.thumb.width == Space.width - assert message.animation.thumb.height == Space.height + assert message.animation.thumb.width == self.width + assert message.animation.thumb.height == self.height assert message.has_protected_content try: assert message.has_media_spoiler @@ -236,10 +234,10 @@ async def test_get_and_download(self, bot, animation): async def test_send_animation_url_file(self, bot, chat_id, animation): message = await bot.send_animation( - chat_id=chat_id, animation=Space.animation_file_url, caption=Space.caption + chat_id=chat_id, animation=self.animation_file_url, caption=self.caption ) - assert message.caption == Space.caption + assert message.caption == self.caption assert isinstance(message.animation, Animation) assert isinstance(message.animation.file_id, str) diff --git a/tests/test_audio.py b/tests/test_audio.py index fd0ac52ca20..e2a4e62f6d1 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -46,7 +46,7 @@ async def audio(bot, chat_id): return (await bot.send_audio(chat_id, audio=f, read_timeout=50, thumb=thumb)).audio -class Space: +class TestAudioBase: caption = "Test *audio*" performer = "Leandro Toledo" title = "Teste" @@ -64,7 +64,7 @@ class Space: audio_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestAudioWithoutRequest: +class TestAudioWithoutRequest(TestAudioBase): def test_slot_behaviour(self, audio, mro_slots): for attr in audio.__slots__: assert getattr(audio, attr, "err") != "err", f"got extra slot '{attr}'" @@ -79,38 +79,38 @@ def test_creation(self, audio): assert audio.file_unique_id != "" def test_expected_values(self, audio): - assert audio.duration == Space.duration + assert audio.duration == self.duration assert audio.performer is None assert audio.title is None - assert audio.mime_type == Space.mime_type - assert audio.file_size == Space.file_size - assert audio.thumb.file_size == Space.thumb_file_size - assert audio.thumb.width == Space.thumb_width - assert audio.thumb.height == Space.thumb_height + assert audio.mime_type == self.mime_type + assert audio.file_size == self.file_size + assert audio.thumb.file_size == self.thumb_file_size + assert audio.thumb.width == self.thumb_width + assert audio.thumb.height == self.thumb_height def test_de_json(self, bot, audio): json_dict = { - "file_id": Space.audio_file_id, - "file_unique_id": Space.audio_file_unique_id, - "duration": Space.duration, - "performer": Space.performer, - "title": Space.title, - "file_name": Space.file_name, - "mime_type": Space.mime_type, - "file_size": Space.file_size, + "file_id": self.audio_file_id, + "file_unique_id": self.audio_file_unique_id, + "duration": self.duration, + "performer": self.performer, + "title": self.title, + "file_name": self.file_name, + "mime_type": self.mime_type, + "file_size": self.file_size, "thumb": audio.thumb.to_dict(), } json_audio = Audio.de_json(json_dict, bot) assert json_audio.api_kwargs == {} - assert json_audio.file_id == Space.audio_file_id - assert json_audio.file_unique_id == Space.audio_file_unique_id - assert json_audio.duration == Space.duration - assert json_audio.performer == Space.performer - assert json_audio.title == Space.title - assert json_audio.file_name == Space.file_name - assert json_audio.mime_type == Space.mime_type - assert json_audio.file_size == Space.file_size + assert json_audio.file_id == self.audio_file_id + assert json_audio.file_unique_id == self.audio_file_unique_id + assert json_audio.duration == self.duration + assert json_audio.performer == self.performer + assert json_audio.title == self.title + assert json_audio.file_name == self.file_name + assert json_audio.mime_type == self.mime_type + assert json_audio.file_size == self.file_size assert json_audio.thumb == audio.thumb def test_to_dict(self, audio): @@ -194,37 +194,37 @@ async def make_assertion(*_, **kwargs): assert await audio.get_file() -class TestAudioWithRequest: +class TestAudioWithRequest(TestAudioBase): async def test_send_all_args(self, bot, chat_id, audio_file, thumb_file): message = await bot.send_audio( chat_id, audio=audio_file, - caption=Space.caption, - duration=Space.duration, - performer=Space.performer, - title=Space.title, + caption=self.caption, + duration=self.duration, + performer=self.performer, + title=self.title, disable_notification=False, protect_content=True, parse_mode="Markdown", thumb=thumb_file, ) - assert message.caption == Space.caption.replace("*", "") + assert message.caption == self.caption.replace("*", "") assert isinstance(message.audio, Audio) assert isinstance(message.audio.file_id, str) assert isinstance(message.audio.file_unique_id, str) assert message.audio.file_unique_id is not None assert message.audio.file_id is not None - assert message.audio.duration == Space.duration - assert message.audio.performer == Space.performer - assert message.audio.title == Space.title - assert message.audio.file_name == Space.file_name - assert message.audio.mime_type == Space.mime_type - assert message.audio.file_size == Space.file_size - assert message.audio.thumb.file_size == Space.thumb_file_size - assert message.audio.thumb.width == Space.thumb_width - assert message.audio.thumb.height == Space.thumb_height + assert message.audio.duration == self.duration + assert message.audio.performer == self.performer + assert message.audio.title == self.title + assert message.audio.file_name == self.file_name + assert message.audio.mime_type == self.mime_type + assert message.audio.file_size == self.file_size + assert message.audio.thumb.file_size == self.thumb_file_size + assert message.audio.thumb.width == self.thumb_width + assert message.audio.thumb.height == self.thumb_height assert message.has_protected_content async def test_get_and_download(self, bot, chat_id, audio): @@ -235,7 +235,7 @@ async def test_get_and_download(self, bot, chat_id, audio): audio = (await bot.send_audio(chat_id, audio.file_id, read_timeout=50)).audio new_file = await bot.get_file(audio.file_id) - assert new_file.file_size == Space.file_size + assert new_file.file_size == self.file_size assert new_file.file_id == audio.file_id assert new_file.file_unique_id == audio.file_unique_id assert str(new_file.file_path).startswith("https://") @@ -245,10 +245,10 @@ async def test_get_and_download(self, bot, chat_id, audio): async def test_send_mp3_url_file(self, bot, chat_id, audio): message = await bot.send_audio( - chat_id=chat_id, audio=Space.audio_file_url, caption=Space.caption + chat_id=chat_id, audio=self.audio_file_url, caption=self.caption ) - assert message.caption == Space.caption + assert message.caption == self.caption assert isinstance(message.audio, Audio) assert isinstance(message.audio.file_id, str) diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index c3fe5c61eb2..f13b6c6f378 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -32,23 +32,23 @@ @pytest.fixture(scope="function", params=["message", "inline"]) def callback_query(bot, request): cbq = CallbackQuery( - Space.id_, - Space.from_user, - Space.chat_instance, - data=Space.data, - game_short_name=Space.game_short_name, + TestCallbackQueryBase.id_, + TestCallbackQueryBase.from_user, + TestCallbackQueryBase.chat_instance, + data=TestCallbackQueryBase.data, + game_short_name=TestCallbackQueryBase.game_short_name, ) cbq.set_bot(bot) cbq._unfreeze() if request.param == "message": - cbq.message = Space.message + cbq.message = TestCallbackQueryBase.message cbq.message.set_bot(bot) else: - cbq.inline_message_id = Space.inline_message_id + cbq.inline_message_id = TestCallbackQueryBase.inline_message_id return cbq -class Space: +class TestCallbackQueryBase: id_ = "id" from_user = User(1, "test_user", False) chat_instance = "chat_instance" @@ -58,7 +58,7 @@ class Space: game_short_name = "the_game" -class TestCallbackQueryWithoutRequest: +class TestCallbackQueryWithoutRequest(TestCallbackQueryBase): @staticmethod def skip_params(callback_query: CallbackQuery): if callback_query.inline_message_id: @@ -90,24 +90,24 @@ def test_slot_behaviour(self, callback_query, mro_slots): def test_de_json(self, bot): json_dict = { - "id": Space.id_, - "from": Space.from_user.to_dict(), - "chat_instance": Space.chat_instance, - "message": Space.message.to_dict(), - "data": Space.data, - "inline_message_id": Space.inline_message_id, - "game_short_name": Space.game_short_name, + "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.api_kwargs == {} - assert callback_query.id == Space.id_ - assert callback_query.from_user == Space.from_user - assert callback_query.chat_instance == Space.chat_instance - assert callback_query.message == Space.message - assert callback_query.data == Space.data - assert callback_query.inline_message_id == Space.inline_message_id - assert callback_query.game_short_name == Space.game_short_name + 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() @@ -124,11 +124,11 @@ def test_to_dict(self, callback_query): assert callback_query_dict["game_short_name"] == callback_query.game_short_name def test_equality(self): - a = CallbackQuery(Space.id_, Space.from_user, "chat") - b = CallbackQuery(Space.id_, Space.from_user, "chat") - c = CallbackQuery(Space.id_, None, "") + 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(Space.id_, "unique_id", 1) + e = Audio(self.id_, "unique_id", 1) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_chat.py b/tests/test_chat.py index fd34ccf41e5..e60ea3ea131 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -32,34 +32,34 @@ @pytest.fixture(scope="module") def chat(bot): chat = Chat( - Space.id_, - title=Space.title, - type=Space.type_, - username=Space.username, - sticker_set_name=Space.sticker_set_name, - can_set_sticker_set=Space.can_set_sticker_set, - permissions=Space.permissions, - slow_mode_delay=Space.slow_mode_delay, - bio=Space.bio, - linked_chat_id=Space.linked_chat_id, - location=Space.location, + TestChatBase.id_, + title=TestChatBase.title, + type=TestChatBase.type_, + username=TestChatBase.username, + sticker_set_name=TestChatBase.sticker_set_name, + can_set_sticker_set=TestChatBase.can_set_sticker_set, + permissions=TestChatBase.permissions, + slow_mode_delay=TestChatBase.slow_mode_delay, + bio=TestChatBase.bio, + linked_chat_id=TestChatBase.linked_chat_id, + location=TestChatBase.location, has_private_forwards=True, has_protected_content=True, join_to_send_messages=True, join_by_request=True, has_restricted_voice_and_video_messages=True, is_forum=True, - active_usernames=Space.active_usernames, - emoji_status_custom_emoji_id=Space.emoji_status_custom_emoji_id, - has_aggressive_anti_spam_enabled=Space.has_aggressive_anti_spam_enabled, - has_hidden_members=Space.has_hidden_members, + active_usernames=TestChatBase.active_usernames, + emoji_status_custom_emoji_id=TestChatBase.emoji_status_custom_emoji_id, + has_aggressive_anti_spam_enabled=TestChatBase.has_aggressive_anti_spam_enabled, + has_hidden_members=TestChatBase.has_hidden_members, ) chat.set_bot(bot) chat._unfreeze() return chat -class Space: +class TestChatBase: id_ = -28767330 title = "ToledosPalaceBot - Group" type_ = "group" @@ -88,7 +88,7 @@ class Space: has_hidden_members = True -class TestChatWithoutRequest: +class TestChatWithoutRequest(TestChatBase): def test_slot_behaviour(self, chat, mro_slots): for attr in chat.__slots__: assert getattr(chat, attr, "err") != "err", f"got extra slot '{attr}'" @@ -96,61 +96,61 @@ def test_slot_behaviour(self, chat, mro_slots): def test_de_json(self, bot): json_dict = { - "id": Space.id_, - "title": Space.title, - "type": Space.type_, - "username": Space.username, - "all_members_are_administrators": Space.all_members_are_administrators, - "sticker_set_name": Space.sticker_set_name, - "can_set_sticker_set": Space.can_set_sticker_set, - "permissions": Space.permissions.to_dict(), - "slow_mode_delay": Space.slow_mode_delay, - "bio": Space.bio, - "has_protected_content": Space.has_protected_content, - "has_private_forwards": Space.has_private_forwards, - "linked_chat_id": Space.linked_chat_id, - "location": Space.location.to_dict(), - "join_to_send_messages": Space.join_to_send_messages, - "join_by_request": Space.join_by_request, + "id": self.id_, + "title": self.title, + "type": self.type_, + "username": self.username, + "all_members_are_administrators": self.all_members_are_administrators, + "sticker_set_name": self.sticker_set_name, + "can_set_sticker_set": self.can_set_sticker_set, + "permissions": self.permissions.to_dict(), + "slow_mode_delay": self.slow_mode_delay, + "bio": self.bio, + "has_protected_content": self.has_protected_content, + "has_private_forwards": self.has_private_forwards, + "linked_chat_id": self.linked_chat_id, + "location": self.location.to_dict(), + "join_to_send_messages": self.join_to_send_messages, + "join_by_request": self.join_by_request, "has_restricted_voice_and_video_messages": ( - Space.has_restricted_voice_and_video_messages + self.has_restricted_voice_and_video_messages ), - "is_forum": Space.is_forum, - "active_usernames": Space.active_usernames, - "emoji_status_custom_emoji_id": Space.emoji_status_custom_emoji_id, - "has_aggressive_anti_spam_enabled": Space.has_aggressive_anti_spam_enabled, - "has_hidden_members": Space.has_hidden_members, + "is_forum": self.is_forum, + "active_usernames": self.active_usernames, + "emoji_status_custom_emoji_id": self.emoji_status_custom_emoji_id, + "has_aggressive_anti_spam_enabled": self.has_aggressive_anti_spam_enabled, + "has_hidden_members": self.has_hidden_members, } chat = Chat.de_json(json_dict, bot) - assert chat.id == Space.id_ - assert chat.title == Space.title - assert chat.type == Space.type_ - assert chat.username == Space.username - assert chat.sticker_set_name == Space.sticker_set_name - assert chat.can_set_sticker_set == Space.can_set_sticker_set - assert chat.permissions == Space.permissions - assert chat.slow_mode_delay == Space.slow_mode_delay - assert chat.bio == Space.bio - assert chat.has_protected_content == Space.has_protected_content - assert chat.has_private_forwards == Space.has_private_forwards - assert chat.linked_chat_id == Space.linked_chat_id - assert chat.location.location == Space.location.location - assert chat.location.address == Space.location.address - assert chat.join_to_send_messages == Space.join_to_send_messages - assert chat.join_by_request == Space.join_by_request + assert chat.id == self.id_ + assert chat.title == self.title + assert chat.type == self.type_ + assert chat.username == self.username + assert chat.sticker_set_name == self.sticker_set_name + assert chat.can_set_sticker_set == self.can_set_sticker_set + assert chat.permissions == self.permissions + assert chat.slow_mode_delay == self.slow_mode_delay + assert chat.bio == self.bio + assert chat.has_protected_content == self.has_protected_content + assert chat.has_private_forwards == self.has_private_forwards + assert chat.linked_chat_id == self.linked_chat_id + assert chat.location.location == self.location.location + assert chat.location.address == self.location.address + assert chat.join_to_send_messages == self.join_to_send_messages + assert chat.join_by_request == self.join_by_request assert ( chat.has_restricted_voice_and_video_messages - == Space.has_restricted_voice_and_video_messages + == self.has_restricted_voice_and_video_messages ) assert chat.api_kwargs == { - "all_members_are_administrators": Space.all_members_are_administrators + "all_members_are_administrators": self.all_members_are_administrators } - assert chat.is_forum == Space.is_forum - assert chat.active_usernames == tuple(Space.active_usernames) - assert chat.emoji_status_custom_emoji_id == Space.emoji_status_custom_emoji_id - assert chat.has_aggressive_anti_spam_enabled == Space.has_aggressive_anti_spam_enabled - assert chat.has_hidden_members == Space.has_hidden_members + assert chat.is_forum == self.is_forum + assert chat.active_usernames == tuple(self.active_usernames) + assert chat.emoji_status_custom_emoji_id == self.emoji_status_custom_emoji_id + assert chat.has_aggressive_anti_spam_enabled == self.has_aggressive_anti_spam_enabled + assert chat.has_hidden_members == self.has_hidden_members def test_to_dict(self, chat): chat_dict = chat.to_dict() @@ -197,11 +197,11 @@ def test_enum_init(self): assert chat.type is ChatType.PRIVATE def test_equality(self): - a = Chat(Space.id_, Space.title, Space.type_) - b = Chat(Space.id_, Space.title, Space.type_) - c = Chat(Space.id_, "", "") - d = Chat(0, Space.title, Space.type_) - e = User(Space.id_, "", False) + 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_, "", False) assert a == b assert hash(a) == hash(b) @@ -446,7 +446,7 @@ async def make_assertion(*_, **kwargs): async def test_set_permissions(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): chat_id = kwargs["chat_id"] == chat.id - permissions = kwargs["permissions"] == Space.permissions + permissions = kwargs["permissions"] == self.permissions return chat_id and permissions assert check_shortcut_signature( @@ -458,7 +458,7 @@ async def make_assertion(*_, **kwargs): assert await check_defaults_handling(chat.set_permissions, chat.get_bot()) monkeypatch.setattr(chat.get_bot(), "set_chat_permissions", make_assertion) - assert await chat.set_permissions(permissions=Space.permissions) + assert await chat.set_permissions(permissions=self.permissions) async def test_set_administrator_custom_title(self, monkeypatch, chat): async def make_assertion(*_, **kwargs): diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 275cf266be7..66d9ed4dd95 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -32,19 +32,19 @@ def creator(): @pytest.fixture(scope="module") def invite_link(creator): return ChatInviteLink( - Space.link, + TestChatInviteLinkBase.link, creator, - Space.creates_join_request, - Space.primary, - Space.revoked, - expire_date=Space.expire_date, - member_limit=Space.member_limit, - name=Space.name, - pending_join_request_count=Space.pending_join_request_count, + TestChatInviteLinkBase.creates_join_request, + TestChatInviteLinkBase.primary, + TestChatInviteLinkBase.revoked, + expire_date=TestChatInviteLinkBase.expire_date, + member_limit=TestChatInviteLinkBase.member_limit, + name=TestChatInviteLinkBase.name, + pending_join_request_count=TestChatInviteLinkBase.pending_join_request_count, ) -class Space: +class TestChatInviteLinkBase: link = "thisialink" creates_join_request = False primary = True @@ -55,7 +55,7 @@ class Space: pending_join_request_count = 42 -class TestChatInviteLinkWithoutRequest: +class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase): def test_slot_behaviour(self, mro_slots, invite_link): for attr in invite_link.__slots__: assert getattr(invite_link, attr, "err") != "err", f"got extra slot '{attr}'" @@ -63,48 +63,48 @@ def test_slot_behaviour(self, mro_slots, invite_link): def test_de_json_required_args(self, bot, creator): json_dict = { - "invite_link": Space.link, + "invite_link": self.link, "creator": creator.to_dict(), - "creates_join_request": Space.creates_join_request, - "is_primary": Space.primary, - "is_revoked": Space.revoked, + "creates_join_request": self.creates_join_request, + "is_primary": self.primary, + "is_revoked": self.revoked, } invite_link = ChatInviteLink.de_json(json_dict, bot) assert invite_link.api_kwargs == {} - assert invite_link.invite_link == Space.link + assert invite_link.invite_link == self.link assert invite_link.creator == creator - assert invite_link.creates_join_request == Space.creates_join_request - assert invite_link.is_primary == Space.primary - assert invite_link.is_revoked == Space.revoked + assert invite_link.creates_join_request == self.creates_join_request + assert invite_link.is_primary == self.primary + assert invite_link.is_revoked == self.revoked def test_de_json_all_args(self, bot, creator): json_dict = { - "invite_link": Space.link, + "invite_link": self.link, "creator": creator.to_dict(), - "creates_join_request": Space.creates_join_request, - "is_primary": Space.primary, - "is_revoked": Space.revoked, - "expire_date": to_timestamp(Space.expire_date), - "member_limit": Space.member_limit, - "name": Space.name, - "pending_join_request_count": str(Space.pending_join_request_count), + "creates_join_request": self.creates_join_request, + "is_primary": self.primary, + "is_revoked": self.revoked, + "expire_date": to_timestamp(self.expire_date), + "member_limit": self.member_limit, + "name": self.name, + "pending_join_request_count": str(self.pending_join_request_count), } invite_link = ChatInviteLink.de_json(json_dict, bot) assert invite_link.api_kwargs == {} - assert invite_link.invite_link == Space.link + assert invite_link.invite_link == self.link assert invite_link.creator == creator - assert invite_link.creates_join_request == Space.creates_join_request - assert invite_link.is_primary == Space.primary - assert invite_link.is_revoked == Space.revoked - assert abs(invite_link.expire_date - Space.expire_date) < datetime.timedelta(seconds=1) - assert to_timestamp(invite_link.expire_date) == to_timestamp(Space.expire_date) - assert invite_link.member_limit == Space.member_limit - assert invite_link.name == Space.name - assert invite_link.pending_join_request_count == Space.pending_join_request_count + assert invite_link.creates_join_request == self.creates_join_request + assert invite_link.is_primary == self.primary + assert invite_link.is_revoked == self.revoked + assert abs(invite_link.expire_date - self.expire_date) < datetime.timedelta(seconds=1) + assert to_timestamp(invite_link.expire_date) == to_timestamp(self.expire_date) + assert invite_link.member_limit == self.member_limit + assert invite_link.name == self.name + assert invite_link.pending_join_request_count == self.pending_join_request_count def test_to_dict(self, invite_link): invite_link_dict = invite_link.to_dict() @@ -112,12 +112,12 @@ def test_to_dict(self, invite_link): assert invite_link_dict["creator"] == invite_link.creator.to_dict() assert invite_link_dict["invite_link"] == invite_link.invite_link assert invite_link_dict["creates_join_request"] == invite_link.creates_join_request - assert invite_link_dict["is_primary"] == Space.primary - assert invite_link_dict["is_revoked"] == Space.revoked - assert invite_link_dict["expire_date"] == to_timestamp(Space.expire_date) - assert invite_link_dict["member_limit"] == Space.member_limit - assert invite_link_dict["name"] == Space.name - assert invite_link_dict["pending_join_request_count"] == Space.pending_join_request_count + assert invite_link_dict["is_primary"] == self.primary + assert invite_link_dict["is_revoked"] == self.revoked + assert invite_link_dict["expire_date"] == to_timestamp(self.expire_date) + assert invite_link_dict["member_limit"] == self.member_limit + assert invite_link_dict["name"] == self.name + assert invite_link_dict["pending_join_request_count"] == self.pending_join_request_count def test_equality(self): a = ChatInviteLink("link", User(1, "", False), True, True, True) diff --git a/tests/test_chatjoinrequest.py b/tests/test_chatjoinrequest.py index b2048d2195b..c34d2935b92 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -37,17 +37,17 @@ def time(): @pytest.fixture(scope="module") def chat_join_request(bot, time): cjr = ChatJoinRequest( - chat=Space.chat, - from_user=Space.from_user, + chat=TestChatJoinRequestBase.chat, + from_user=TestChatJoinRequestBase.from_user, date=time, - bio=Space.bio, - invite_link=Space.invite_link, + bio=TestChatJoinRequestBase.bio, + invite_link=TestChatJoinRequestBase.invite_link, ) cjr.set_bot(bot) return cjr -class Space: +class TestChatJoinRequestBase: chat = Chat(1, Chat.SUPERGROUP) from_user = User(2, "first_name", False) bio = "bio" @@ -61,7 +61,7 @@ class Space: ) -class TestChatJoinRequestWithoutRequest: +class TestChatJoinRequestWithoutRequest(TestChatJoinRequestBase): def test_slot_behaviour(self, chat_join_request, mro_slots): inst = chat_join_request for attr in inst.__slots__: @@ -70,28 +70,28 @@ def test_slot_behaviour(self, chat_join_request, mro_slots): def test_de_json(self, bot, time): json_dict = { - "chat": Space.chat.to_dict(), - "from": Space.from_user.to_dict(), + "chat": self.chat.to_dict(), + "from": self.from_user.to_dict(), "date": to_timestamp(time), } chat_join_request = ChatJoinRequest.de_json(json_dict, bot) assert chat_join_request.api_kwargs == {} - assert chat_join_request.chat == Space.chat - assert chat_join_request.from_user == Space.from_user + assert chat_join_request.chat == self.chat + assert chat_join_request.from_user == self.from_user assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1) assert to_timestamp(chat_join_request.date) == to_timestamp(time) - json_dict.update({"bio": Space.bio, "invite_link": Space.invite_link.to_dict()}) + json_dict.update({"bio": self.bio, "invite_link": self.invite_link.to_dict()}) chat_join_request = ChatJoinRequest.de_json(json_dict, bot) assert chat_join_request.api_kwargs == {} - assert chat_join_request.chat == Space.chat - assert chat_join_request.from_user == Space.from_user + assert chat_join_request.chat == self.chat + assert chat_join_request.from_user == self.from_user assert abs(chat_join_request.date - time) < datetime.timedelta(seconds=1) assert to_timestamp(chat_join_request.date) == to_timestamp(time) - assert chat_join_request.bio == Space.bio - assert chat_join_request.invite_link == Space.invite_link + assert chat_join_request.bio == self.bio + assert chat_join_request.invite_link == self.invite_link def test_to_dict(self, chat_join_request, time): chat_join_request_dict = chat_join_request.to_dict() @@ -105,10 +105,10 @@ def test_to_dict(self, chat_join_request, time): def test_equality(self, chat_join_request, time): a = chat_join_request - b = ChatJoinRequest(Space.chat, Space.from_user, time) - c = ChatJoinRequest(Space.chat, Space.from_user, time, bio="bio") - d = ChatJoinRequest(Space.chat, Space.from_user, time + datetime.timedelta(1)) - e = ChatJoinRequest(Space.chat, User(-1, "last_name", True), time) + b = ChatJoinRequest(self.chat, self.from_user, time) + c = ChatJoinRequest(self.chat, self.from_user, time, bio="bio") + d = ChatJoinRequest(self.chat, self.from_user, time + datetime.timedelta(1)) + e = ChatJoinRequest(self.chat, User(-1, "last_name", True), time) f = User(456, "", False) assert a == b diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index 422e5074a72..391e41297aa 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def chat_location(): - return ChatLocation(Space.location, Space.address) + return ChatLocation(TestChatLocationBase.location, TestChatLocationBase.address) -class Space: +class TestChatLocationBase: location = Location(123, 456) address = "The Shire" -class TestChatLocationWithoutRequest: +class TestChatLocationWithoutRequest(TestChatLocationBase): def test_slot_behaviour(self, chat_location, mro_slots): inst = chat_location for attr in inst.__slots__: @@ -41,14 +41,14 @@ def test_slot_behaviour(self, chat_location, mro_slots): def test_de_json(self, bot): json_dict = { - "location": Space.location.to_dict(), - "address": Space.address, + "location": self.location.to_dict(), + "address": self.address, } chat_location = ChatLocation.de_json(json_dict, bot) assert chat_location.api_kwargs == {} - assert chat_location.location == Space.location - assert chat_location.address == Space.address + assert chat_location.location == self.location + assert chat_location.address == self.address def test_to_dict(self, chat_location): chat_location_dict = chat_location.to_dict() @@ -59,9 +59,9 @@ def test_to_dict(self, chat_location): def test_equality(self, chat_location): a = chat_location - b = ChatLocation(Space.location, Space.address) - c = ChatLocation(Space.location, "Mordor") - d = ChatLocation(Location(456, 132), Space.address) + b = ChatLocation(self.location, self.address) + c = ChatLocation(self.location, "Mordor") + d = ChatLocation(Location(456, 132), self.address) e = User(456, "", False) assert a == b diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index 6aaf898f5b2..4045d4090ee 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -46,14 +46,14 @@ def chat(): @pytest.fixture(scope="module") def old_chat_member(user): - return ChatMember(user, Space.old_status) + return ChatMember(user, TestChatMemberUpdatedBase.old_status) @pytest.fixture(scope="module") def new_chat_member(user): return ChatMemberAdministrator( user, - Space.new_status, + TestChatMemberUpdatedBase.new_status, True, True, True, @@ -81,12 +81,12 @@ def chat_member_updated(user, chat, old_chat_member, new_chat_member, invite_lin return ChatMemberUpdated(chat, user, time, old_chat_member, new_chat_member, invite_link) -class Space: +class TestChatMemberUpdatedBase: old_status = ChatMember.MEMBER new_status = ChatMember.ADMINISTRATOR -class TestChatMemberUpdatedWithoutRequest: +class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase): def test_slot_behaviour(self, mro_slots, chat_member_updated): action = chat_member_updated for attr in action.__slots__: diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index eb70028c7ad..6f6355f6979 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -37,7 +37,7 @@ def chat_permissions(): ) -class Space: +class TestChatPermissionsBase: can_send_messages = True can_send_media_messages = True can_send_polls = True @@ -49,7 +49,7 @@ class Space: can_manage_topics = None -class TestChatPermissionsWithoutRequest: +class TestChatPermissionsWithoutRequest(TestChatPermissionsBase): def test_slot_behaviour(self, chat_permissions, mro_slots): inst = chat_permissions for attr in inst.__slots__: @@ -58,28 +58,28 @@ def test_slot_behaviour(self, chat_permissions, mro_slots): def test_de_json(self, bot): json_dict = { - "can_send_messages": Space.can_send_messages, - "can_send_media_messages": Space.can_send_media_messages, - "can_send_polls": Space.can_send_polls, - "can_send_other_messages": Space.can_send_other_messages, - "can_add_web_page_previews": Space.can_add_web_page_previews, - "can_change_info": Space.can_change_info, - "can_invite_users": Space.can_invite_users, - "can_pin_messages": Space.can_pin_messages, - "can_manage_topics": Space.can_manage_topics, + "can_send_messages": self.can_send_messages, + "can_send_media_messages": self.can_send_media_messages, + "can_send_polls": self.can_send_polls, + "can_send_other_messages": self.can_send_other_messages, + "can_add_web_page_previews": self.can_add_web_page_previews, + "can_change_info": self.can_change_info, + "can_invite_users": self.can_invite_users, + "can_pin_messages": self.can_pin_messages, + "can_manage_topics": self.can_manage_topics, } permissions = ChatPermissions.de_json(json_dict, bot) assert permissions.api_kwargs == {} - assert permissions.can_send_messages == Space.can_send_messages - assert permissions.can_send_media_messages == Space.can_send_media_messages - assert permissions.can_send_polls == Space.can_send_polls - assert permissions.can_send_other_messages == Space.can_send_other_messages - assert permissions.can_add_web_page_previews == Space.can_add_web_page_previews - assert permissions.can_change_info == Space.can_change_info - assert permissions.can_invite_users == Space.can_invite_users - assert permissions.can_pin_messages == Space.can_pin_messages - assert permissions.can_manage_topics == Space.can_manage_topics + assert permissions.can_send_messages == self.can_send_messages + assert permissions.can_send_media_messages == self.can_send_media_messages + assert permissions.can_send_polls == self.can_send_polls + assert permissions.can_send_other_messages == self.can_send_other_messages + assert permissions.can_add_web_page_previews == self.can_add_web_page_previews + assert permissions.can_change_info == self.can_change_info + assert permissions.can_invite_users == self.can_invite_users + assert permissions.can_pin_messages == self.can_pin_messages + assert permissions.can_manage_topics == self.can_manage_topics def test_to_dict(self, chat_permissions): permissions_dict = chat_permissions.to_dict() diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index 78de123b62d..ed1410fce73 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -50,7 +50,7 @@ async def func(): ) -class Space: +class TestChatPhotoBase: chatphoto_small_file_id = "smallCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_big_file_id = "bigCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_small_file_unique_id = "smalladc3145fd2e84d95b64d68eaa22aa33e" @@ -58,7 +58,7 @@ class Space: chatphoto_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.jpg" -class TestChatPhotoWithoutRequest: +class TestChatPhotoWithoutRequest(TestChatPhotoBase): def test_slot_behaviour(self, chat_photo, mro_slots): for attr in chat_photo.__slots__: assert getattr(chat_photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -66,17 +66,17 @@ def test_slot_behaviour(self, chat_photo, mro_slots): def test_de_json(self, bot, chat_photo): json_dict = { - "small_file_id": Space.chatphoto_small_file_id, - "big_file_id": Space.chatphoto_big_file_id, - "small_file_unique_id": Space.chatphoto_small_file_unique_id, - "big_file_unique_id": Space.chatphoto_big_file_unique_id, + "small_file_id": self.chatphoto_small_file_id, + "big_file_id": self.chatphoto_big_file_id, + "small_file_unique_id": self.chatphoto_small_file_unique_id, + "big_file_unique_id": self.chatphoto_big_file_unique_id, } chat_photo = ChatPhoto.de_json(json_dict, bot) assert chat_photo.api_kwargs == {} - assert chat_photo.small_file_id == Space.chatphoto_small_file_id - assert chat_photo.big_file_id == Space.chatphoto_big_file_id - assert chat_photo.small_file_unique_id == Space.chatphoto_small_file_unique_id - assert chat_photo.big_file_unique_id == Space.chatphoto_big_file_unique_id + assert chat_photo.small_file_id == self.chatphoto_small_file_id + assert chat_photo.big_file_id == self.chatphoto_big_file_id + assert chat_photo.small_file_unique_id == self.chatphoto_small_file_unique_id + assert chat_photo.big_file_unique_id == self.chatphoto_big_file_unique_id async def test_to_dict(self, chat_photo): chat_photo_dict = chat_photo.to_dict() @@ -89,22 +89,22 @@ async def test_to_dict(self, chat_photo): def test_equality(self): a = ChatPhoto( - Space.chatphoto_small_file_id, - Space.chatphoto_big_file_id, - Space.chatphoto_small_file_unique_id, - Space.chatphoto_big_file_unique_id, + self.chatphoto_small_file_id, + self.chatphoto_big_file_id, + self.chatphoto_small_file_unique_id, + self.chatphoto_big_file_unique_id, ) b = ChatPhoto( - Space.chatphoto_small_file_id, - Space.chatphoto_big_file_id, - Space.chatphoto_small_file_unique_id, - Space.chatphoto_big_file_unique_id, + self.chatphoto_small_file_id, + self.chatphoto_big_file_id, + self.chatphoto_small_file_unique_id, + self.chatphoto_big_file_unique_id, ) c = ChatPhoto( - "", "", Space.chatphoto_small_file_unique_id, Space.chatphoto_big_file_unique_id + "", "", self.chatphoto_small_file_unique_id, self.chatphoto_big_file_unique_id ) d = ChatPhoto("", "", 0, 0) - e = Voice(Space.chatphoto_small_file_id, Space.chatphoto_small_file_unique_id, 0) + e = Voice(self.chatphoto_small_file_id, self.chatphoto_small_file_unique_id, 0) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 9a2a25e35c6..dc9ea7ca174 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -31,15 +31,17 @@ def user(): @pytest.fixture(scope="module") def chosen_inline_result(user): - return ChosenInlineResult(Space.result_id, user, Space.query) + return ChosenInlineResult( + TestChosenInlineResultBase.result_id, user, TestChosenInlineResultBase.query + ) -class Space: +class TestChosenInlineResultBase: result_id = "result id" query = "query text" -class TestChosenInlineResultWithoutRequest: +class TestChosenInlineResultWithoutRequest(TestChosenInlineResultBase): def test_slot_behaviour(self, chosen_inline_result, mro_slots): inst = chosen_inline_result for attr in inst.__slots__: @@ -47,29 +49,29 @@ def test_slot_behaviour(self, chosen_inline_result, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json_required(self, bot, user): - json_dict = {"result_id": Space.result_id, "from": user.to_dict(), "query": Space.query} + json_dict = {"result_id": self.result_id, "from": user.to_dict(), "query": self.query} result = ChosenInlineResult.de_json(json_dict, bot) assert result.api_kwargs == {} - assert result.result_id == Space.result_id + assert result.result_id == self.result_id assert result.from_user == user - assert result.query == Space.query + assert result.query == self.query def test_de_json_all(self, bot, user): loc = Location(-42.003, 34.004) json_dict = { - "result_id": Space.result_id, + "result_id": self.result_id, "from": user.to_dict(), - "query": Space.query, + "query": self.query, "location": loc.to_dict(), "inline_message_id": "a random id", } result = ChosenInlineResult.de_json(json_dict, bot) assert result.api_kwargs == {} - assert result.result_id == Space.result_id + assert result.result_id == self.result_id assert result.from_user == user - assert result.query == Space.query + assert result.query == self.query assert result.location == loc assert result.inline_message_id == "a random id" @@ -82,11 +84,11 @@ def test_to_dict(self, chosen_inline_result): assert chosen_inline_result_dict["query"] == chosen_inline_result.query def test_equality(self, user): - a = ChosenInlineResult(Space.result_id, user, "Query", "") - b = ChosenInlineResult(Space.result_id, user, "Query", "") - c = ChosenInlineResult(Space.result_id, 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(Space.result_id, "unique_id", 0) + e = Voice(self.result_id, "unique_id", 0) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_contact.py b/tests/test_contact.py index 49b317927f2..9160474efd9 100644 --- a/tests/test_contact.py +++ b/tests/test_contact.py @@ -28,44 +28,49 @@ @pytest.fixture(scope="module") def contact(): - return Contact(Space.phone_number, Space.first_name, Space.last_name, Space.user_id) + return Contact( + TestContactBase.phone_number, + TestContactBase.first_name, + TestContactBase.last_name, + TestContactBase.user_id, + ) -class Space: +class TestContactBase: phone_number = "+11234567890" first_name = "Leandro" last_name = "Toledo" user_id = 23 -class TestContactWithoutRequest: +class TestContactWithoutRequest(TestContactBase): def test_slot_behaviour(self, contact, mro_slots): for attr in contact.__slots__: assert getattr(contact, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(contact)) == len(set(mro_slots(contact))), "duplicate slot" def test_de_json_required(self, bot): - json_dict = {"phone_number": Space.phone_number, "first_name": Space.first_name} + json_dict = {"phone_number": self.phone_number, "first_name": self.first_name} contact = Contact.de_json(json_dict, bot) assert contact.api_kwargs == {} - assert contact.phone_number == Space.phone_number - assert contact.first_name == Space.first_name + assert contact.phone_number == self.phone_number + assert contact.first_name == self.first_name def test_de_json_all(self, bot): json_dict = { - "phone_number": Space.phone_number, - "first_name": Space.first_name, - "last_name": Space.last_name, - "user_id": Space.user_id, + "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) assert contact.api_kwargs == {} - assert contact.phone_number == Space.phone_number - assert contact.first_name == Space.first_name - assert contact.last_name == Space.last_name - assert contact.user_id == Space.user_id + 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_to_dict(self, contact): contact_dict = contact.to_dict() @@ -77,10 +82,10 @@ def test_to_dict(self, contact): assert contact_dict["user_id"] == contact.user_id def test_equality(self): - a = Contact(Space.phone_number, Space.first_name) - b = Contact(Space.phone_number, Space.first_name) - c = Contact(Space.phone_number, "") - d = Contact("", Space.first_name) + 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("", "unique_id", 0) assert a == b @@ -121,7 +126,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.send_contact(contact=contact, chat_id=chat_id) -class TestContactWithRequest: +class TestContactWithRequest(TestContactBase): @pytest.mark.parametrize( "default_bot,custom", [ diff --git a/tests/test_dice.py b/tests/test_dice.py index b621f049b35..182b3276c97 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -27,11 +27,11 @@ def dice(request): return Dice(value=5, emoji=request.param) -class Space: +class TestDiceBase: value = 4 -class TestDiceWithoutRequest: +class TestDiceWithoutRequest(TestDiceBase): def test_slot_behaviour(self, dice, mro_slots): for attr in dice.__slots__: assert getattr(dice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -39,11 +39,11 @@ def test_slot_behaviour(self, dice, mro_slots): @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI) def test_de_json(self, bot, emoji): - json_dict = {"value": Space.value, "emoji": emoji} + json_dict = {"value": self.value, "emoji": emoji} dice = Dice.de_json(json_dict, bot) assert dice.api_kwargs == {} - assert dice.value == Space.value + assert dice.value == self.value assert dice.emoji == emoji assert Dice.de_json(None, bot) is None diff --git a/tests/test_document.py b/tests/test_document.py index 15643f35acd..40764ea68c7 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -46,7 +46,7 @@ async def document(bot, chat_id): return (await bot.send_document(chat_id, document=f, read_timeout=50)).document -class Space: +class TestDocumentBase: caption = "DocumentTest - *Caption*" document_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.gif" file_size = 12948 @@ -59,7 +59,7 @@ class Space: document_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestDocumentWithoutRequest: +class TestDocumentWithoutRequest(TestDocumentBase): def test_slot_behaviour(self, document, mro_slots): for attr in document.__slots__: assert getattr(document, attr, "err") != "err", f"got extra slot '{attr}'" @@ -73,31 +73,31 @@ def test_creation(self, document): assert document.file_unique_id != "" def test_expected_values(self, document): - assert document.file_size == Space.file_size - assert document.mime_type == Space.mime_type - assert document.file_name == Space.file_name - assert document.thumb.file_size == Space.thumb_file_size - assert document.thumb.width == Space.thumb_width - assert document.thumb.height == Space.thumb_height + 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_height def test_de_json(self, bot, document): json_dict = { - "file_id": Space.document_file_id, - "file_unique_id": Space.document_file_unique_id, + "file_id": self.document_file_id, + "file_unique_id": self.document_file_unique_id, "thumb": document.thumb.to_dict(), - "file_name": Space.file_name, - "mime_type": Space.mime_type, - "file_size": Space.file_size, + "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.api_kwargs == {} - assert test_document.file_id == Space.document_file_id - assert test_document.file_unique_id == Space.document_file_unique_id + assert test_document.file_id == self.document_file_id + assert test_document.file_unique_id == self.document_file_unique_id assert test_document.thumb == document.thumb - assert test_document.file_name == Space.file_name - assert test_document.mime_type == Space.mime_type - assert test_document.file_size == Space.file_size + 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() @@ -186,7 +186,7 @@ async def make_assertion(*_, **kwargs): assert await document.get_file() -class TestDocumentWithRequest: +class TestDocumentWithRequest(TestDocumentBase): async def test_error_send_empty_file(self, bot, chat_id): with open(os.devnull, "rb") as f: with pytest.raises(TelegramError): @@ -221,7 +221,7 @@ async def test_send_all_args(self, bot, chat_id, document_file, document, thumb_ message = await bot.send_document( chat_id, document=document_file, - caption=Space.caption, + caption=self.caption, disable_notification=False, protect_content=True, filename="telegram_custom.png", @@ -238,13 +238,13 @@ async def test_send_all_args(self, bot, chat_id, document_file, document, thumb_ 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.caption == Space.caption.replace("*", "") - assert message.document.thumb.width == Space.thumb_width - assert message.document.thumb.height == Space.thumb_height + assert message.caption == self.caption.replace("*", "") + assert message.document.thumb.width == self.thumb_width + assert message.document.thumb.height == self.thumb_height assert message.has_protected_content async def test_send_url_gif_file(self, bot, chat_id): - message = await bot.send_document(chat_id, Space.document_file_url) + message = await bot.send_document(chat_id, self.document_file_url) document = message.document diff --git a/tests/test_encryptedcredentials.py b/tests/test_encryptedcredentials.py index a3f5a6ee59e..ad934545825 100644 --- a/tests/test_encryptedcredentials.py +++ b/tests/test_encryptedcredentials.py @@ -24,16 +24,20 @@ @pytest.fixture(scope="module") def encrypted_credentials(): - return EncryptedCredentials(Space.data, Space.hash, Space.secret) + return EncryptedCredentials( + TestEncryptedCredentialsBase.data, + TestEncryptedCredentialsBase.hash, + TestEncryptedCredentialsBase.secret, + ) -class Space: +class TestEncryptedCredentialsBase: data = "data" hash = "hash" secret = "secret" -class TestEncryptedCredentialsWithoutRequest: +class TestEncryptedCredentialsWithoutRequest(TestEncryptedCredentialsBase): def test_slot_behaviour(self, encrypted_credentials, mro_slots): inst = encrypted_credentials for attr in inst.__slots__: @@ -41,9 +45,9 @@ def test_slot_behaviour(self, encrypted_credentials, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, encrypted_credentials): - assert encrypted_credentials.data == Space.data - assert encrypted_credentials.hash == Space.hash - assert encrypted_credentials.secret == Space.secret + assert encrypted_credentials.data == self.data + assert encrypted_credentials.hash == self.hash + assert encrypted_credentials.secret == self.secret def test_to_dict(self, encrypted_credentials): encrypted_credentials_dict = encrypted_credentials.to_dict() @@ -54,11 +58,11 @@ def test_to_dict(self, encrypted_credentials): assert encrypted_credentials_dict["secret"] == encrypted_credentials.secret def test_equality(self): - a = EncryptedCredentials(Space.data, Space.hash, Space.secret) - b = EncryptedCredentials(Space.data, Space.hash, Space.secret) - c = EncryptedCredentials(Space.data, "", "") - d = EncryptedCredentials("", Space.hash, "") - e = EncryptedCredentials("", "", Space.secret) + a = EncryptedCredentials(self.data, self.hash, self.secret) + b = EncryptedCredentials(self.data, self.hash, self.secret) + c = EncryptedCredentials(self.data, "", "") + d = EncryptedCredentials("", self.hash, "") + e = EncryptedCredentials("", "", self.secret) f = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_encryptedpassportelement.py b/tests/test_encryptedpassportelement.py index c14c859c3d1..a4f938e9fd5 100644 --- a/tests/test_encryptedpassportelement.py +++ b/tests/test_encryptedpassportelement.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="module") def encrypted_passport_element(): return EncryptedPassportElement( - Space.type_, + TestEncryptedPassportElementBase.type_, "this is a hash", - data=Space.data, - phone_number=Space.phone_number, - email=Space.email, - files=Space.files, - front_side=Space.front_side, - reverse_side=Space.reverse_side, - selfie=Space.selfie, + data=TestEncryptedPassportElementBase.data, + phone_number=TestEncryptedPassportElementBase.phone_number, + email=TestEncryptedPassportElementBase.email, + files=TestEncryptedPassportElementBase.files, + front_side=TestEncryptedPassportElementBase.front_side, + reverse_side=TestEncryptedPassportElementBase.reverse_side, + selfie=TestEncryptedPassportElementBase.selfie, ) -class Space: +class TestEncryptedPassportElementBase: type_ = "type" hash = "this is a hash" data = "data" @@ -49,7 +49,7 @@ class Space: selfie = PassportFile("file_id", 50, 0, 25) -class TestEncryptedPassportElementWithoutRequest: +class TestEncryptedPassportElementWithoutRequest(TestEncryptedPassportElementBase): def test_slot_behaviour(self, encrypted_passport_element, mro_slots): inst = encrypted_passport_element for attr in inst.__slots__: @@ -57,15 +57,15 @@ def test_slot_behaviour(self, encrypted_passport_element, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, encrypted_passport_element): - assert encrypted_passport_element.type == Space.type_ - assert encrypted_passport_element.hash == Space.hash - assert encrypted_passport_element.data == Space.data - assert encrypted_passport_element.phone_number == Space.phone_number - assert encrypted_passport_element.email == Space.email - assert encrypted_passport_element.files == tuple(Space.files) - assert encrypted_passport_element.front_side == Space.front_side - assert encrypted_passport_element.reverse_side == Space.reverse_side - assert encrypted_passport_element.selfie == Space.selfie + assert encrypted_passport_element.type == self.type_ + assert encrypted_passport_element.hash == self.hash + assert encrypted_passport_element.data == self.data + assert encrypted_passport_element.phone_number == self.phone_number + assert encrypted_passport_element.email == self.email + assert encrypted_passport_element.files == tuple(self.files) + assert encrypted_passport_element.front_side == self.front_side + assert encrypted_passport_element.reverse_side == self.reverse_side + assert encrypted_passport_element.selfie == self.selfie def test_to_dict(self, encrypted_passport_element): encrypted_passport_element_dict = encrypted_passport_element.to_dict() @@ -93,14 +93,14 @@ def test_to_dict(self, encrypted_passport_element): ) def test_attributes_always_tuple(self): - element = EncryptedPassportElement(Space.type_, Space.hash) + element = EncryptedPassportElement(self.type_, self.hash) assert element.files == () assert element.translation == () def test_equality(self): - a = EncryptedPassportElement(Space.type_, Space.hash, data=Space.data) - b = EncryptedPassportElement(Space.type_, Space.hash, data=Space.data) - c = EncryptedPassportElement(Space.data, "") + a = EncryptedPassportElement(self.type_, self.hash, data=self.data) + b = EncryptedPassportElement(self.type_, self.hash, data=self.data) + c = EncryptedPassportElement(self.data, "") d = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_file.py b/tests/test_file.py index a6cfb054c54..30c75b87896 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -30,10 +30,10 @@ @pytest.fixture(scope="module") def file(bot): file = File( - Space.file_id, - Space.file_unique_id, - file_path=Space.file_path, - file_size=Space.file_size, + TestFileBase.file_id, + TestFileBase.file_unique_id, + file_path=TestFileBase.file_path, + file_size=TestFileBase.file_size, ) file.set_bot(bot) file._unfreeze() @@ -49,7 +49,12 @@ def encrypted_file(bot): "Oq3G4sX+bKZthoyms1YlPqvWou9esb+z0Bi/KqQUG8s=", "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) - ef = File(Space.file_id, Space.file_unique_id, Space.file_size, Space.file_path) + ef = File( + TestFileBase.file_id, + TestFileBase.file_unique_id, + TestFileBase.file_size, + TestFileBase.file_path, + ) ef.set_bot(bot) ef.set_credentials(fc) return ef @@ -63,9 +68,9 @@ def encrypted_local_file(bot): "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) ef = File( - Space.file_id, - Space.file_unique_id, - Space.file_size, + TestFileBase.file_id, + TestFileBase.file_unique_id, + TestFileBase.file_size, file_path=str(data_file("image_encrypted.jpg")), ) ef.set_bot(bot) @@ -76,16 +81,16 @@ def encrypted_local_file(bot): @pytest.fixture(scope="module") def local_file(bot): file = File( - Space.file_id, - Space.file_unique_id, + TestFileBase.file_id, + TestFileBase.file_unique_id, file_path=str(data_file("local_file.txt")), - file_size=Space.file_size, + file_size=TestFileBase.file_size, ) file.set_bot(bot) return file -class Space: +class TestFileBase: file_id = "NOTVALIDDOESNOTMATTER" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_path = ( @@ -95,7 +100,7 @@ class Space: file_content = "Saint-Saëns".encode() # Intentionally contains unicode chars. -class TestFileWithoutRequest: +class TestFileWithoutRequest(TestFileBase): def test_slot_behaviour(self, file, mro_slots): for attr in file.__slots__: assert getattr(file, attr, "err") != "err", f"got extra slot '{attr}'" @@ -103,18 +108,18 @@ def test_slot_behaviour(self, file, mro_slots): def test_de_json(self, bot): json_dict = { - "file_id": Space.file_id, - "file_unique_id": Space.file_unique_id, - "file_path": Space.file_path, - "file_size": Space.file_size, + "file_id": self.file_id, + "file_unique_id": self.file_unique_id, + "file_path": self.file_path, + "file_size": self.file_size, } new_file = File.de_json(json_dict, bot) assert new_file.api_kwargs == {} - assert new_file.file_id == Space.file_id - assert new_file.file_unique_id == Space.file_unique_id - assert new_file.file_path == Space.file_path - assert new_file.file_size == Space.file_size + assert new_file.file_id == self.file_id + assert new_file.file_unique_id == self.file_unique_id + assert new_file.file_path == self.file_path + assert new_file.file_size == self.file_size def test_to_dict(self, file): file_dict = file.to_dict() @@ -126,11 +131,11 @@ def test_to_dict(self, file): assert file_dict["file_size"] == file.file_size def test_equality(self, bot): - a = File(Space.file_id, Space.file_unique_id, bot) - b = File("", Space.file_unique_id, bot) - c = File(Space.file_id, Space.file_unique_id, None) + a = File(self.file_id, self.file_unique_id, bot) + b = File("", self.file_unique_id, bot) + c = File(self.file_id, self.file_unique_id, None) d = File("", "", bot) - e = Voice(Space.file_id, Space.file_unique_id, 0) + e = Voice(self.file_id, self.file_unique_id, 0) assert a == b assert hash(a) == hash(b) @@ -147,13 +152,13 @@ def test_equality(self, bot): async def test_download(self, monkeypatch, file): async def test(*args, **kwargs): - return Space.file_content + return self.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) out_file = await file.download_to_drive() try: - assert out_file.read_bytes() == Space.file_content + assert out_file.read_bytes() == self.file_content finally: out_file.unlink() @@ -162,7 +167,7 @@ async def test(*args, **kwargs): ) async def test_download_custom_path(self, monkeypatch, file, custom_path_type): async def test(*args, **kwargs): - return Space.file_content + return self.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) file_handle, custom_path = mkstemp() @@ -170,14 +175,14 @@ async def test(*args, **kwargs): try: out_file = await file.download_to_drive(custom_path_type(custom_path)) assert out_file == custom_path - assert out_file.read_bytes() == Space.file_content + assert out_file.read_bytes() == self.file_content finally: os.close(file_handle) custom_path.unlink() async def test_download_no_filename(self, monkeypatch, file): async def test(*args, **kwargs): - return Space.file_content + return self.file_content file.file_path = None @@ -186,29 +191,29 @@ async def test(*args, **kwargs): assert str(out_file)[-len(file.file_id) :] == file.file_id try: - assert out_file.read_bytes() == Space.file_content + assert out_file.read_bytes() == self.file_content finally: out_file.unlink() async def test_download_file_obj(self, monkeypatch, file): async def test(*args, **kwargs): - return Space.file_content + return self.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) with TemporaryFile() as custom_fobj: await file.download_to_memory(out=custom_fobj) custom_fobj.seek(0) - assert custom_fobj.read() == Space.file_content + assert custom_fobj.read() == self.file_content async def test_download_bytearray(self, monkeypatch, file): async def test(*args, **kwargs): - return Space.file_content + return self.file_content monkeypatch.setattr(file.get_bot().request, "retrieve", test) # Check that a download to a newly allocated bytearray works. buf = await file.download_as_bytearray() - assert buf == bytearray(Space.file_content) + assert buf == bytearray(self.file_content) # Check that a download to a given bytearray works (extends the bytearray). buf2 = buf[:] @@ -267,7 +272,7 @@ async def test(*args, **kwargs): assert buf2[: len(buf)] == buf -class TestFileWithRequest: +class TestFileWithRequest(TestFileBase): async def test_error_get_empty_file_id(self, bot): with pytest.raises(TelegramError): await bot.get_file(file_id="") @@ -284,7 +289,7 @@ async def test_download_custom_path_local_file(self, local_file, custom_path_typ try: out_file = await local_file.download_to_drive(custom_path_type(custom_path)) assert out_file == custom_path - assert out_file.read_bytes() == Space.file_content + assert out_file.read_bytes() == self.file_content finally: os.close(file_handle) custom_path.unlink() @@ -293,7 +298,7 @@ async def test_download_file_obj_local_file(self, local_file): with TemporaryFile() as custom_fobj: await local_file.download_to_memory(out=custom_fobj) custom_fobj.seek(0) - assert custom_fobj.read() == Space.file_content + assert custom_fobj.read() == self.file_content @pytest.mark.parametrize( "custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"] @@ -321,7 +326,7 @@ async def test_download_local_file_encrypted(self, encrypted_local_file): async def test_download_bytearray_local_file(self, local_file): # Check that a download to a newly allocated bytearray works. buf = await local_file.download_as_bytearray() - assert buf == bytearray(Space.file_content) + assert buf == bytearray(self.file_content) # Check that a download to a given bytearray works (extends the bytearray). buf2 = buf[:] diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index 1e9870558ae..18822a33fc2 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -24,25 +24,25 @@ @pytest.fixture(scope="module") def force_reply(): - return ForceReply(Space.selective, Space.input_field_placeholder) + return ForceReply(TestForceReplyBase.selective, TestForceReplyBase.input_field_placeholder) -class Space: +class TestForceReplyBase: force_reply = True selective = True input_field_placeholder = "force replies can be annoying if not used properly" -class TestForceReplyWithoutRequest: +class TestForceReplyWithoutRequest(TestForceReplyBase): def test_slot_behaviour(self, force_reply, mro_slots): for attr in force_reply.__slots__: assert getattr(force_reply, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(force_reply)) == len(set(mro_slots(force_reply))), "duplicate slot" def test_expected(self, force_reply): - assert force_reply.force_reply == Space.force_reply - assert force_reply.selective == Space.selective - assert force_reply.input_field_placeholder == Space.input_field_placeholder + assert force_reply.force_reply == self.force_reply + assert force_reply.selective == self.selective + assert force_reply.input_field_placeholder == self.input_field_placeholder def test_to_dict(self, force_reply): force_reply_dict = force_reply.to_dict() @@ -68,7 +68,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestForceReplyWithRequest: +class TestForceReplyWithRequest(TestForceReplyBase): async def test_send_message_with_force_reply(self, bot, chat_id, force_reply): message = await bot.send_message(chat_id, "text", reply_markup=force_reply) assert message.text == "text" diff --git a/tests/test_game.py b/tests/test_game.py index 753b35dc888..1ad8f4d1603 100644 --- a/tests/test_game.py +++ b/tests/test_game.py @@ -25,18 +25,18 @@ @pytest.fixture(scope="module") def game(): game = Game( - Space.title, - Space.description, - Space.photo, - text=Space.text, - text_entities=Space.text_entities, - animation=Space.animation, + TestGameBase.title, + TestGameBase.description, + TestGameBase.photo, + text=TestGameBase.text, + text_entities=TestGameBase.text_entities, + animation=TestGameBase.animation, ) game._unfreeze() return game -class Space: +class TestGameBase: title = "Python-telegram-bot Test Game" description = "description" photo = [PhotoSize("Blah", "ElseBlah", 640, 360, file_size=0)] @@ -48,7 +48,7 @@ class Space: animation = Animation("blah", "unique_id", 320, 180, 1) -class TestGameWithoutRequest: +class TestGameWithoutRequest(TestGameBase): def test_slot_behaviour(self, game, mro_slots): for attr in game.__slots__: assert getattr(game, attr, "err") != "err", f"got extra slot '{attr}'" @@ -56,35 +56,35 @@ def test_slot_behaviour(self, game, mro_slots): def test_de_json_required(self, bot): json_dict = { - "title": Space.title, - "description": Space.description, - "photo": [Space.photo[0].to_dict()], + "title": self.title, + "description": self.description, + "photo": [self.photo[0].to_dict()], } game = Game.de_json(json_dict, bot) assert game.api_kwargs == {} - assert game.title == Space.title - assert game.description == Space.description - assert game.photo == tuple(Space.photo) + assert game.title == self.title + assert game.description == self.description + assert game.photo == tuple(self.photo) def test_de_json_all(self, bot): json_dict = { - "title": Space.title, - "description": Space.description, - "photo": [Space.photo[0].to_dict()], - "text": Space.text, - "text_entities": [Space.text_entities[0].to_dict()], - "animation": Space.animation.to_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) assert game.api_kwargs == {} - assert game.title == Space.title - assert game.description == Space.description - assert game.photo == tuple(Space.photo) - assert game.text == Space.text - assert game.text_entities == tuple(Space.text_entities) - assert game.animation == Space.animation + assert game.title == self.title + assert game.description == self.description + assert game.photo == tuple(self.photo) + assert game.text == self.text + assert game.text_entities == tuple(self.text_entities) + assert game.animation == self.animation def test_to_dict(self, game): game_dict = game.to_dict() diff --git a/tests/test_gamehighscore.py b/tests/test_gamehighscore.py index 7c14d179883..1556a67d40d 100644 --- a/tests/test_gamehighscore.py +++ b/tests/test_gamehighscore.py @@ -24,16 +24,18 @@ @pytest.fixture(scope="module") def game_highscore(): - return GameHighScore(Space.position, Space.user, Space.score) + return GameHighScore( + TestGameHighScoreBase.position, TestGameHighScoreBase.user, TestGameHighScoreBase.score + ) -class Space: +class TestGameHighScoreBase: position = 12 user = User(2, "test user", False) score = 42 -class TestGameHighScoreWithoutRequest: +class TestGameHighScoreWithoutRequest(TestGameHighScoreBase): def test_slot_behaviour(self, game_highscore, mro_slots): for attr in game_highscore.__slots__: assert getattr(game_highscore, attr, "err") != "err", f"got extra slot '{attr}'" @@ -41,16 +43,16 @@ def test_slot_behaviour(self, game_highscore, mro_slots): def test_de_json(self, bot): json_dict = { - "position": Space.position, - "user": Space.user.to_dict(), - "score": Space.score, + "position": self.position, + "user": self.user.to_dict(), + "score": self.score, } highscore = GameHighScore.de_json(json_dict, bot) assert highscore.api_kwargs == {} - assert highscore.position == Space.position - assert highscore.user == Space.user - assert highscore.score == Space.score + assert highscore.position == self.position + assert highscore.user == self.user + assert highscore.score == self.score assert GameHighScore.de_json(None, bot) is None diff --git a/tests/test_inlinekeyboardbutton.py b/tests/test_inlinekeyboardbutton.py index 331bbfe9eee..d9783dcd076 100644 --- a/tests/test_inlinekeyboardbutton.py +++ b/tests/test_inlinekeyboardbutton.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="module") def inline_keyboard_button(): return InlineKeyboardButton( - Space.text, - url=Space.url, - callback_data=Space.callback_data, - switch_inline_query=Space.switch_inline_query, - switch_inline_query_current_chat=Space.switch_inline_query_current_chat, - callback_game=Space.callback_game, - pay=Space.pay, - login_url=Space.login_url, - web_app=Space.web_app, + TestInlineKeyboardButtonBase.text, + url=TestInlineKeyboardButtonBase.url, + callback_data=TestInlineKeyboardButtonBase.callback_data, + switch_inline_query=TestInlineKeyboardButtonBase.switch_inline_query, + switch_inline_query_current_chat=TestInlineKeyboardButtonBase.switch_inline_query_current_chat, # noqa: E501 + callback_game=TestInlineKeyboardButtonBase.callback_game, + pay=TestInlineKeyboardButtonBase.pay, + login_url=TestInlineKeyboardButtonBase.login_url, + web_app=TestInlineKeyboardButtonBase.web_app, ) -class Space: +class TestInlineKeyboardButtonBase: text = "text" url = "url" callback_data = "callback data" @@ -49,7 +49,7 @@ class Space: web_app = WebAppInfo(url="https://example.com") -class TestInlineKeyboardButtonWithoutRequest: +class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase): def test_slot_behaviour(self, inline_keyboard_button, mro_slots): inst = inline_keyboard_button for attr in inst.__slots__: @@ -57,18 +57,18 @@ def test_slot_behaviour(self, inline_keyboard_button, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_keyboard_button): - assert inline_keyboard_button.text == Space.text - assert inline_keyboard_button.url == Space.url - assert inline_keyboard_button.callback_data == Space.callback_data - assert inline_keyboard_button.switch_inline_query == Space.switch_inline_query + 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 - == Space.switch_inline_query_current_chat + == self.switch_inline_query_current_chat ) assert isinstance(inline_keyboard_button.callback_game, CallbackGame) - assert inline_keyboard_button.pay == Space.pay - assert inline_keyboard_button.login_url == Space.login_url - assert inline_keyboard_button.web_app == Space.web_app + assert inline_keyboard_button.pay == self.pay + assert inline_keyboard_button.login_url == self.login_url + assert inline_keyboard_button.web_app == self.web_app def test_to_dict(self, inline_keyboard_button): inline_keyboard_button_dict = inline_keyboard_button.to_dict() @@ -97,32 +97,32 @@ def test_to_dict(self, inline_keyboard_button): def test_de_json(self, bot): json_dict = { - "text": Space.text, - "url": Space.url, - "callback_data": Space.callback_data, - "switch_inline_query": Space.switch_inline_query, - "switch_inline_query_current_chat": Space.switch_inline_query_current_chat, - "callback_game": Space.callback_game.to_dict(), - "web_app": Space.web_app.to_dict(), - "login_url": Space.login_url.to_dict(), - "pay": Space.pay, + "text": self.text, + "url": self.url, + "callback_data": self.callback_data, + "switch_inline_query": self.switch_inline_query, + "switch_inline_query_current_chat": self.switch_inline_query_current_chat, + "callback_game": self.callback_game.to_dict(), + "web_app": self.web_app.to_dict(), + "login_url": self.login_url.to_dict(), + "pay": self.pay, } inline_keyboard_button = InlineKeyboardButton.de_json(json_dict, None) assert inline_keyboard_button.api_kwargs == {} - assert inline_keyboard_button.text == Space.text - assert inline_keyboard_button.url == Space.url - assert inline_keyboard_button.callback_data == Space.callback_data - assert inline_keyboard_button.switch_inline_query == Space.switch_inline_query + 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 - == Space.switch_inline_query_current_chat + == self.switch_inline_query_current_chat ) # CallbackGame has empty _id_attrs, so just test if the class is created. assert isinstance(inline_keyboard_button.callback_game, CallbackGame) - assert inline_keyboard_button.pay == Space.pay - assert inline_keyboard_button.login_url == Space.login_url - assert inline_keyboard_button.web_app == Space.web_app + assert inline_keyboard_button.pay == self.pay + assert inline_keyboard_button.login_url == self.login_url + assert inline_keyboard_button.web_app == self.web_app none = InlineKeyboardButton.de_json({}, bot) assert none is None diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 344ecfcac32..6123e6738e1 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -30,10 +30,10 @@ @pytest.fixture(scope="module") def inline_keyboard_markup(): - return InlineKeyboardMarkup(Space.inline_keyboard) + return InlineKeyboardMarkup(TestInlineKeyboardMarkupBase.inline_keyboard) -class Space: +class TestInlineKeyboardMarkupBase: inline_keyboard = [ [ InlineKeyboardButton(text="button1", callback_data="data1"), @@ -42,7 +42,7 @@ class Space: ] -class TestInlineKeyboardMarkupWithoutRequest: +class TestInlineKeyboardMarkupWithoutRequest(TestInlineKeyboardMarkupBase): def test_slot_behaviour(self, inline_keyboard_markup, mro_slots): inst = inline_keyboard_markup for attr in inst.__slots__: @@ -54,7 +54,7 @@ def test_to_dict(self, inline_keyboard_markup): assert isinstance(inline_keyboard_markup_dict, dict) assert inline_keyboard_markup_dict["inline_keyboard"] == [ - [Space.inline_keyboard[0][0].to_dict(), Space.inline_keyboard[0][1].to_dict()] + [self.inline_keyboard[0][0].to_dict(), self.inline_keyboard[0][1].to_dict()] ] def test_de_json(self): @@ -174,7 +174,7 @@ def test_from_column(self): def test_expected_values(self, inline_keyboard_markup): assert inline_keyboard_markup.inline_keyboard == tuple( - tuple(row) for row in Space.inline_keyboard + tuple(row) for row in self.inline_keyboard ) def test_wrong_keyboard_inputs(self): @@ -225,7 +225,7 @@ async def make_assertion( await bot.send_message(123, "test", reply_markup=inline_keyboard_markup) -class TestInlineKeyborardMarkupWithRequest: +class TestInlineKeyborardMarkupWithRequest(TestInlineKeyboardMarkupBase): async def test_send_message_with_inline_keyboard_markup( self, bot, chat_id, inline_keyboard_markup ): diff --git a/tests/test_inlinequery.py b/tests/test_inlinequery.py index 67f86e62627..7b79a998fce 100644 --- a/tests/test_inlinequery.py +++ b/tests/test_inlinequery.py @@ -30,17 +30,17 @@ @pytest.fixture(scope="module") def inline_query(bot): ilq = InlineQuery( - Space.id_, - Space.from_user, - Space.query, - Space.offset, - location=Space.location, + TestInlineQueryBase.id_, + TestInlineQueryBase.from_user, + TestInlineQueryBase.query, + TestInlineQueryBase.offset, + location=TestInlineQueryBase.location, ) ilq.set_bot(bot) return ilq -class Space: +class TestInlineQueryBase: id_ = 1234 from_user = User(1, "First name", False) query = "query text" @@ -48,7 +48,7 @@ class Space: location = Location(8.8, 53.1) -class TestInlineQueryWithoutRequest: +class TestInlineQueryWithoutRequest(TestInlineQueryBase): def test_slot_behaviour(self, inline_query, mro_slots): for attr in inline_query.__slots__: assert getattr(inline_query, attr, "err") != "err", f"got extra slot '{attr}'" @@ -56,20 +56,20 @@ def test_slot_behaviour(self, inline_query, mro_slots): def test_de_json(self, bot): json_dict = { - "id": Space.id_, - "from": Space.from_user.to_dict(), - "query": Space.query, - "offset": Space.offset, - "location": Space.location.to_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) assert inline_query_json.api_kwargs == {} - assert inline_query_json.id == Space.id_ - assert inline_query_json.from_user == Space.from_user - assert inline_query_json.location == Space.location - assert inline_query_json.query == Space.query - assert inline_query_json.offset == Space.offset + 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 def test_to_dict(self, inline_query): inline_query_dict = inline_query.to_dict() @@ -82,11 +82,11 @@ def test_to_dict(self, inline_query): assert inline_query_dict["offset"] == inline_query.offset def test_equality(self): - a = InlineQuery(Space.id_, User(1, "", False), "", "") - b = InlineQuery(Space.id_, User(1, "", False), "", "") - c = InlineQuery(Space.id_, User(0, "", False), "", "") + a = InlineQuery(self.id_, User(1, "", False), "", "") + b = InlineQuery(self.id_, User(1, "", False), "", "") + c = InlineQuery(self.id_, User(0, "", False), "", "") d = InlineQuery(0, User(1, "", False), "", "") - e = Update(Space.id_) + e = Update(self.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultarticle.py b/tests/test_inlinequeryresultarticle.py index f0d26705dac..1d4ebce805a 100644 --- a/tests/test_inlinequeryresultarticle.py +++ b/tests/test_inlinequeryresultarticle.py @@ -31,20 +31,20 @@ @pytest.fixture(scope="module") def inline_query_result_article(): return InlineQueryResultArticle( - Space.id_, - Space.title, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, - url=Space.url, - hide_url=Space.hide_url, - description=Space.description, - thumb_url=Space.thumb_url, - thumb_height=Space.thumb_height, - thumb_width=Space.thumb_width, + TestInlineQueryResultArticleBase.id_, + TestInlineQueryResultArticleBase.title, + input_message_content=TestInlineQueryResultArticleBase.input_message_content, + reply_markup=TestInlineQueryResultArticleBase.reply_markup, + url=TestInlineQueryResultArticleBase.url, + hide_url=TestInlineQueryResultArticleBase.hide_url, + description=TestInlineQueryResultArticleBase.description, + thumb_url=TestInlineQueryResultArticleBase.thumb_url, + thumb_height=TestInlineQueryResultArticleBase.thumb_height, + thumb_width=TestInlineQueryResultArticleBase.thumb_width, ) -class Space: +class TestInlineQueryResultArticleBase: id_ = "id" type_ = "article" title = "title" @@ -58,7 +58,7 @@ class Space: thumb_width = 15 -class TestInlineQueryResultArticleWithoutRequest: +class TestInlineQueryResultArticleWithoutRequest(TestInlineQueryResultArticleBase): def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): inst = inline_query_result_article for attr in inst.__slots__: @@ -66,20 +66,20 @@ def test_slot_behaviour(self, inline_query_result_article, mro_slots, recwarn): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_article): - assert inline_query_result_article.type == Space.type_ - assert inline_query_result_article.id == Space.id_ - assert inline_query_result_article.title == Space.title + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_article.reply_markup.to_dict() == Space.reply_markup.to_dict() - assert inline_query_result_article.url == Space.url - assert inline_query_result_article.hide_url == Space.hide_url - assert inline_query_result_article.description == Space.description - assert inline_query_result_article.thumb_url == Space.thumb_url - assert inline_query_result_article.thumb_height == Space.thumb_height - assert inline_query_result_article.thumb_width == Space.thumb_width + 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 def test_to_dict(self, inline_query_result_article): inline_query_result_article_dict = inline_query_result_article.to_dict() @@ -115,11 +115,11 @@ def test_to_dict(self, inline_query_result_article): ) def test_equality(self): - a = InlineQueryResultArticle(Space.id_, Space.title, Space.input_message_content) - b = InlineQueryResultArticle(Space.id_, Space.title, Space.input_message_content) - c = InlineQueryResultArticle(Space.id_, "", Space.input_message_content) - d = InlineQueryResultArticle("", Space.title, Space.input_message_content) - e = InlineQueryResultAudio(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultaudio.py b/tests/test_inlinequeryresultaudio.py index a1f6c4bebf3..fd5fb1570d6 100644 --- a/tests/test_inlinequeryresultaudio.py +++ b/tests/test_inlinequeryresultaudio.py @@ -32,20 +32,20 @@ @pytest.fixture(scope="module") def inline_query_result_audio(): return InlineQueryResultAudio( - Space.id_, - Space.audio_url, - Space.title, - performer=Space.performer, - audio_duration=Space.audio_duration, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultAudioBase.id_, + TestInlineQueryResultAudioBase.audio_url, + TestInlineQueryResultAudioBase.title, + performer=TestInlineQueryResultAudioBase.performer, + audio_duration=TestInlineQueryResultAudioBase.audio_duration, + caption=TestInlineQueryResultAudioBase.caption, + parse_mode=TestInlineQueryResultAudioBase.parse_mode, + caption_entities=TestInlineQueryResultAudioBase.caption_entities, + input_message_content=TestInlineQueryResultAudioBase.input_message_content, + reply_markup=TestInlineQueryResultAudioBase.reply_markup, ) -class Space: +class TestInlineQueryResultAudioBase: id_ = "id" type_ = "audio" audio_url = "audio url" @@ -59,7 +59,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultAudioWithoutRequest: +class TestInlineQueryResultAudioWithoutRequest(TestInlineQueryResultAudioBase): def test_slot_behaviour(self, inline_query_result_audio, mro_slots): inst = inline_query_result_audio for attr in inst.__slots__: @@ -67,20 +67,20 @@ def test_slot_behaviour(self, inline_query_result_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_audio): - assert inline_query_result_audio.type == Space.type_ - assert inline_query_result_audio.id == Space.id_ - assert inline_query_result_audio.audio_url == Space.audio_url - assert inline_query_result_audio.title == Space.title - assert inline_query_result_audio.performer == Space.performer - assert inline_query_result_audio.audio_duration == Space.audio_duration - assert inline_query_result_audio.caption == Space.caption - assert inline_query_result_audio.parse_mode == Space.parse_mode - assert inline_query_result_audio.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_audio.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_audio.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_audio.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_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() @@ -110,15 +110,15 @@ def test_to_dict(self, inline_query_result_audio): ) def test_caption_entities_always_tuple(self): - inline_query_result_audio = InlineQueryResultAudio(Space.id_, Space.audio_url, Space.title) + inline_query_result_audio = InlineQueryResultAudio(self.id_, self.audio_url, self.title) assert inline_query_result_audio.caption_entities == () def test_equality(self): - a = InlineQueryResultAudio(Space.id_, Space.audio_url, Space.title) - b = InlineQueryResultAudio(Space.id_, Space.title, Space.title) - c = InlineQueryResultAudio(Space.id_, "", Space.title) - d = InlineQueryResultAudio("", Space.audio_url, Space.title) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedaudio.py b/tests/test_inlinequeryresultcachedaudio.py index ec65ea79f88..67234661315 100644 --- a/tests/test_inlinequeryresultcachedaudio.py +++ b/tests/test_inlinequeryresultcachedaudio.py @@ -32,17 +32,17 @@ @pytest.fixture(scope="module") def inline_query_result_cached_audio(): return InlineQueryResultCachedAudio( - Space.id_, - Space.audio_file_id, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedAudioBase.id_, + TestInlineQueryResultCachedAudioBase.audio_file_id, + caption=TestInlineQueryResultCachedAudioBase.caption, + parse_mode=TestInlineQueryResultCachedAudioBase.parse_mode, + caption_entities=TestInlineQueryResultCachedAudioBase.caption_entities, + input_message_content=TestInlineQueryResultCachedAudioBase.input_message_content, + reply_markup=TestInlineQueryResultCachedAudioBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedAudioBase: id_ = "id" type_ = "audio" audio_file_id = "audio file id" @@ -53,7 +53,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedAudioWithoutRequest: +class TestInlineQueryResultCachedAudioWithoutRequest(TestInlineQueryResultCachedAudioBase): def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): inst = inline_query_result_cached_audio for attr in inst.__slots__: @@ -61,22 +61,22 @@ def test_slot_behaviour(self, inline_query_result_cached_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_audio): - assert inline_query_result_cached_audio.type == Space.type_ - assert inline_query_result_cached_audio.id == Space.id_ - assert inline_query_result_cached_audio.audio_file_id == Space.audio_file_id - assert inline_query_result_cached_audio.caption == Space.caption - assert inline_query_result_cached_audio.parse_mode == Space.parse_mode - assert inline_query_result_cached_audio.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_audio.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_cached_audio.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( - inline_query_result_cached_audio.reply_markup.to_dict() == Space.reply_markup.to_dict() + inline_query_result_cached_audio.reply_markup.to_dict() == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - audio = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) + audio = InlineQueryResultCachedAudio(self.id_, self.audio_file_id) assert audio.caption_entities == () def test_to_dict(self, inline_query_result_cached_audio): @@ -112,11 +112,11 @@ def test_to_dict(self, inline_query_result_cached_audio): ) def test_equality(self): - a = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) - b = InlineQueryResultCachedAudio(Space.id_, Space.audio_file_id) - c = InlineQueryResultCachedAudio(Space.id_, "") - d = InlineQueryResultCachedAudio("", Space.audio_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcacheddocument.py b/tests/test_inlinequeryresultcacheddocument.py index 2e9b7c62405..6b47eb7e7a0 100644 --- a/tests/test_inlinequeryresultcacheddocument.py +++ b/tests/test_inlinequeryresultcacheddocument.py @@ -32,19 +32,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_document(): return InlineQueryResultCachedDocument( - Space.id_, - Space.title, - Space.document_file_id, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - description=Space.description, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedDocumentBase.id_, + TestInlineQueryResultCachedDocumentBase.title, + TestInlineQueryResultCachedDocumentBase.document_file_id, + caption=TestInlineQueryResultCachedDocumentBase.caption, + parse_mode=TestInlineQueryResultCachedDocumentBase.parse_mode, + caption_entities=TestInlineQueryResultCachedDocumentBase.caption_entities, + description=TestInlineQueryResultCachedDocumentBase.description, + input_message_content=TestInlineQueryResultCachedDocumentBase.input_message_content, + reply_markup=TestInlineQueryResultCachedDocumentBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedDocumentBase: id_ = "id" type_ = "document" document_file_id = "document file id" @@ -57,7 +57,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedDocumentWithoutRequest: +class TestInlineQueryResultCachedDocumentWithoutRequest(TestInlineQueryResultCachedDocumentBase): def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): inst = inline_query_result_cached_document for attr in inst.__slots__: @@ -65,27 +65,25 @@ def test_slot_behaviour(self, inline_query_result_cached_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_document): - assert inline_query_result_cached_document.id == Space.id_ - assert inline_query_result_cached_document.type == Space.type_ - assert inline_query_result_cached_document.document_file_id == Space.document_file_id - assert inline_query_result_cached_document.title == Space.title - assert inline_query_result_cached_document.caption == Space.caption - assert inline_query_result_cached_document.parse_mode == Space.parse_mode - assert inline_query_result_cached_document.caption_entities == tuple( - Space.caption_entities - ) - assert inline_query_result_cached_document.description == Space.description + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_document.caption_entities == tuple(self.caption_entities) + assert inline_query_result_cached_document.description == self.description assert ( inline_query_result_cached_document.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( inline_query_result_cached_document.reply_markup.to_dict() - == Space.reply_markup.to_dict() + == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - test = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) + test = InlineQueryResultCachedDocument(self.id_, self.title, self.document_file_id) assert test.caption_entities == () def test_to_dict(self, inline_query_result_cached_document): @@ -133,11 +131,11 @@ def test_to_dict(self, inline_query_result_cached_document): ) def test_equality(self): - a = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) - b = InlineQueryResultCachedDocument(Space.id_, Space.title, Space.document_file_id) - c = InlineQueryResultCachedDocument(Space.id_, Space.title, "") - d = InlineQueryResultCachedDocument("", Space.title, Space.document_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedgif.py b/tests/test_inlinequeryresultcachedgif.py index 376eaeed4e8..34f26df73ba 100644 --- a/tests/test_inlinequeryresultcachedgif.py +++ b/tests/test_inlinequeryresultcachedgif.py @@ -31,18 +31,18 @@ @pytest.fixture(scope="module") def inline_query_result_cached_gif(): return InlineQueryResultCachedGif( - Space.id_, - Space.gif_file_id, - title=Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedGifBase.id_, + TestInlineQueryResultCachedGifBase.gif_file_id, + title=TestInlineQueryResultCachedGifBase.title, + caption=TestInlineQueryResultCachedGifBase.caption, + parse_mode=TestInlineQueryResultCachedGifBase.parse_mode, + caption_entities=TestInlineQueryResultCachedGifBase.caption_entities, + input_message_content=TestInlineQueryResultCachedGifBase.input_message_content, + reply_markup=TestInlineQueryResultCachedGifBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedGifBase: id_ = "id" type_ = "gif" gif_file_id = "gif file id" @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedGifWithoutRequest: +class TestInlineQueryResultCachedGifWithoutRequest(TestInlineQueryResultCachedGifBase): def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): inst = inline_query_result_cached_gif for attr in inst.__slots__: @@ -62,23 +62,21 @@ def test_slot_behaviour(self, inline_query_result_cached_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_gif): - assert inline_query_result_cached_gif.type == Space.type_ - assert inline_query_result_cached_gif.id == Space.id_ - assert inline_query_result_cached_gif.gif_file_id == Space.gif_file_id - assert inline_query_result_cached_gif.title == Space.title - assert inline_query_result_cached_gif.caption == Space.caption - assert inline_query_result_cached_gif.parse_mode == Space.parse_mode - assert inline_query_result_cached_gif.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_gif.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_cached_gif.input_message_content.to_dict() - == Space.input_message_content.to_dict() - ) - assert ( - inline_query_result_cached_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() + == self.input_message_content.to_dict() ) + assert inline_query_result_cached_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) + result = InlineQueryResultCachedGif(self.id_, self.gif_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_gif): @@ -113,11 +111,11 @@ def test_to_dict(self, inline_query_result_cached_gif): ) def test_equality(self): - a = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) - b = InlineQueryResultCachedGif(Space.id_, Space.gif_file_id) - c = InlineQueryResultCachedGif(Space.id_, "") - d = InlineQueryResultCachedGif("", Space.gif_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedmpeg4gif.py b/tests/test_inlinequeryresultcachedmpeg4gif.py index 9be3d166a33..37a47e11bfc 100644 --- a/tests/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/test_inlinequeryresultcachedmpeg4gif.py @@ -31,18 +31,18 @@ @pytest.fixture(scope="module") def inline_query_result_cached_mpeg4_gif(): return InlineQueryResultCachedMpeg4Gif( - Space.id_, - Space.mpeg4_file_id, - title=Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedMpeg4GifBase.id_, + TestInlineQueryResultCachedMpeg4GifBase.mpeg4_file_id, + title=TestInlineQueryResultCachedMpeg4GifBase.title, + caption=TestInlineQueryResultCachedMpeg4GifBase.caption, + parse_mode=TestInlineQueryResultCachedMpeg4GifBase.parse_mode, + caption_entities=TestInlineQueryResultCachedMpeg4GifBase.caption_entities, + input_message_content=TestInlineQueryResultCachedMpeg4GifBase.input_message_content, + reply_markup=TestInlineQueryResultCachedMpeg4GifBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedMpeg4GifBase: id_ = "id" type_ = "mpeg4_gif" mpeg4_file_id = "mpeg4 file id" @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedMpeg4GifWithoutRequest: +class TestInlineQueryResultCachedMpeg4GifWithoutRequest(TestInlineQueryResultCachedMpeg4GifBase): def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): inst = inline_query_result_cached_mpeg4_gif for attr in inst.__slots__: @@ -62,26 +62,26 @@ def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_mpeg4_gif): - assert inline_query_result_cached_mpeg4_gif.type == Space.type_ - assert inline_query_result_cached_mpeg4_gif.id == Space.id_ - assert inline_query_result_cached_mpeg4_gif.mpeg4_file_id == Space.mpeg4_file_id - assert inline_query_result_cached_mpeg4_gif.title == Space.title - assert inline_query_result_cached_mpeg4_gif.caption == Space.caption - assert inline_query_result_cached_mpeg4_gif.parse_mode == Space.parse_mode + 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.parse_mode == self.parse_mode assert inline_query_result_cached_mpeg4_gif.caption_entities == tuple( - Space.caption_entities + self.caption_entities ) assert ( inline_query_result_cached_mpeg4_gif.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( inline_query_result_cached_mpeg4_gif.reply_markup.to_dict() - == Space.reply_markup.to_dict() + == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) + result = InlineQueryResultCachedMpeg4Gif(self.id_, self.mpeg4_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_mpeg4_gif): @@ -125,11 +125,11 @@ def test_to_dict(self, inline_query_result_cached_mpeg4_gif): ) def test_equality(self): - a = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) - b = InlineQueryResultCachedMpeg4Gif(Space.id_, Space.mpeg4_file_id) - c = InlineQueryResultCachedMpeg4Gif(Space.id_, "") - d = InlineQueryResultCachedMpeg4Gif("", Space.mpeg4_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedphoto.py b/tests/test_inlinequeryresultcachedphoto.py index 29984f6aea1..209bc90618c 100644 --- a/tests/test_inlinequeryresultcachedphoto.py +++ b/tests/test_inlinequeryresultcachedphoto.py @@ -31,19 +31,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_photo(): return InlineQueryResultCachedPhoto( - Space.id_, - Space.photo_file_id, - title=Space.title, - description=Space.description, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedPhotoBase.id_, + TestInlineQueryResultCachedPhotoBase.photo_file_id, + title=TestInlineQueryResultCachedPhotoBase.title, + description=TestInlineQueryResultCachedPhotoBase.description, + caption=TestInlineQueryResultCachedPhotoBase.caption, + parse_mode=TestInlineQueryResultCachedPhotoBase.parse_mode, + caption_entities=TestInlineQueryResultCachedPhotoBase.caption_entities, + input_message_content=TestInlineQueryResultCachedPhotoBase.input_message_content, + reply_markup=TestInlineQueryResultCachedPhotoBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedPhotoBase: id_ = "id" type_ = "photo" photo_file_id = "photo file id" @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedPhotoWithoutRequest: +class TestInlineQueryResultCachedPhotoWithoutRequest(TestInlineQueryResultCachedPhotoBase): def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): inst = inline_query_result_cached_photo for attr in inst.__slots__: @@ -64,24 +64,24 @@ def test_slot_behaviour(self, inline_query_result_cached_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_photo): - assert inline_query_result_cached_photo.type == Space.type_ - assert inline_query_result_cached_photo.id == Space.id_ - assert inline_query_result_cached_photo.photo_file_id == Space.photo_file_id - assert inline_query_result_cached_photo.title == Space.title - assert inline_query_result_cached_photo.description == Space.description - assert inline_query_result_cached_photo.caption == Space.caption - assert inline_query_result_cached_photo.parse_mode == Space.parse_mode - assert inline_query_result_cached_photo.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_photo.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_cached_photo.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( - inline_query_result_cached_photo.reply_markup.to_dict() == Space.reply_markup.to_dict() + inline_query_result_cached_photo.reply_markup.to_dict() == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) + result = InlineQueryResultCachedPhoto(self.id_, self.photo_file_id) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_photo): @@ -125,11 +125,11 @@ def test_to_dict(self, inline_query_result_cached_photo): ) def test_equality(self): - a = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) - b = InlineQueryResultCachedPhoto(Space.id_, Space.photo_file_id) - c = InlineQueryResultCachedPhoto(Space.id_, "") - d = InlineQueryResultCachedPhoto("", Space.photo_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedsticker.py b/tests/test_inlinequeryresultcachedsticker.py index 0415b550fc5..d41e0506bc9 100644 --- a/tests/test_inlinequeryresultcachedsticker.py +++ b/tests/test_inlinequeryresultcachedsticker.py @@ -30,14 +30,14 @@ @pytest.fixture(scope="module") def inline_query_result_cached_sticker(): return InlineQueryResultCachedSticker( - Space.id_, - Space.sticker_file_id, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedStickerBase.id_, + TestInlineQueryResultCachedStickerBase.sticker_file_id, + input_message_content=TestInlineQueryResultCachedStickerBase.input_message_content, + reply_markup=TestInlineQueryResultCachedStickerBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedStickerBase: id_ = "id" type_ = "sticker" sticker_file_id = "sticker file id" @@ -45,7 +45,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedStickerWithoutRequest: +class TestInlineQueryResultCachedStickerWithoutRequest(TestInlineQueryResultCachedStickerBase): def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): inst = inline_query_result_cached_sticker for attr in inst.__slots__: @@ -53,16 +53,16 @@ def test_slot_behaviour(self, inline_query_result_cached_sticker, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_sticker): - assert inline_query_result_cached_sticker.type == Space.type_ - assert inline_query_result_cached_sticker.id == Space.id_ - assert inline_query_result_cached_sticker.sticker_file_id == Space.sticker_file_id + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( inline_query_result_cached_sticker.reply_markup.to_dict() - == Space.reply_markup.to_dict() + == self.reply_markup.to_dict() ) def test_to_dict(self, inline_query_result_cached_sticker): @@ -90,11 +90,11 @@ def test_to_dict(self, inline_query_result_cached_sticker): ) def test_equality(self): - a = InlineQueryResultCachedSticker(Space.id_, Space.sticker_file_id) - b = InlineQueryResultCachedSticker(Space.id_, Space.sticker_file_id) - c = InlineQueryResultCachedSticker(Space.id_, "") - d = InlineQueryResultCachedSticker("", Space.sticker_file_id) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedvideo.py b/tests/test_inlinequeryresultcachedvideo.py index ac365539742..2ee368c408f 100644 --- a/tests/test_inlinequeryresultcachedvideo.py +++ b/tests/test_inlinequeryresultcachedvideo.py @@ -31,19 +31,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_video(): return InlineQueryResultCachedVideo( - Space.id_, - Space.video_file_id, - Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - description=Space.description, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedVideoBase.id_, + TestInlineQueryResultCachedVideoBase.video_file_id, + TestInlineQueryResultCachedVideoBase.title, + caption=TestInlineQueryResultCachedVideoBase.caption, + parse_mode=TestInlineQueryResultCachedVideoBase.parse_mode, + caption_entities=TestInlineQueryResultCachedVideoBase.caption_entities, + description=TestInlineQueryResultCachedVideoBase.description, + input_message_content=TestInlineQueryResultCachedVideoBase.input_message_content, + reply_markup=TestInlineQueryResultCachedVideoBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedVideoBase: id_ = "id" type_ = "video" video_file_id = "video file id" @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedVideoWithoutRequest: +class TestInlineQueryResultCachedVideoWithoutRequest(TestInlineQueryResultCachedVideoBase): def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): inst = inline_query_result_cached_video for attr in inst.__slots__: @@ -64,24 +64,24 @@ def test_slot_behaviour(self, inline_query_result_cached_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_video): - assert inline_query_result_cached_video.type == Space.type_ - assert inline_query_result_cached_video.id == Space.id_ - assert inline_query_result_cached_video.video_file_id == Space.video_file_id - assert inline_query_result_cached_video.title == Space.title - assert inline_query_result_cached_video.description == Space.description - assert inline_query_result_cached_video.caption == Space.caption - assert inline_query_result_cached_video.parse_mode == Space.parse_mode - assert inline_query_result_cached_video.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_video.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_cached_video.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( - inline_query_result_cached_video.reply_markup.to_dict() == Space.reply_markup.to_dict() + inline_query_result_cached_video.reply_markup.to_dict() == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - video = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) + video = InlineQueryResultCachedVideo(self.id_, self.video_file_id, self.title) assert video.caption_entities == () @@ -126,11 +126,11 @@ def test_to_dict(self, inline_query_result_cached_video): ) def test_equality(self): - a = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) - b = InlineQueryResultCachedVideo(Space.id_, Space.video_file_id, Space.title) - c = InlineQueryResultCachedVideo(Space.id_, "", Space.title) - d = InlineQueryResultCachedVideo("", Space.video_file_id, Space.title) - e = InlineQueryResultCachedVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcachedvoice.py b/tests/test_inlinequeryresultcachedvoice.py index 7b9bdcc7ed9..c1625b2db7a 100644 --- a/tests/test_inlinequeryresultcachedvoice.py +++ b/tests/test_inlinequeryresultcachedvoice.py @@ -31,18 +31,18 @@ @pytest.fixture(scope="module") def inline_query_result_cached_voice(): return InlineQueryResultCachedVoice( - Space.id_, - Space.voice_file_id, - Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultCachedVoiceBase.id_, + TestInlineQueryResultCachedVoiceBase.voice_file_id, + TestInlineQueryResultCachedVoiceBase.title, + caption=TestInlineQueryResultCachedVoiceBase.caption, + parse_mode=TestInlineQueryResultCachedVoiceBase.parse_mode, + caption_entities=TestInlineQueryResultCachedVoiceBase.caption_entities, + input_message_content=TestInlineQueryResultCachedVoiceBase.input_message_content, + reply_markup=TestInlineQueryResultCachedVoiceBase.reply_markup, ) -class Space: +class TestInlineQueryResultCachedVoiceBase: id_ = "id" type_ = "voice" voice_file_id = "voice file id" @@ -54,7 +54,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedVoiceWithoutRequest: +class TestInlineQueryResultCachedVoiceWithoutRequest(TestInlineQueryResultCachedVoiceBase): def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): inst = inline_query_result_cached_voice for attr in inst.__slots__: @@ -62,23 +62,23 @@ def test_slot_behaviour(self, inline_query_result_cached_voice, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_cached_voice): - assert inline_query_result_cached_voice.type == Space.type_ - assert inline_query_result_cached_voice.id == Space.id_ - assert inline_query_result_cached_voice.voice_file_id == Space.voice_file_id - assert inline_query_result_cached_voice.title == Space.title - assert inline_query_result_cached_voice.caption == Space.caption - assert inline_query_result_cached_voice.parse_mode == Space.parse_mode - assert inline_query_result_cached_voice.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_cached_voice.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_cached_voice.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) assert ( - inline_query_result_cached_voice.reply_markup.to_dict() == Space.reply_markup.to_dict() + inline_query_result_cached_voice.reply_markup.to_dict() == self.reply_markup.to_dict() ) def test_caption_entities_always_tuple(self): - result = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) + result = InlineQueryResultCachedVoice(self.id_, self.voice_file_id, self.title) assert result.caption_entities == () def test_to_dict(self, inline_query_result_cached_voice): @@ -118,11 +118,11 @@ def test_to_dict(self, inline_query_result_cached_voice): ) def test_equality(self): - a = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) - b = InlineQueryResultCachedVoice(Space.id_, Space.voice_file_id, Space.title) - c = InlineQueryResultCachedVoice(Space.id_, "", Space.title) - d = InlineQueryResultCachedVoice("", Space.voice_file_id, Space.title) - e = InlineQueryResultCachedAudio(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultcontact.py b/tests/test_inlinequeryresultcontact.py index 17e65b533c6..2b418e9526e 100644 --- a/tests/test_inlinequeryresultcontact.py +++ b/tests/test_inlinequeryresultcontact.py @@ -30,19 +30,19 @@ @pytest.fixture(scope="module") def inline_query_result_contact(): return InlineQueryResultContact( - Space.id_, - Space.phone_number, - Space.first_name, - last_name=Space.last_name, - thumb_url=Space.thumb_url, - thumb_width=Space.thumb_width, - thumb_height=Space.thumb_height, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultContactBase.id_, + TestInlineQueryResultContactBase.phone_number, + TestInlineQueryResultContactBase.first_name, + last_name=TestInlineQueryResultContactBase.last_name, + thumb_url=TestInlineQueryResultContactBase.thumb_url, + thumb_width=TestInlineQueryResultContactBase.thumb_width, + thumb_height=TestInlineQueryResultContactBase.thumb_height, + input_message_content=TestInlineQueryResultContactBase.input_message_content, + reply_markup=TestInlineQueryResultContactBase.reply_markup, ) -class Space: +class TestInlineQueryResultContactBase: id_ = "id" type_ = "contact" phone_number = "phone_number" @@ -55,7 +55,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultContactWithoutRequest: +class TestInlineQueryResultContactWithoutRequest(TestInlineQueryResultContactBase): def test_slot_behaviour(self, inline_query_result_contact, mro_slots): inst = inline_query_result_contact for attr in inst.__slots__: @@ -63,19 +63,19 @@ def test_slot_behaviour(self, inline_query_result_contact, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_contact): - assert inline_query_result_contact.id == Space.id_ - assert inline_query_result_contact.type == Space.type_ - assert inline_query_result_contact.phone_number == Space.phone_number - assert inline_query_result_contact.first_name == Space.first_name - assert inline_query_result_contact.last_name == Space.last_name - assert inline_query_result_contact.thumb_url == Space.thumb_url - assert inline_query_result_contact.thumb_width == Space.thumb_width - assert inline_query_result_contact.thumb_height == Space.thumb_height + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_contact.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_contact.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_contact): inline_query_result_contact_dict = inline_query_result_contact.to_dict() @@ -115,11 +115,11 @@ def test_to_dict(self, inline_query_result_contact): ) def test_equality(self): - a = InlineQueryResultContact(Space.id_, Space.phone_number, Space.first_name) - b = InlineQueryResultContact(Space.id_, Space.phone_number, Space.first_name) - c = InlineQueryResultContact(Space.id_, "", Space.first_name) - d = InlineQueryResultContact("", Space.phone_number, Space.first_name) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultdocument.py b/tests/test_inlinequeryresultdocument.py index 836748adf40..b1221788e14 100644 --- a/tests/test_inlinequeryresultdocument.py +++ b/tests/test_inlinequeryresultdocument.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="module") def inline_query_result_document(): return InlineQueryResultDocument( - Space.id_, - Space.document_url, - Space.title, - Space.mime_type, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - description=Space.description, - thumb_url=Space.thumb_url, - thumb_width=Space.thumb_width, - thumb_height=Space.thumb_height, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultDocumentBase.id_, + TestInlineQueryResultDocumentBase.document_url, + TestInlineQueryResultDocumentBase.title, + TestInlineQueryResultDocumentBase.mime_type, + caption=TestInlineQueryResultDocumentBase.caption, + parse_mode=TestInlineQueryResultDocumentBase.parse_mode, + caption_entities=TestInlineQueryResultDocumentBase.caption_entities, + description=TestInlineQueryResultDocumentBase.description, + thumb_url=TestInlineQueryResultDocumentBase.thumb_url, + thumb_width=TestInlineQueryResultDocumentBase.thumb_width, + thumb_height=TestInlineQueryResultDocumentBase.thumb_height, + input_message_content=TestInlineQueryResultDocumentBase.input_message_content, + reply_markup=TestInlineQueryResultDocumentBase.reply_markup, ) -class Space: +class TestInlineQueryResultDocumentBase: id_ = "id" type_ = "document" document_url = "document url" @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultDocumentWithoutRequest: +class TestInlineQueryResultDocumentWithoutRequest(TestInlineQueryResultDocumentBase): def test_slot_behaviour(self, inline_query_result_document, mro_slots): inst = inline_query_result_document for attr in inst.__slots__: @@ -72,28 +72,26 @@ def test_slot_behaviour(self, inline_query_result_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_document): - assert inline_query_result_document.id == Space.id_ - assert inline_query_result_document.type == Space.type_ - assert inline_query_result_document.document_url == Space.document_url - assert inline_query_result_document.title == Space.title - assert inline_query_result_document.caption == Space.caption - assert inline_query_result_document.parse_mode == Space.parse_mode - assert inline_query_result_document.caption_entities == tuple(Space.caption_entities) - assert inline_query_result_document.mime_type == Space.mime_type - assert inline_query_result_document.description == Space.description - assert inline_query_result_document.thumb_url == Space.thumb_url - assert inline_query_result_document.thumb_width == Space.thumb_width - assert inline_query_result_document.thumb_height == Space.thumb_height + 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.parse_mode == self.parse_mode + assert inline_query_result_document.caption_entities == tuple(self.caption_entities) + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_document.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_document.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultDocument( - Space.id_, Space.document_url, Space.title, Space.mime_type - ) + result = InlineQueryResultDocument(self.id_, self.document_url, self.title, self.mime_type) assert result.caption_entities == () def test_to_dict(self, inline_query_result_document): @@ -145,11 +143,11 @@ def test_to_dict(self, inline_query_result_document): ) def test_equality(self): - a = InlineQueryResultDocument(Space.id_, Space.document_url, Space.title, Space.mime_type) - b = InlineQueryResultDocument(Space.id_, Space.document_url, Space.title, Space.mime_type) - c = InlineQueryResultDocument(Space.id_, "", Space.title, Space.mime_type) - d = InlineQueryResultDocument("", Space.document_url, Space.title, Space.mime_type) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultgame.py b/tests/test_inlinequeryresultgame.py index 0ca69ba0169..f7c6ae75774 100644 --- a/tests/test_inlinequeryresultgame.py +++ b/tests/test_inlinequeryresultgame.py @@ -29,20 +29,20 @@ @pytest.fixture(scope="module") def inline_query_result_game(): return InlineQueryResultGame( - Space.id_, - Space.game_short_name, - reply_markup=Space.reply_markup, + TestInlineQueryResultGameBase.id_, + TestInlineQueryResultGameBase.game_short_name, + reply_markup=TestInlineQueryResultGameBase.reply_markup, ) -class Space: +class TestInlineQueryResultGameBase: id_ = "id" type_ = "game" game_short_name = "game short name" reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultGameWithoutRequest: +class TestInlineQueryResultGameWithoutRequest(TestInlineQueryResultGameBase): def test_slot_behaviour(self, inline_query_result_game, mro_slots): inst = inline_query_result_game for attr in inst.__slots__: @@ -50,10 +50,10 @@ def test_slot_behaviour(self, inline_query_result_game, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_game): - assert inline_query_result_game.type == Space.type_ - assert inline_query_result_game.id == Space.id_ - assert inline_query_result_game.game_short_name == Space.game_short_name - assert inline_query_result_game.reply_markup.to_dict() == Space.reply_markup.to_dict() + 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() @@ -71,11 +71,11 @@ def test_to_dict(self, inline_query_result_game): ) def test_equality(self): - a = InlineQueryResultGame(Space.id_, Space.game_short_name) - b = InlineQueryResultGame(Space.id_, Space.game_short_name) - c = InlineQueryResultGame(Space.id_, "") - d = InlineQueryResultGame("", Space.game_short_name) - e = InlineQueryResultVoice(Space.id_, "", "") + 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) diff --git a/tests/test_inlinequeryresultgif.py b/tests/test_inlinequeryresultgif.py index 6d3dd7e255e..c50fd6b2d0e 100644 --- a/tests/test_inlinequeryresultgif.py +++ b/tests/test_inlinequeryresultgif.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="module") def inline_query_result_gif(): return InlineQueryResultGif( - Space.id_, - Space.gif_url, - Space.thumb_url, - gif_width=Space.gif_width, - gif_height=Space.gif_height, - gif_duration=Space.gif_duration, - title=Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, - thumb_mime_type=Space.thumb_mime_type, + TestInlineQueryResultGifBase.id_, + TestInlineQueryResultGifBase.gif_url, + TestInlineQueryResultGifBase.thumb_url, + gif_width=TestInlineQueryResultGifBase.gif_width, + gif_height=TestInlineQueryResultGifBase.gif_height, + gif_duration=TestInlineQueryResultGifBase.gif_duration, + title=TestInlineQueryResultGifBase.title, + caption=TestInlineQueryResultGifBase.caption, + parse_mode=TestInlineQueryResultGifBase.parse_mode, + caption_entities=TestInlineQueryResultGifBase.caption_entities, + input_message_content=TestInlineQueryResultGifBase.input_message_content, + reply_markup=TestInlineQueryResultGifBase.reply_markup, + thumb_mime_type=TestInlineQueryResultGifBase.thumb_mime_type, ) -class Space: +class TestInlineQueryResultGifBase: id_ = "id" type_ = "gif" gif_url = "gif url" @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultGifWithoutRequest: +class TestInlineQueryResultGifWithoutRequest(TestInlineQueryResultGifBase): def test_slot_behaviour(self, inline_query_result_gif, mro_slots): inst = inline_query_result_gif for attr in inst.__slots__: @@ -72,27 +72,27 @@ def test_slot_behaviour(self, inline_query_result_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_caption_entities_always_tuple(self): - result = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) + result = InlineQueryResultGif(self.id_, self.gif_url, self.thumb_url) assert result.caption_entities == () def test_expected_values(self, inline_query_result_gif): - assert inline_query_result_gif.type == Space.type_ - assert inline_query_result_gif.id == Space.id_ - assert inline_query_result_gif.gif_url == Space.gif_url - assert inline_query_result_gif.gif_width == Space.gif_width - assert inline_query_result_gif.gif_height == Space.gif_height - assert inline_query_result_gif.gif_duration == Space.gif_duration - assert inline_query_result_gif.thumb_url == Space.thumb_url - assert inline_query_result_gif.thumb_mime_type == Space.thumb_mime_type - assert inline_query_result_gif.title == Space.title - assert inline_query_result_gif.caption == Space.caption - assert inline_query_result_gif.parse_mode == Space.parse_mode - assert inline_query_result_gif.caption_entities == tuple(Space.caption_entities) + 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.thumb_mime_type == self.thumb_mime_type + assert inline_query_result_gif.title == self.title + assert inline_query_result_gif.caption == self.caption + assert inline_query_result_gif.parse_mode == self.parse_mode + assert inline_query_result_gif.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_gif.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_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() @@ -125,11 +125,11 @@ def test_to_dict(self, inline_query_result_gif): ) def test_equality(self): - a = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) - b = InlineQueryResultGif(Space.id_, Space.gif_url, Space.thumb_url) - c = InlineQueryResultGif(Space.id_, "", Space.thumb_url) - d = InlineQueryResultGif("", Space.gif_url, Space.thumb_url) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultlocation.py b/tests/test_inlinequeryresultlocation.py index 4d0eedd3e03..d15688e3417 100644 --- a/tests/test_inlinequeryresultlocation.py +++ b/tests/test_inlinequeryresultlocation.py @@ -30,23 +30,23 @@ @pytest.fixture(scope="module") def inline_query_result_location(): return InlineQueryResultLocation( - Space.id_, - Space.latitude, - Space.longitude, - Space.title, - live_period=Space.live_period, - thumb_url=Space.thumb_url, - thumb_width=Space.thumb_width, - thumb_height=Space.thumb_height, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, - horizontal_accuracy=Space.horizontal_accuracy, - heading=Space.heading, - proximity_alert_radius=Space.proximity_alert_radius, + TestInlineQueryResultLocationBase.id_, + TestInlineQueryResultLocationBase.latitude, + TestInlineQueryResultLocationBase.longitude, + TestInlineQueryResultLocationBase.title, + live_period=TestInlineQueryResultLocationBase.live_period, + thumb_url=TestInlineQueryResultLocationBase.thumb_url, + thumb_width=TestInlineQueryResultLocationBase.thumb_width, + thumb_height=TestInlineQueryResultLocationBase.thumb_height, + input_message_content=TestInlineQueryResultLocationBase.input_message_content, + reply_markup=TestInlineQueryResultLocationBase.reply_markup, + horizontal_accuracy=TestInlineQueryResultLocationBase.horizontal_accuracy, + heading=TestInlineQueryResultLocationBase.heading, + proximity_alert_radius=TestInlineQueryResultLocationBase.proximity_alert_radius, ) -class Space: +class TestInlineQueryResultLocationBase: id_ = "id" type_ = "location" latitude = 0.0 @@ -63,7 +63,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultLocationWithoutRequest: +class TestInlineQueryResultLocationWithoutRequest(TestInlineQueryResultLocationBase): def test_slot_behaviour(self, inline_query_result_location, mro_slots): inst = inline_query_result_location for attr in inst.__slots__: @@ -71,23 +71,23 @@ def test_slot_behaviour(self, inline_query_result_location, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_location): - assert inline_query_result_location.id == Space.id_ - assert inline_query_result_location.type == Space.type_ - assert inline_query_result_location.latitude == Space.latitude - assert inline_query_result_location.longitude == Space.longitude - assert inline_query_result_location.title == Space.title - assert inline_query_result_location.live_period == Space.live_period - assert inline_query_result_location.thumb_url == Space.thumb_url - assert inline_query_result_location.thumb_width == Space.thumb_width - assert inline_query_result_location.thumb_height == Space.thumb_height + 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.live_period == self.live_period + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_location.reply_markup.to_dict() == Space.reply_markup.to_dict() - assert inline_query_result_location.heading == Space.heading - assert inline_query_result_location.horizontal_accuracy == Space.horizontal_accuracy - assert inline_query_result_location.proximity_alert_radius == Space.proximity_alert_radius + assert inline_query_result_location.reply_markup.to_dict() == self.reply_markup.to_dict() + assert inline_query_result_location.heading == self.heading + assert inline_query_result_location.horizontal_accuracy == self.horizontal_accuracy + assert inline_query_result_location.proximity_alert_radius == self.proximity_alert_radius def test_to_dict(self, inline_query_result_location): inline_query_result_location_dict = inline_query_result_location.to_dict() @@ -138,11 +138,11 @@ def test_to_dict(self, inline_query_result_location): ) def test_equality(self): - a = InlineQueryResultLocation(Space.id_, Space.longitude, Space.latitude, Space.title) - b = InlineQueryResultLocation(Space.id_, Space.longitude, Space.latitude, Space.title) - c = InlineQueryResultLocation(Space.id_, 0, Space.latitude, Space.title) - d = InlineQueryResultLocation("", Space.longitude, Space.latitude, Space.title) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultmpeg4gif.py b/tests/test_inlinequeryresultmpeg4gif.py index 7ab728c22b3..ae1210c89b4 100644 --- a/tests/test_inlinequeryresultmpeg4gif.py +++ b/tests/test_inlinequeryresultmpeg4gif.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="module") def inline_query_result_mpeg4_gif(): return InlineQueryResultMpeg4Gif( - Space.id_, - Space.mpeg4_url, - Space.thumb_url, - mpeg4_width=Space.mpeg4_width, - mpeg4_height=Space.mpeg4_height, - mpeg4_duration=Space.mpeg4_duration, - title=Space.title, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, - thumb_mime_type=Space.thumb_mime_type, + TestInlineQueryResultMpeg4GifBase.id_, + TestInlineQueryResultMpeg4GifBase.mpeg4_url, + TestInlineQueryResultMpeg4GifBase.thumb_url, + mpeg4_width=TestInlineQueryResultMpeg4GifBase.mpeg4_width, + mpeg4_height=TestInlineQueryResultMpeg4GifBase.mpeg4_height, + mpeg4_duration=TestInlineQueryResultMpeg4GifBase.mpeg4_duration, + title=TestInlineQueryResultMpeg4GifBase.title, + caption=TestInlineQueryResultMpeg4GifBase.caption, + parse_mode=TestInlineQueryResultMpeg4GifBase.parse_mode, + caption_entities=TestInlineQueryResultMpeg4GifBase.caption_entities, + input_message_content=TestInlineQueryResultMpeg4GifBase.input_message_content, + reply_markup=TestInlineQueryResultMpeg4GifBase.reply_markup, + thumb_mime_type=TestInlineQueryResultMpeg4GifBase.thumb_mime_type, ) -class Space: +class TestInlineQueryResultMpeg4GifBase: id_ = "id" type_ = "mpeg4_gif" mpeg4_url = "mpeg4 url" @@ -64,7 +64,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultMpeg4GifWithoutRequest: +class TestInlineQueryResultMpeg4GifWithoutRequest(TestInlineQueryResultMpeg4GifBase): def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): inst = inline_query_result_mpeg4_gif for attr in inst.__slots__: @@ -72,26 +72,26 @@ def test_slot_behaviour(self, inline_query_result_mpeg4_gif, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_mpeg4_gif): - assert inline_query_result_mpeg4_gif.type == Space.type_ - assert inline_query_result_mpeg4_gif.id == Space.id_ - assert inline_query_result_mpeg4_gif.mpeg4_url == Space.mpeg4_url - assert inline_query_result_mpeg4_gif.mpeg4_width == Space.mpeg4_width - assert inline_query_result_mpeg4_gif.mpeg4_height == Space.mpeg4_height - assert inline_query_result_mpeg4_gif.mpeg4_duration == Space.mpeg4_duration - assert inline_query_result_mpeg4_gif.thumb_url == Space.thumb_url - assert inline_query_result_mpeg4_gif.thumb_mime_type == Space.thumb_mime_type - assert inline_query_result_mpeg4_gif.title == Space.title - assert inline_query_result_mpeg4_gif.caption == Space.caption - assert inline_query_result_mpeg4_gif.parse_mode == Space.parse_mode - assert inline_query_result_mpeg4_gif.caption_entities == tuple(Space.caption_entities) + 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.thumb_mime_type == self.thumb_mime_type + assert inline_query_result_mpeg4_gif.title == self.title + assert inline_query_result_mpeg4_gif.caption == self.caption + assert inline_query_result_mpeg4_gif.parse_mode == self.parse_mode + assert inline_query_result_mpeg4_gif.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_mpeg4_gif.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_mpeg4_gif.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) + result = InlineQueryResultMpeg4Gif(self.id_, self.mpeg4_url, self.thumb_url) assert result.caption_entities == () def test_to_dict(self, inline_query_result_mpeg4_gif): @@ -145,11 +145,11 @@ def test_to_dict(self, inline_query_result_mpeg4_gif): ) def test_equality(self): - a = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) - b = InlineQueryResultMpeg4Gif(Space.id_, Space.mpeg4_url, Space.thumb_url) - c = InlineQueryResultMpeg4Gif(Space.id_, "", Space.thumb_url) - d = InlineQueryResultMpeg4Gif("", Space.mpeg4_url, Space.thumb_url) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultphoto.py b/tests/test_inlinequeryresultphoto.py index 99e02bf2e1f..e6944f3b383 100644 --- a/tests/test_inlinequeryresultphoto.py +++ b/tests/test_inlinequeryresultphoto.py @@ -31,22 +31,22 @@ @pytest.fixture(scope="module") def inline_query_result_photo(): return InlineQueryResultPhoto( - Space.id_, - Space.photo_url, - Space.thumb_url, - photo_width=Space.photo_width, - photo_height=Space.photo_height, - title=Space.title, - description=Space.description, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultPhotoBase.id_, + TestInlineQueryResultPhotoBase.photo_url, + TestInlineQueryResultPhotoBase.thumb_url, + photo_width=TestInlineQueryResultPhotoBase.photo_width, + photo_height=TestInlineQueryResultPhotoBase.photo_height, + title=TestInlineQueryResultPhotoBase.title, + description=TestInlineQueryResultPhotoBase.description, + caption=TestInlineQueryResultPhotoBase.caption, + parse_mode=TestInlineQueryResultPhotoBase.parse_mode, + caption_entities=TestInlineQueryResultPhotoBase.caption_entities, + input_message_content=TestInlineQueryResultPhotoBase.input_message_content, + reply_markup=TestInlineQueryResultPhotoBase.reply_markup, ) -class Space: +class TestInlineQueryResultPhotoBase: id_ = "id" type_ = "photo" photo_url = "photo url" @@ -63,7 +63,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultPhotoWithoutRequest: +class TestInlineQueryResultPhotoWithoutRequest(TestInlineQueryResultPhotoBase): def test_slot_behaviour(self, inline_query_result_photo, mro_slots): inst = inline_query_result_photo for attr in inst.__slots__: @@ -71,25 +71,25 @@ def test_slot_behaviour(self, inline_query_result_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_photo): - assert inline_query_result_photo.type == Space.type_ - assert inline_query_result_photo.id == Space.id_ - assert inline_query_result_photo.photo_url == Space.photo_url - assert inline_query_result_photo.photo_width == Space.photo_width - assert inline_query_result_photo.photo_height == Space.photo_height - assert inline_query_result_photo.thumb_url == Space.thumb_url - assert inline_query_result_photo.title == Space.title - assert inline_query_result_photo.description == Space.description - assert inline_query_result_photo.caption == Space.caption - assert inline_query_result_photo.parse_mode == Space.parse_mode - assert inline_query_result_photo.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_photo.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_photo.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_photo.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_photo.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): - result = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) + result = InlineQueryResultPhoto(self.id_, self.photo_url, self.thumb_url) assert result.caption_entities == () def test_to_dict(self, inline_query_result_photo): @@ -126,11 +126,11 @@ def test_to_dict(self, inline_query_result_photo): ) def test_equality(self): - a = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) - b = InlineQueryResultPhoto(Space.id_, Space.photo_url, Space.thumb_url) - c = InlineQueryResultPhoto(Space.id_, "", Space.thumb_url) - d = InlineQueryResultPhoto("", Space.photo_url, Space.thumb_url) - e = InlineQueryResultVoice(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvenue.py b/tests/test_inlinequeryresultvenue.py index fdd5ba907a5..7592bfdf064 100644 --- a/tests/test_inlinequeryresultvenue.py +++ b/tests/test_inlinequeryresultvenue.py @@ -30,24 +30,24 @@ @pytest.fixture(scope="module") def inline_query_result_venue(): return InlineQueryResultVenue( - Space.id_, - Space.latitude, - Space.longitude, - Space.title, - Space.address, - foursquare_id=Space.foursquare_id, - foursquare_type=Space.foursquare_type, - thumb_url=Space.thumb_url, - thumb_width=Space.thumb_width, - thumb_height=Space.thumb_height, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, - google_place_id=Space.google_place_id, - google_place_type=Space.google_place_type, + TestInlineQueryResultVenueBase.id_, + TestInlineQueryResultVenueBase.latitude, + TestInlineQueryResultVenueBase.longitude, + TestInlineQueryResultVenueBase.title, + TestInlineQueryResultVenueBase.address, + foursquare_id=TestInlineQueryResultVenueBase.foursquare_id, + foursquare_type=TestInlineQueryResultVenueBase.foursquare_type, + thumb_url=TestInlineQueryResultVenueBase.thumb_url, + thumb_width=TestInlineQueryResultVenueBase.thumb_width, + thumb_height=TestInlineQueryResultVenueBase.thumb_height, + input_message_content=TestInlineQueryResultVenueBase.input_message_content, + reply_markup=TestInlineQueryResultVenueBase.reply_markup, + google_place_id=TestInlineQueryResultVenueBase.google_place_id, + google_place_type=TestInlineQueryResultVenueBase.google_place_type, ) -class Space: +class TestInlineQueryResultVenueBase: id_ = "id" type_ = "venue" latitude = "latitude" @@ -65,7 +65,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVenueWithoutRequest: +class TestInlineQueryResultVenueWithoutRequest(TestInlineQueryResultVenueBase): def test_slot_behaviour(self, inline_query_result_venue, mro_slots): inst = inline_query_result_venue for attr in inst.__slots__: @@ -73,24 +73,24 @@ def test_slot_behaviour(self, inline_query_result_venue, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_venue): - assert inline_query_result_venue.id == Space.id_ - assert inline_query_result_venue.type == Space.type_ - assert inline_query_result_venue.latitude == Space.latitude - assert inline_query_result_venue.longitude == Space.longitude - assert inline_query_result_venue.title == Space.title - assert inline_query_result_venue.address == Space.address - assert inline_query_result_venue.foursquare_id == Space.foursquare_id - assert inline_query_result_venue.foursquare_type == Space.foursquare_type - assert inline_query_result_venue.google_place_id == Space.google_place_id - assert inline_query_result_venue.google_place_type == Space.google_place_type - assert inline_query_result_venue.thumb_url == Space.thumb_url - assert inline_query_result_venue.thumb_width == Space.thumb_width - assert inline_query_result_venue.thumb_height == Space.thumb_height + 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.foursquare_type == self.foursquare_type + assert inline_query_result_venue.google_place_id == self.google_place_id + assert inline_query_result_venue.google_place_type == self.google_place_type + 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() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_venue.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_venue.reply_markup.to_dict() == self.reply_markup.to_dict() def test_to_dict(self, inline_query_result_venue): inline_query_result_venue_dict = inline_query_result_venue.to_dict() @@ -137,14 +137,14 @@ def test_to_dict(self, inline_query_result_venue): def test_equality(self): a = InlineQueryResultVenue( - Space.id_, Space.longitude, Space.latitude, Space.title, Space.address + self.id_, self.longitude, self.latitude, self.title, self.address ) b = InlineQueryResultVenue( - Space.id_, Space.longitude, Space.latitude, Space.title, Space.address + self.id_, self.longitude, self.latitude, self.title, self.address ) - c = InlineQueryResultVenue(Space.id_, "", Space.latitude, Space.title, Space.address) - d = InlineQueryResultVenue("", Space.longitude, Space.latitude, Space.title, Space.address) - e = InlineQueryResultVoice(Space.id_, "", "") + c = InlineQueryResultVenue(self.id_, "", self.latitude, self.title, self.address) + d = InlineQueryResultVenue("", self.longitude, self.latitude, self.title, self.address) + e = InlineQueryResultVoice(self.id_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvideo.py b/tests/test_inlinequeryresultvideo.py index 23fb1ee65cd..3e8edf76ed8 100644 --- a/tests/test_inlinequeryresultvideo.py +++ b/tests/test_inlinequeryresultvideo.py @@ -31,24 +31,24 @@ @pytest.fixture(scope="module") def inline_query_result_video(): return InlineQueryResultVideo( - Space.id_, - Space.video_url, - Space.mime_type, - Space.thumb_url, - Space.title, - video_width=Space.video_width, - video_height=Space.video_height, - video_duration=Space.video_duration, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - description=Space.description, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + TestInlineQueryResultVideoBase.id_, + TestInlineQueryResultVideoBase.video_url, + TestInlineQueryResultVideoBase.mime_type, + TestInlineQueryResultVideoBase.thumb_url, + TestInlineQueryResultVideoBase.title, + video_width=TestInlineQueryResultVideoBase.video_width, + video_height=TestInlineQueryResultVideoBase.video_height, + video_duration=TestInlineQueryResultVideoBase.video_duration, + caption=TestInlineQueryResultVideoBase.caption, + parse_mode=TestInlineQueryResultVideoBase.parse_mode, + caption_entities=TestInlineQueryResultVideoBase.caption_entities, + description=TestInlineQueryResultVideoBase.description, + input_message_content=TestInlineQueryResultVideoBase.input_message_content, + reply_markup=TestInlineQueryResultVideoBase.reply_markup, ) -class Space: +class TestInlineQueryResultVideoBase: id_ = "id" type_ = "video" video_url = "video url" @@ -66,7 +66,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVideoWithoutRequest: +class TestInlineQueryResultVideoWithoutRequest(TestInlineQueryResultVideoBase): def test_slot_behaviour(self, inline_query_result_video, mro_slots): inst = inline_query_result_video for attr in inst.__slots__: @@ -74,28 +74,28 @@ def test_slot_behaviour(self, inline_query_result_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_video): - assert inline_query_result_video.type == Space.type_ - assert inline_query_result_video.id == Space.id_ - assert inline_query_result_video.video_url == Space.video_url - assert inline_query_result_video.mime_type == Space.mime_type - assert inline_query_result_video.video_width == Space.video_width - assert inline_query_result_video.video_height == Space.video_height - assert inline_query_result_video.video_duration == Space.video_duration - assert inline_query_result_video.thumb_url == Space.thumb_url - assert inline_query_result_video.title == Space.title - assert inline_query_result_video.description == Space.description - assert inline_query_result_video.caption == Space.caption - assert inline_query_result_video.parse_mode == Space.parse_mode - assert inline_query_result_video.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_video.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_video.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_video.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_video.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): video = InlineQueryResultVideo( - Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title + self.id_, self.video_url, self.mime_type, self.thumb_url, self.title ) assert video.caption_entities == () @@ -139,16 +139,14 @@ def test_to_dict(self, inline_query_result_video): def test_equality(self): a = InlineQueryResultVideo( - Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title + self.id_, self.video_url, self.mime_type, self.thumb_url, self.title ) b = InlineQueryResultVideo( - Space.id_, Space.video_url, Space.mime_type, Space.thumb_url, Space.title + self.id_, self.video_url, self.mime_type, self.thumb_url, self.title ) - c = InlineQueryResultVideo(Space.id_, "", Space.mime_type, Space.thumb_url, Space.title) - d = InlineQueryResultVideo( - "", Space.video_url, Space.mime_type, Space.thumb_url, Space.title - ) - e = InlineQueryResultVoice(Space.id_, "", "") + 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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inlinequeryresultvoice.py b/tests/test_inlinequeryresultvoice.py index c0ea7837fe0..8ce2f42dbca 100644 --- a/tests/test_inlinequeryresultvoice.py +++ b/tests/test_inlinequeryresultvoice.py @@ -31,19 +31,19 @@ @pytest.fixture(scope="module") def inline_query_result_voice(): return InlineQueryResultVoice( - id=Space.id_, - voice_url=Space.voice_url, - title=Space.title, - voice_duration=Space.voice_duration, - caption=Space.caption, - parse_mode=Space.parse_mode, - caption_entities=Space.caption_entities, - input_message_content=Space.input_message_content, - reply_markup=Space.reply_markup, + id=TestInlineQueryResultVoiceBase.id_, + voice_url=TestInlineQueryResultVoiceBase.voice_url, + title=TestInlineQueryResultVoiceBase.title, + voice_duration=TestInlineQueryResultVoiceBase.voice_duration, + caption=TestInlineQueryResultVoiceBase.caption, + parse_mode=TestInlineQueryResultVoiceBase.parse_mode, + caption_entities=TestInlineQueryResultVoiceBase.caption_entities, + input_message_content=TestInlineQueryResultVoiceBase.input_message_content, + reply_markup=TestInlineQueryResultVoiceBase.reply_markup, ) -class Space: +class TestInlineQueryResultVoiceBase: id_ = "id" type_ = "voice" voice_url = "voice url" @@ -56,7 +56,7 @@ class Space: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVoiceWithoutRequest: +class TestInlineQueryResultVoiceWithoutRequest(TestInlineQueryResultVoiceBase): def test_slot_behaviour(self, inline_query_result_voice, mro_slots): inst = inline_query_result_voice for attr in inst.__slots__: @@ -64,25 +64,25 @@ def test_slot_behaviour(self, inline_query_result_voice, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, inline_query_result_voice): - assert inline_query_result_voice.type == Space.type_ - assert inline_query_result_voice.id == Space.id_ - assert inline_query_result_voice.voice_url == Space.voice_url - assert inline_query_result_voice.title == Space.title - assert inline_query_result_voice.voice_duration == Space.voice_duration - assert inline_query_result_voice.caption == Space.caption - assert inline_query_result_voice.parse_mode == Space.parse_mode - assert inline_query_result_voice.caption_entities == tuple(Space.caption_entities) + 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.parse_mode == self.parse_mode + assert inline_query_result_voice.caption_entities == tuple(self.caption_entities) assert ( inline_query_result_voice.input_message_content.to_dict() - == Space.input_message_content.to_dict() + == self.input_message_content.to_dict() ) - assert inline_query_result_voice.reply_markup.to_dict() == Space.reply_markup.to_dict() + assert inline_query_result_voice.reply_markup.to_dict() == self.reply_markup.to_dict() def test_caption_entities_always_tuple(self): result = InlineQueryResultVoice( - Space.id_, - Space.voice_url, - Space.title, + self.id_, + self.voice_url, + self.title, ) assert result.caption_entities == () @@ -114,11 +114,11 @@ def test_to_dict(self, inline_query_result_voice): ) def test_equality(self): - a = InlineQueryResultVoice(Space.id_, Space.voice_url, Space.title) - b = InlineQueryResultVoice(Space.id_, Space.voice_url, Space.title) - c = InlineQueryResultVoice(Space.id_, "", Space.title) - d = InlineQueryResultVoice("", Space.voice_url, Space.title) - e = InlineQueryResultAudio(Space.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_, "", "") assert a == b assert hash(a) == hash(b) diff --git a/tests/test_inputcontactmessagecontent.py b/tests/test_inputcontactmessagecontent.py index a4d0ec5f2a7..cd47a2b180b 100644 --- a/tests/test_inputcontactmessagecontent.py +++ b/tests/test_inputcontactmessagecontent.py @@ -23,16 +23,20 @@ @pytest.fixture(scope="module") def input_contact_message_content(): - return InputContactMessageContent(Space.phone_number, Space.first_name, Space.last_name) + return InputContactMessageContent( + TestInputContactMessageContentBase.phone_number, + TestInputContactMessageContentBase.first_name, + TestInputContactMessageContentBase.last_name, + ) -class Space: +class TestInputContactMessageContentBase: phone_number = "phone number" first_name = "first name" last_name = "last name" -class TestInputContactMessageContentWithoutRequest: +class TestInputContactMessageContentWithoutRequest(TestInputContactMessageContentBase): def test_slot_behaviour(self, input_contact_message_content, mro_slots): inst = input_contact_message_content for attr in inst.__slots__: @@ -40,9 +44,9 @@ def test_slot_behaviour(self, input_contact_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_contact_message_content): - assert input_contact_message_content.first_name == Space.first_name - assert input_contact_message_content.phone_number == Space.phone_number - assert input_contact_message_content.last_name == Space.last_name + assert input_contact_message_content.first_name == self.first_name + assert input_contact_message_content.phone_number == self.phone_number + assert input_contact_message_content.last_name == self.last_name def test_to_dict(self, input_contact_message_content): input_contact_message_content_dict = input_contact_message_content.to_dict() diff --git a/tests/test_inputinvoicemessagecontent.py b/tests/test_inputinvoicemessagecontent.py index cd464ec58c2..d7d207575da 100644 --- a/tests/test_inputinvoicemessagecontent.py +++ b/tests/test_inputinvoicemessagecontent.py @@ -25,30 +25,30 @@ @pytest.fixture(scope="module") def input_invoice_message_content(): return InputInvoiceMessageContent( - title=Space.title, - description=Space.description, - payload=Space.payload, - provider_token=Space.provider_token, - currency=Space.currency, - prices=Space.prices, - max_tip_amount=Space.max_tip_amount, - suggested_tip_amounts=Space.suggested_tip_amounts, - provider_data=Space.provider_data, - photo_url=Space.photo_url, - photo_size=Space.photo_size, - photo_width=Space.photo_width, - photo_height=Space.photo_height, - need_name=Space.need_name, - need_phone_number=Space.need_phone_number, - need_email=Space.need_email, - need_shipping_address=Space.need_shipping_address, - send_phone_number_to_provider=Space.send_phone_number_to_provider, - send_email_to_provider=Space.send_email_to_provider, - is_flexible=Space.is_flexible, + title=TestInputInvoiceMessageContentBase.title, + description=TestInputInvoiceMessageContentBase.description, + payload=TestInputInvoiceMessageContentBase.payload, + provider_token=TestInputInvoiceMessageContentBase.provider_token, + currency=TestInputInvoiceMessageContentBase.currency, + prices=TestInputInvoiceMessageContentBase.prices, + max_tip_amount=TestInputInvoiceMessageContentBase.max_tip_amount, + suggested_tip_amounts=TestInputInvoiceMessageContentBase.suggested_tip_amounts, + provider_data=TestInputInvoiceMessageContentBase.provider_data, + photo_url=TestInputInvoiceMessageContentBase.photo_url, + photo_size=TestInputInvoiceMessageContentBase.photo_size, + photo_width=TestInputInvoiceMessageContentBase.photo_width, + photo_height=TestInputInvoiceMessageContentBase.photo_height, + need_name=TestInputInvoiceMessageContentBase.need_name, + need_phone_number=TestInputInvoiceMessageContentBase.need_phone_number, + need_email=TestInputInvoiceMessageContentBase.need_email, + need_shipping_address=TestInputInvoiceMessageContentBase.need_shipping_address, + send_phone_number_to_provider=TestInputInvoiceMessageContentBase.send_phone_number_to_provider, # noqa: E501 + send_email_to_provider=TestInputInvoiceMessageContentBase.send_email_to_provider, + is_flexible=TestInputInvoiceMessageContentBase.is_flexible, ) -class Space: +class TestInputInvoiceMessageContentBase: title = "invoice title" description = "invoice description" payload = "invoice payload" @@ -71,7 +71,7 @@ class Space: is_flexible = True -class TestInputInvoiceMessageContentWithoutRequest: +class TestInputInvoiceMessageContentWithoutRequest(TestInputInvoiceMessageContentBase): def test_slot_behaviour(self, input_invoice_message_content, mro_slots): inst = input_invoice_message_content for attr in inst.__slots__: @@ -79,45 +79,45 @@ def test_slot_behaviour(self, input_invoice_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_invoice_message_content): - assert input_invoice_message_content.title == Space.title - assert input_invoice_message_content.description == Space.description - assert input_invoice_message_content.payload == Space.payload - assert input_invoice_message_content.provider_token == Space.provider_token - assert input_invoice_message_content.currency == Space.currency - assert input_invoice_message_content.prices == tuple(Space.prices) - assert input_invoice_message_content.max_tip_amount == Space.max_tip_amount + assert input_invoice_message_content.title == self.title + assert input_invoice_message_content.description == self.description + assert input_invoice_message_content.payload == self.payload + assert input_invoice_message_content.provider_token == self.provider_token + assert input_invoice_message_content.currency == self.currency + assert input_invoice_message_content.prices == tuple(self.prices) + assert input_invoice_message_content.max_tip_amount == self.max_tip_amount assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in Space.suggested_tip_amounts + int(amount) for amount in self.suggested_tip_amounts ) - assert input_invoice_message_content.provider_data == Space.provider_data - assert input_invoice_message_content.photo_url == Space.photo_url - assert input_invoice_message_content.photo_size == int(Space.photo_size) - assert input_invoice_message_content.photo_width == int(Space.photo_width) - assert input_invoice_message_content.photo_height == int(Space.photo_height) - assert input_invoice_message_content.need_name == Space.need_name - assert input_invoice_message_content.need_phone_number == Space.need_phone_number - assert input_invoice_message_content.need_email == Space.need_email - assert input_invoice_message_content.need_shipping_address == Space.need_shipping_address + assert input_invoice_message_content.provider_data == self.provider_data + assert input_invoice_message_content.photo_url == self.photo_url + assert input_invoice_message_content.photo_size == int(self.photo_size) + assert input_invoice_message_content.photo_width == int(self.photo_width) + assert input_invoice_message_content.photo_height == int(self.photo_height) + assert input_invoice_message_content.need_name == self.need_name + assert input_invoice_message_content.need_phone_number == self.need_phone_number + assert input_invoice_message_content.need_email == self.need_email + assert input_invoice_message_content.need_shipping_address == self.need_shipping_address assert ( input_invoice_message_content.send_phone_number_to_provider - == Space.send_phone_number_to_provider + == self.send_phone_number_to_provider ) - assert input_invoice_message_content.send_email_to_provider == Space.send_email_to_provider - assert input_invoice_message_content.is_flexible == Space.is_flexible + assert input_invoice_message_content.send_email_to_provider == self.send_email_to_provider + assert input_invoice_message_content.is_flexible == self.is_flexible def test_suggested_tip_amonuts_always_tuple(self, input_invoice_message_content): assert isinstance(input_invoice_message_content.suggested_tip_amounts, tuple) assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in Space.suggested_tip_amounts + int(amount) for amount in self.suggested_tip_amounts ) input_invoice_message_content = InputInvoiceMessageContent( - title=Space.title, - description=Space.description, - payload=Space.payload, - provider_token=Space.provider_token, - currency=Space.currency, - prices=Space.prices, + title=self.title, + description=self.description, + payload=self.payload, + provider_token=self.provider_token, + currency=self.currency, + prices=self.prices, ) assert input_invoice_message_content.suggested_tip_amounts == tuple() @@ -204,92 +204,92 @@ def test_de_json(self, bot): assert InputInvoiceMessageContent.de_json({}, bot=bot) is None json_dict = { - "title": Space.title, - "description": Space.description, - "payload": Space.payload, - "provider_token": Space.provider_token, - "currency": Space.currency, - "prices": [price.to_dict() for price in Space.prices], - "max_tip_amount": Space.max_tip_amount, - "suggested_tip_amounts": Space.suggested_tip_amounts, - "provider_data": Space.provider_data, - "photo_url": Space.photo_url, - "photo_size": Space.photo_size, - "photo_width": Space.photo_width, - "photo_height": Space.photo_height, - "need_name": Space.need_name, - "need_phone_number": Space.need_phone_number, - "need_email": Space.need_email, - "need_shipping_address": Space.need_shipping_address, - "send_phone_number_to_provider": Space.send_phone_number_to_provider, - "send_email_to_provider": Space.send_email_to_provider, - "is_flexible": Space.is_flexible, + "title": self.title, + "description": self.description, + "payload": self.payload, + "provider_token": self.provider_token, + "currency": self.currency, + "prices": [price.to_dict() for price in self.prices], + "max_tip_amount": self.max_tip_amount, + "suggested_tip_amounts": self.suggested_tip_amounts, + "provider_data": self.provider_data, + "photo_url": self.photo_url, + "photo_size": self.photo_size, + "photo_width": self.photo_width, + "photo_height": self.photo_height, + "need_name": self.need_name, + "need_phone_number": self.need_phone_number, + "need_email": self.need_email, + "need_shipping_address": self.need_shipping_address, + "send_phone_number_to_provider": self.send_phone_number_to_provider, + "send_email_to_provider": self.send_email_to_provider, + "is_flexible": self.is_flexible, } input_invoice_message_content = InputInvoiceMessageContent.de_json(json_dict, bot=bot) assert input_invoice_message_content.api_kwargs == {} - assert input_invoice_message_content.title == Space.title - assert input_invoice_message_content.description == Space.description - assert input_invoice_message_content.payload == Space.payload - assert input_invoice_message_content.provider_token == Space.provider_token - assert input_invoice_message_content.currency == Space.currency - assert input_invoice_message_content.prices == tuple(Space.prices) - assert input_invoice_message_content.max_tip_amount == Space.max_tip_amount + assert input_invoice_message_content.title == self.title + assert input_invoice_message_content.description == self.description + assert input_invoice_message_content.payload == self.payload + assert input_invoice_message_content.provider_token == self.provider_token + assert input_invoice_message_content.currency == self.currency + assert input_invoice_message_content.prices == tuple(self.prices) + assert input_invoice_message_content.max_tip_amount == self.max_tip_amount assert input_invoice_message_content.suggested_tip_amounts == tuple( - int(amount) for amount in Space.suggested_tip_amounts + int(amount) for amount in self.suggested_tip_amounts ) - assert input_invoice_message_content.provider_data == Space.provider_data - assert input_invoice_message_content.photo_url == Space.photo_url - assert input_invoice_message_content.photo_size == int(Space.photo_size) - assert input_invoice_message_content.photo_width == int(Space.photo_width) - assert input_invoice_message_content.photo_height == int(Space.photo_height) - assert input_invoice_message_content.need_name == Space.need_name - assert input_invoice_message_content.need_phone_number == Space.need_phone_number - assert input_invoice_message_content.need_email == Space.need_email - assert input_invoice_message_content.need_shipping_address == Space.need_shipping_address + assert input_invoice_message_content.provider_data == self.provider_data + assert input_invoice_message_content.photo_url == self.photo_url + assert input_invoice_message_content.photo_size == int(self.photo_size) + assert input_invoice_message_content.photo_width == int(self.photo_width) + assert input_invoice_message_content.photo_height == int(self.photo_height) + assert input_invoice_message_content.need_name == self.need_name + assert input_invoice_message_content.need_phone_number == self.need_phone_number + assert input_invoice_message_content.need_email == self.need_email + assert input_invoice_message_content.need_shipping_address == self.need_shipping_address assert ( input_invoice_message_content.send_phone_number_to_provider - == Space.send_phone_number_to_provider + == self.send_phone_number_to_provider ) - assert input_invoice_message_content.send_email_to_provider == Space.send_email_to_provider - assert input_invoice_message_content.is_flexible == Space.is_flexible + assert input_invoice_message_content.send_email_to_provider == self.send_email_to_provider + assert input_invoice_message_content.is_flexible == self.is_flexible def test_equality(self): a = InputInvoiceMessageContent( - Space.title, - Space.description, - Space.payload, - Space.provider_token, - Space.currency, - Space.prices, + self.title, + self.description, + self.payload, + self.provider_token, + self.currency, + self.prices, ) b = InputInvoiceMessageContent( - Space.title, - Space.description, - Space.payload, - Space.provider_token, - Space.currency, - Space.prices, + self.title, + self.description, + self.payload, + self.provider_token, + self.currency, + self.prices, max_tip_amount=100, provider_data="foobar", ) c = InputInvoiceMessageContent( - Space.title, - Space.description, - Space.payload, - Space.provider_token, - Space.currency, + self.title, + self.description, + self.payload, + self.provider_token, + self.currency, # the first prices amount & the second lebal changed [LabeledPrice("label1", 24), LabeledPrice("label22", 314)], ) d = InputInvoiceMessageContent( - Space.title, - Space.description, + self.title, + self.description, "different_payload", - Space.provider_token, - Space.currency, - Space.prices, + self.provider_token, + self.currency, + self.prices, ) e = InputTextMessageContent("text") diff --git a/tests/test_inputlocationmessagecontent.py b/tests/test_inputlocationmessagecontent.py index 2df1a289d2e..a9e776cb655 100644 --- a/tests/test_inputlocationmessagecontent.py +++ b/tests/test_inputlocationmessagecontent.py @@ -24,16 +24,16 @@ @pytest.fixture(scope="module") def input_location_message_content(): return InputLocationMessageContent( - Space.latitude, - Space.longitude, - live_period=Space.live_period, - horizontal_accuracy=Space.horizontal_accuracy, - heading=Space.heading, - proximity_alert_radius=Space.proximity_alert_radius, + TestInputLocationMessageContentBase.latitude, + TestInputLocationMessageContentBase.longitude, + live_period=TestInputLocationMessageContentBase.live_period, + horizontal_accuracy=TestInputLocationMessageContentBase.horizontal_accuracy, + heading=TestInputLocationMessageContentBase.heading, + proximity_alert_radius=TestInputLocationMessageContentBase.proximity_alert_radius, ) -class Space: +class TestInputLocationMessageContentBase: latitude = -23.691288 longitude = -46.788279 live_period = 80 @@ -42,7 +42,7 @@ class Space: proximity_alert_radius = 999 -class TestInputLocationMessageContentWithoutRequest: +class TestInputLocationMessageContentWithoutRequest(TestInputLocationMessageContentBase): def test_slot_behaviour(self, input_location_message_content, mro_slots): inst = input_location_message_content for attr in inst.__slots__: @@ -50,14 +50,12 @@ def test_slot_behaviour(self, input_location_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_location_message_content): - assert input_location_message_content.longitude == Space.longitude - assert input_location_message_content.latitude == Space.latitude - assert input_location_message_content.live_period == Space.live_period - assert input_location_message_content.horizontal_accuracy == Space.horizontal_accuracy - assert input_location_message_content.heading == Space.heading - assert ( - input_location_message_content.proximity_alert_radius == Space.proximity_alert_radius - ) + assert input_location_message_content.longitude == self.longitude + assert input_location_message_content.latitude == self.latitude + assert input_location_message_content.live_period == self.live_period + assert input_location_message_content.horizontal_accuracy == self.horizontal_accuracy + assert input_location_message_content.heading == self.heading + assert input_location_message_content.proximity_alert_radius == self.proximity_alert_radius def test_to_dict(self, input_location_message_content): input_location_message_content_dict = input_location_message_content.to_dict() diff --git a/tests/test_inputmedia.py b/tests/test_inputmedia.py index caeae0c350e..585e3a581a6 100644 --- a/tests/test_inputmedia.py +++ b/tests/test_inputmedia.py @@ -60,72 +60,72 @@ @pytest.fixture(scope="module") def input_media_video(class_thumb_file): return InputMediaVideo( - media=VideoSpace.media, - caption=VideoSpace.caption, - width=VideoSpace.width, - height=VideoSpace.height, - duration=VideoSpace.duration, - parse_mode=VideoSpace.parse_mode, - caption_entities=VideoSpace.caption_entities, + media=TestInputMediaVideoBase.media, + caption=TestInputMediaVideoBase.caption, + width=TestInputMediaVideoBase.width, + height=TestInputMediaVideoBase.height, + duration=TestInputMediaVideoBase.duration, + parse_mode=TestInputMediaVideoBase.parse_mode, + caption_entities=TestInputMediaVideoBase.caption_entities, thumb=class_thumb_file, - supports_streaming=VideoSpace.supports_streaming, - has_spoiler=VideoSpace.has_spoiler, + supports_streaming=TestInputMediaVideoBase.supports_streaming, + has_spoiler=TestInputMediaVideoBase.has_spoiler, ) @pytest.fixture(scope="module") def input_media_photo(): return InputMediaPhoto( - media=PhotoSpace.media, - caption=PhotoSpace.caption, - parse_mode=PhotoSpace.parse_mode, - caption_entities=PhotoSpace.caption_entities, - has_spoiler=PhotoSpace.has_spoiler, + media=TestInputMediaPhotoBase.media, + caption=TestInputMediaPhotoBase.caption, + parse_mode=TestInputMediaPhotoBase.parse_mode, + caption_entities=TestInputMediaPhotoBase.caption_entities, + has_spoiler=TestInputMediaPhotoBase.has_spoiler, ) @pytest.fixture(scope="module") def input_media_animation(class_thumb_file): return InputMediaAnimation( - media=AnimationSpace.media, - caption=AnimationSpace.caption, - parse_mode=AnimationSpace.parse_mode, - caption_entities=AnimationSpace.caption_entities, - width=AnimationSpace.width, - height=AnimationSpace.height, + media=TestInputMediaAnimationBase.media, + caption=TestInputMediaAnimationBase.caption, + parse_mode=TestInputMediaAnimationBase.parse_mode, + caption_entities=TestInputMediaAnimationBase.caption_entities, + width=TestInputMediaAnimationBase.width, + height=TestInputMediaAnimationBase.height, thumb=class_thumb_file, - duration=AnimationSpace.duration, - has_spoiler=AnimationSpace.has_spoiler, + duration=TestInputMediaAnimationBase.duration, + has_spoiler=TestInputMediaAnimationBase.has_spoiler, ) @pytest.fixture(scope="module") def input_media_audio(class_thumb_file): return InputMediaAudio( - media=AudioSpace.media, - caption=AudioSpace.caption, - duration=AudioSpace.duration, - performer=AudioSpace.performer, - title=AudioSpace.title, + media=TestInputMediaAudioBase.media, + caption=TestInputMediaAudioBase.caption, + duration=TestInputMediaAudioBase.duration, + performer=TestInputMediaAudioBase.performer, + title=TestInputMediaAudioBase.title, thumb=class_thumb_file, - parse_mode=AudioSpace.parse_mode, - caption_entities=AudioSpace.caption_entities, + parse_mode=TestInputMediaAudioBase.parse_mode, + caption_entities=TestInputMediaAudioBase.caption_entities, ) @pytest.fixture(scope="module") def input_media_document(class_thumb_file): return InputMediaDocument( - media=DocumentSpace.media, - caption=DocumentSpace.caption, + media=TestInputMediaDocumentBase.media, + caption=TestInputMediaDocumentBase.caption, thumb=class_thumb_file, - parse_mode=DocumentSpace.parse_mode, - caption_entities=DocumentSpace.caption_entities, - disable_content_type_detection=DocumentSpace.disable_content_type_detection, + parse_mode=TestInputMediaDocumentBase.parse_mode, + caption_entities=TestInputMediaDocumentBase.caption_entities, + disable_content_type_detection=TestInputMediaDocumentBase.disable_content_type_detection, ) -class VideoSpace: +class TestInputMediaVideoBase: type_ = "video" media = "NOTAREALFILEID" caption = "My Caption" @@ -138,7 +138,7 @@ class VideoSpace: has_spoiler = True -class TestInputMediaVideoWithoutRequest: +class TestInputMediaVideoWithoutRequest(TestInputMediaVideoBase): def test_slot_behaviour(self, input_media_video, mro_slots): inst = input_media_video for attr in inst.__slots__: @@ -146,20 +146,20 @@ def test_slot_behaviour(self, input_media_video, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_video): - assert input_media_video.type == VideoSpace.type_ - assert input_media_video.media == VideoSpace.media - assert input_media_video.caption == VideoSpace.caption - assert input_media_video.width == VideoSpace.width - assert input_media_video.height == VideoSpace.height - assert input_media_video.duration == VideoSpace.duration - assert input_media_video.parse_mode == VideoSpace.parse_mode - assert input_media_video.caption_entities == tuple(VideoSpace.caption_entities) - assert input_media_video.supports_streaming == VideoSpace.supports_streaming + assert input_media_video.type == self.type_ + assert input_media_video.media == self.media + assert input_media_video.caption == self.caption + assert input_media_video.width == self.width + assert input_media_video.height == self.height + assert input_media_video.duration == self.duration + assert input_media_video.parse_mode == self.parse_mode + assert input_media_video.caption_entities == tuple(self.caption_entities) + assert input_media_video.supports_streaming == self.supports_streaming assert isinstance(input_media_video.thumb, InputFile) - assert input_media_video.has_spoiler == VideoSpace.has_spoiler + assert input_media_video.has_spoiler == self.has_spoiler def test_caption_entities_always_tuple(self): - input_media_video = InputMediaVideo(VideoSpace.media) + input_media_video = InputMediaVideo(self.media) assert input_media_video.caption_entities == () def test_to_dict(self, input_media_video): @@ -180,7 +180,7 @@ def test_to_dict(self, input_media_video): def test_with_video(self, video): # noqa: F811 # fixture found in test_video input_media_video = InputMediaVideo(video, caption="test 3") - assert input_media_video.type == VideoSpace.type_ + assert input_media_video.type == self.type_ assert input_media_video.media == video.file_id assert input_media_video.width == video.width assert input_media_video.height == video.height @@ -190,7 +190,7 @@ def test_with_video(self, video): # noqa: F811 def test_with_video_file(self, video_file): # noqa: F811 # fixture found in test_video input_media_video = InputMediaVideo(video_file, caption="test 3") - assert input_media_video.type == VideoSpace.type_ + assert input_media_video.type == self.type_ assert isinstance(input_media_video.media, InputFile) assert input_media_video.caption == "test 3" @@ -202,7 +202,7 @@ def test_with_local_files(self): assert input_media_video.thumb == data_file("telegram.jpg").as_uri() -class PhotoSpace: +class TestInputMediaPhotoBase: type_ = "photo" media = "NOTAREALFILEID" caption = "My Caption" @@ -211,7 +211,7 @@ class PhotoSpace: has_spoiler = True -class TestInputMediaPhotoWithoutRequest: +class TestInputMediaPhotoWithoutRequest(TestInputMediaPhotoBase): def test_slot_behaviour(self, input_media_photo, mro_slots): inst = input_media_photo for attr in inst.__slots__: @@ -219,15 +219,15 @@ def test_slot_behaviour(self, input_media_photo, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_photo): - assert input_media_photo.type == PhotoSpace.type_ - assert input_media_photo.media == PhotoSpace.media - assert input_media_photo.caption == PhotoSpace.caption - assert input_media_photo.parse_mode == PhotoSpace.parse_mode - assert input_media_photo.caption_entities == tuple(PhotoSpace.caption_entities) - assert input_media_photo.has_spoiler == PhotoSpace.has_spoiler + assert input_media_photo.type == self.type_ + assert input_media_photo.media == self.media + assert input_media_photo.caption == self.caption + assert input_media_photo.parse_mode == self.parse_mode + assert input_media_photo.caption_entities == tuple(self.caption_entities) + assert input_media_photo.has_spoiler == self.has_spoiler def test_caption_entities_always_tuple(self): - input_media_photo = InputMediaPhoto(PhotoSpace.media) + input_media_photo = InputMediaPhoto(self.media) assert input_media_photo.caption_entities == () def test_to_dict(self, input_media_photo): @@ -244,14 +244,14 @@ def test_to_dict(self, input_media_photo): def test_with_photo(self, photo): # noqa: F811 # fixture found in test_photo input_media_photo = InputMediaPhoto(photo, caption="test 2") - assert input_media_photo.type == PhotoSpace.type_ + assert input_media_photo.type == self.type_ assert input_media_photo.media == photo.file_id assert input_media_photo.caption == "test 2" def test_with_photo_file(self, photo_file): # noqa: F811 # fixture found in test_photo input_media_photo = InputMediaPhoto(photo_file, caption="test 2") - assert input_media_photo.type == PhotoSpace.type_ + assert input_media_photo.type == self.type_ assert isinstance(input_media_photo.media, InputFile) assert input_media_photo.caption == "test 2" @@ -260,7 +260,7 @@ def test_with_local_files(self): assert input_media_photo.media == data_file("telegram.mp4").as_uri() -class AnimationSpace: +class TestInputMediaAnimationBase: type_ = "animation" media = "NOTAREALFILEID" caption = "My Caption" @@ -272,7 +272,7 @@ class AnimationSpace: has_spoiler = True -class TestInputMediaAnimationWithoutRequest: +class TestInputMediaAnimationWithoutRequest(TestInputMediaAnimationBase): def test_slot_behaviour(self, input_media_animation, mro_slots): inst = input_media_animation for attr in inst.__slots__: @@ -280,16 +280,16 @@ def test_slot_behaviour(self, input_media_animation, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_animation): - assert input_media_animation.type == AnimationSpace.type_ - assert input_media_animation.media == AnimationSpace.media - assert input_media_animation.caption == AnimationSpace.caption - assert input_media_animation.parse_mode == AnimationSpace.parse_mode - assert input_media_animation.caption_entities == tuple(AnimationSpace.caption_entities) + assert input_media_animation.type == self.type_ + assert input_media_animation.media == self.media + assert input_media_animation.caption == self.caption + assert input_media_animation.parse_mode == self.parse_mode + assert input_media_animation.caption_entities == tuple(self.caption_entities) assert isinstance(input_media_animation.thumb, InputFile) - assert input_media_animation.has_spoiler == AnimationSpace.has_spoiler + assert input_media_animation.has_spoiler == self.has_spoiler def test_caption_entities_always_tuple(self): - input_media_animation = InputMediaAnimation(AnimationSpace.media) + input_media_animation = InputMediaAnimation(self.media) assert input_media_animation.caption_entities == () def test_to_dict(self, input_media_animation): @@ -309,14 +309,14 @@ def test_to_dict(self, input_media_animation): def test_with_animation(self, animation): # noqa: F811 # fixture found in test_animation input_media_animation = InputMediaAnimation(animation, caption="test 2") - assert input_media_animation.type == AnimationSpace.type_ + assert input_media_animation.type == self.type_ assert input_media_animation.media == animation.file_id assert input_media_animation.caption == "test 2" def test_with_animation_file(self, animation_file): # noqa: F811 # fixture found in test_animation input_media_animation = InputMediaAnimation(animation_file, caption="test 2") - assert input_media_animation.type == AnimationSpace.type_ + assert input_media_animation.type == self.type_ assert isinstance(input_media_animation.media, InputFile) assert input_media_animation.caption == "test 2" @@ -328,7 +328,7 @@ def test_with_local_files(self): assert input_media_animation.thumb == data_file("telegram.jpg").as_uri() -class AudioSpace: +class TestInputMediaAudioBase: type_ = "audio" media = "NOTAREALFILEID" caption = "My Caption" @@ -339,7 +339,7 @@ class AudioSpace: caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] -class TestInputMediaAudioWithoutRequest: +class TestInputMediaAudioWithoutRequest(TestInputMediaAudioBase): def test_slot_behaviour(self, input_media_audio, mro_slots): inst = input_media_audio for attr in inst.__slots__: @@ -347,18 +347,18 @@ def test_slot_behaviour(self, input_media_audio, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_audio): - assert input_media_audio.type == AudioSpace.type_ - assert input_media_audio.media == AudioSpace.media - assert input_media_audio.caption == AudioSpace.caption - assert input_media_audio.duration == AudioSpace.duration - assert input_media_audio.performer == AudioSpace.performer - assert input_media_audio.title == AudioSpace.title - assert input_media_audio.parse_mode == AudioSpace.parse_mode - assert input_media_audio.caption_entities == tuple(AudioSpace.caption_entities) + assert input_media_audio.type == self.type_ + assert input_media_audio.media == self.media + assert input_media_audio.caption == self.caption + assert input_media_audio.duration == self.duration + assert input_media_audio.performer == self.performer + assert input_media_audio.title == self.title + assert input_media_audio.parse_mode == self.parse_mode + assert input_media_audio.caption_entities == tuple(self.caption_entities) assert isinstance(input_media_audio.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_audio = InputMediaAudio(AudioSpace.media) + input_media_audio = InputMediaAudio(self.media) assert input_media_audio.caption_entities == () def test_to_dict(self, input_media_audio): @@ -377,7 +377,7 @@ def test_to_dict(self, input_media_audio): def test_with_audio(self, audio): # noqa: F811 # fixture found in test_audio input_media_audio = InputMediaAudio(audio, caption="test 3") - assert input_media_audio.type == AudioSpace.type_ + assert input_media_audio.type == self.type_ assert input_media_audio.media == audio.file_id assert input_media_audio.duration == audio.duration assert input_media_audio.performer == audio.performer @@ -387,7 +387,7 @@ def test_with_audio(self, audio): # noqa: F811 def test_with_audio_file(self, audio_file): # noqa: F811 # fixture found in test_audio input_media_audio = InputMediaAudio(audio_file, caption="test 3") - assert input_media_audio.type == AudioSpace.type_ + assert input_media_audio.type == self.type_ assert isinstance(input_media_audio.media, InputFile) assert input_media_audio.caption == "test 3" @@ -399,7 +399,7 @@ def test_with_local_files(self): assert input_media_audio.thumb == data_file("telegram.jpg").as_uri() -class DocumentSpace: +class TestInputMediaDocumentBase: type_ = "document" media = "NOTAREALFILEID" caption = "My Caption" @@ -408,7 +408,7 @@ class DocumentSpace: disable_content_type_detection = True -class TestInputMediaDocumentWithoutRequest: +class TestInputMediaDocumentWithoutRequest(TestInputMediaDocumentBase): def test_slot_behaviour(self, input_media_document, mro_slots): inst = input_media_document for attr in inst.__slots__: @@ -416,19 +416,19 @@ def test_slot_behaviour(self, input_media_document, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_media_document): - assert input_media_document.type == DocumentSpace.type_ - assert input_media_document.media == DocumentSpace.media - assert input_media_document.caption == DocumentSpace.caption - assert input_media_document.parse_mode == DocumentSpace.parse_mode - assert input_media_document.caption_entities == tuple(DocumentSpace.caption_entities) + assert input_media_document.type == self.type_ + assert input_media_document.media == self.media + assert input_media_document.caption == self.caption + assert input_media_document.parse_mode == self.parse_mode + assert input_media_document.caption_entities == tuple(self.caption_entities) assert ( input_media_document.disable_content_type_detection - == DocumentSpace.disable_content_type_detection + == self.disable_content_type_detection ) assert isinstance(input_media_document.thumb, InputFile) def test_caption_entities_always_tuple(self): - input_media_document = InputMediaDocument(DocumentSpace.media) + input_media_document = InputMediaDocument(self.media) assert input_media_document.caption_entities == () def test_to_dict(self, input_media_document): @@ -448,14 +448,14 @@ def test_to_dict(self, input_media_document): def test_with_document(self, document): # noqa: F811 # fixture found in test_document input_media_document = InputMediaDocument(document, caption="test 3") - assert input_media_document.type == DocumentSpace.type_ + assert input_media_document.type == self.type_ assert input_media_document.media == document.file_id assert input_media_document.caption == "test 3" def test_with_document_file(self, document_file): # noqa: F811 # fixture found in test_document input_media_document = InputMediaDocument(document_file, caption="test 3") - assert input_media_document.type == DocumentSpace.type_ + assert input_media_document.type == self.type_ assert isinstance(input_media_document.media, InputFile) assert input_media_document.caption == "test 3" diff --git a/tests/test_inputtextmessagecontent.py b/tests/test_inputtextmessagecontent.py index 55f73c3257e..13d53796fb2 100644 --- a/tests/test_inputtextmessagecontent.py +++ b/tests/test_inputtextmessagecontent.py @@ -25,21 +25,21 @@ @pytest.fixture(scope="module") def input_text_message_content(): return InputTextMessageContent( - Space.message_text, - parse_mode=Space.parse_mode, - entities=Space.entities, - disable_web_page_preview=Space.disable_web_page_preview, + TestInputTextMessageContentBase.message_text, + parse_mode=TestInputTextMessageContentBase.parse_mode, + entities=TestInputTextMessageContentBase.entities, + disable_web_page_preview=TestInputTextMessageContentBase.disable_web_page_preview, ) -class Space: +class TestInputTextMessageContentBase: message_text = "*message text*" parse_mode = ParseMode.MARKDOWN entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] disable_web_page_preview = True -class TestInputTextMessageContentWithoutRequest: +class TestInputTextMessageContentWithoutRequest(TestInputTextMessageContentBase): def test_slot_behaviour(self, input_text_message_content, mro_slots): inst = input_text_message_content for attr in inst.__slots__: @@ -47,12 +47,10 @@ def test_slot_behaviour(self, input_text_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_text_message_content): - assert input_text_message_content.parse_mode == Space.parse_mode - assert input_text_message_content.message_text == Space.message_text - assert ( - input_text_message_content.disable_web_page_preview == Space.disable_web_page_preview - ) - assert input_text_message_content.entities == tuple(Space.entities) + assert input_text_message_content.parse_mode == self.parse_mode + assert input_text_message_content.message_text == self.message_text + assert input_text_message_content.disable_web_page_preview == self.disable_web_page_preview + assert input_text_message_content.entities == tuple(self.entities) def test_entities_always_tuple(self): input_text_message_content = InputTextMessageContent("text") diff --git a/tests/test_inputvenuemessagecontent.py b/tests/test_inputvenuemessagecontent.py index 5c46a7698dc..2837249d169 100644 --- a/tests/test_inputvenuemessagecontent.py +++ b/tests/test_inputvenuemessagecontent.py @@ -24,18 +24,18 @@ @pytest.fixture(scope="module") def input_venue_message_content(): return InputVenueMessageContent( - Space.latitude, - Space.longitude, - Space.title, - Space.address, - foursquare_id=Space.foursquare_id, - foursquare_type=Space.foursquare_type, - google_place_id=Space.google_place_id, - google_place_type=Space.google_place_type, + TestInputVenueMessageContentBase.latitude, + TestInputVenueMessageContentBase.longitude, + TestInputVenueMessageContentBase.title, + TestInputVenueMessageContentBase.address, + foursquare_id=TestInputVenueMessageContentBase.foursquare_id, + foursquare_type=TestInputVenueMessageContentBase.foursquare_type, + google_place_id=TestInputVenueMessageContentBase.google_place_id, + google_place_type=TestInputVenueMessageContentBase.google_place_type, ) -class Space: +class TestInputVenueMessageContentBase: latitude = 1.0 longitude = 2.0 title = "title" @@ -46,7 +46,7 @@ class Space: google_place_type = "google place type" -class TestInputVenueMessageContentWithoutRequest: +class TestInputVenueMessageContentWithoutRequest(TestInputVenueMessageContentBase): def test_slot_behaviour(self, input_venue_message_content, mro_slots): inst = input_venue_message_content for attr in inst.__slots__: @@ -54,14 +54,14 @@ def test_slot_behaviour(self, input_venue_message_content, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, input_venue_message_content): - assert input_venue_message_content.longitude == Space.longitude - assert input_venue_message_content.latitude == Space.latitude - assert input_venue_message_content.title == Space.title - assert input_venue_message_content.address == Space.address - assert input_venue_message_content.foursquare_id == Space.foursquare_id - assert input_venue_message_content.foursquare_type == Space.foursquare_type - assert input_venue_message_content.google_place_id == Space.google_place_id - assert input_venue_message_content.google_place_type == Space.google_place_type + assert input_venue_message_content.longitude == self.longitude + assert input_venue_message_content.latitude == self.latitude + assert input_venue_message_content.title == self.title + assert input_venue_message_content.address == self.address + assert input_venue_message_content.foursquare_id == self.foursquare_id + assert input_venue_message_content.foursquare_type == self.foursquare_type + assert input_venue_message_content.google_place_id == self.google_place_id + assert input_venue_message_content.google_place_type == self.google_place_type def test_to_dict(self, input_venue_message_content): input_venue_message_content_dict = input_venue_message_content.to_dict() diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 510a3f1f06a..877a366615d 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -28,15 +28,15 @@ @pytest.fixture(scope="module") def invoice(): return Invoice( - Space.title, - Space.description, - Space.start_parameter, - Space.currency, - Space.total_amount, + TestInvoiceBase.title, + TestInvoiceBase.description, + TestInvoiceBase.start_parameter, + TestInvoiceBase.currency, + TestInvoiceBase.total_amount, ) -class Space: +class TestInvoiceBase: payload = "payload" prices = [LabeledPrice("Fish", 100), LabeledPrice("Fish Tax", 1000)] provider_data = """{"test":"test"}""" @@ -49,7 +49,7 @@ class Space: suggested_tip_amounts = [13, 42] -class TestInvoiceWithoutRequest: +class TestInvoiceWithoutRequest(TestInvoiceBase): def test_slot_behaviour(self, invoice, mro_slots): for attr in invoice.__slots__: assert getattr(invoice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -58,21 +58,21 @@ def test_slot_behaviour(self, invoice, mro_slots): def test_de_json(self, bot): invoice_json = Invoice.de_json( { - "title": Space.title, - "description": Space.description, - "start_parameter": Space.start_parameter, - "currency": Space.currency, - "total_amount": Space.total_amount, + "title": self.title, + "description": self.description, + "start_parameter": self.start_parameter, + "currency": self.currency, + "total_amount": self.total_amount, }, bot, ) assert invoice_json.api_kwargs == {} - assert invoice_json.title == Space.title - assert invoice_json.description == Space.description - assert invoice_json.start_parameter == Space.start_parameter - assert invoice_json.currency == Space.currency - assert invoice_json.total_amount == Space.total_amount + 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 def test_to_dict(self, invoice): invoice_dict = invoice.to_dict() @@ -156,14 +156,14 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert await bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, + self.currency, + self.prices, provider_data={"test_data": 123456789}, - start_parameter=Space.start_parameter, + start_parameter=self.start_parameter, ) def test_equality(self): @@ -182,36 +182,36 @@ def test_equality(self): assert hash(a) != hash(d) -class TestInvoiceWithRequest: +class TestInvoiceWithRequest(TestInvoiceBase): async def test_send_required_args_only(self, bot, chat_id, provider_token): send_inv_task = asyncio.create_task( bot.send_invoice( chat_id=chat_id, - title=Space.title, - description=Space.description, - payload=Space.payload, + title=self.title, + description=self.description, + payload=self.payload, provider_token=provider_token, - currency=Space.currency, - prices=Space.prices, + currency=self.currency, + prices=self.prices, ) ) create_inv_link_task = asyncio.create_task( bot.create_invoice_link( - title=Space.title, - description=Space.description, - payload=Space.payload, + title=self.title, + description=self.description, + payload=self.payload, provider_token=provider_token, - currency=Space.currency, - prices=Space.prices, + currency=self.currency, + prices=self.prices, ) ) message = await send_inv_task - assert message.invoice.currency == Space.currency + assert message.invoice.currency == self.currency assert message.invoice.start_parameter == "" - assert message.invoice.description == Space.description - assert message.invoice.title == Space.title - assert message.invoice.total_amount == Space.total_amount + assert message.invoice.description == self.description + assert message.invoice.title == self.title + assert message.invoice.total_amount == self.total_amount link = await create_inv_link_task assert isinstance(link, str) @@ -226,12 +226,12 @@ async def test_send_invoice_default_protect_content( *( default_bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, + self.currency, + self.prices, **i, ) for i in ({}, {"protect_content": False}) @@ -258,12 +258,12 @@ async def test_send_invoice_default_allow_sending_without_reply( if custom is not None: message = await default_bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, + self.currency, + self.prices, allow_sending_without_reply=custom, reply_to_message_id=reply_to_message.message_id, ) @@ -271,12 +271,12 @@ async def test_send_invoice_default_allow_sending_without_reply( elif default_bot.defaults.allow_sending_without_reply: message = await default_bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, + self.currency, + self.prices, reply_to_message_id=reply_to_message.message_id, ) assert message.reply_to_message is None @@ -284,28 +284,28 @@ async def test_send_invoice_default_allow_sending_without_reply( with pytest.raises(BadRequest, match="message not found"): await default_bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, + self.currency, + self.prices, reply_to_message_id=reply_to_message.message_id, ) async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token): message = await bot.send_invoice( chat_id, - Space.title, - Space.description, - Space.payload, + self.title, + self.description, + self.payload, provider_token, - Space.currency, - Space.prices, - max_tip_amount=Space.max_tip_amount, - suggested_tip_amounts=Space.suggested_tip_amounts, - start_parameter=Space.start_parameter, - provider_data=Space.provider_data, + self.currency, + self.prices, + max_tip_amount=self.max_tip_amount, + suggested_tip_amounts=self.suggested_tip_amounts, + start_parameter=self.start_parameter, + provider_data=self.provider_data, photo_url="https://raw.githubusercontent.com/" "python-telegram-bot/logos/master/logo/png/ptb-logo_240.png", photo_size=240, @@ -323,5 +323,5 @@ async def test_send_all_args_send_invoice(self, bot, chat_id, provider_token): ) for attr in message.invoice.__slots__: - assert getattr(message.invoice, attr) == getattr(Space, attr) + assert getattr(message.invoice, attr) == getattr(self, attr) assert message.has_protected_content diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index 58c86cdff1f..5d8e315f53e 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def keyboard_button(): return KeyboardButton( - Space.text, - request_location=Space.request_location, - request_contact=Space.request_contact, - request_poll=Space.request_poll, - web_app=Space.web_app, + TestKeyboardButtonBase.text, + request_location=TestKeyboardButtonBase.request_location, + request_contact=TestKeyboardButtonBase.request_contact, + request_poll=TestKeyboardButtonBase.request_poll, + web_app=TestKeyboardButtonBase.web_app, ) -class Space: +class TestKeyboardButtonBase: text = "text" request_location = True request_contact = True @@ -40,7 +40,7 @@ class Space: web_app = WebAppInfo(url="https://example.com") -class TestKeyboardButtonWithoutRequest: +class TestKeyboardButtonWithoutRequest(TestKeyboardButtonBase): def test_slot_behaviour(self, keyboard_button, mro_slots): inst = keyboard_button for attr in inst.__slots__: @@ -48,11 +48,11 @@ def test_slot_behaviour(self, keyboard_button, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, keyboard_button): - assert keyboard_button.text == Space.text - assert keyboard_button.request_location == Space.request_location - assert keyboard_button.request_contact == Space.request_contact - assert keyboard_button.request_poll == Space.request_poll - assert keyboard_button.web_app == Space.web_app + assert keyboard_button.text == self.text + assert keyboard_button.request_location == self.request_location + assert keyboard_button.request_contact == self.request_contact + assert keyboard_button.request_poll == self.request_poll + assert keyboard_button.web_app == self.web_app def test_to_dict(self, keyboard_button): keyboard_button_dict = keyboard_button.to_dict() @@ -66,20 +66,20 @@ def test_to_dict(self, keyboard_button): def test_de_json(self, bot): json_dict = { - "text": Space.text, - "request_location": Space.request_location, - "request_contact": Space.request_contact, - "request_poll": Space.request_poll.to_dict(), - "web_app": Space.web_app.to_dict(), + "text": self.text, + "request_location": self.request_location, + "request_contact": self.request_contact, + "request_poll": self.request_poll.to_dict(), + "web_app": self.web_app.to_dict(), } inline_keyboard_button = KeyboardButton.de_json(json_dict, None) assert inline_keyboard_button.api_kwargs == {} - assert inline_keyboard_button.text == Space.text - assert inline_keyboard_button.request_location == Space.request_location - assert inline_keyboard_button.request_contact == Space.request_contact - assert inline_keyboard_button.request_poll == Space.request_poll - assert inline_keyboard_button.web_app == Space.web_app + assert inline_keyboard_button.text == self.text + assert inline_keyboard_button.request_location == self.request_location + assert inline_keyboard_button.request_contact == self.request_contact + assert inline_keyboard_button.request_poll == self.request_poll + assert inline_keyboard_button.web_app == self.web_app none = KeyboardButton.de_json({}, None) assert none is None diff --git a/tests/test_keyboardbuttonpolltype.py b/tests/test_keyboardbuttonpolltype.py index f9fa3f298d9..56404a2139d 100644 --- a/tests/test_keyboardbuttonpolltype.py +++ b/tests/test_keyboardbuttonpolltype.py @@ -23,14 +23,14 @@ @pytest.fixture(scope="module") def keyboard_button_poll_type(): - return KeyboardButtonPollType(Space.type) + return KeyboardButtonPollType(TestKeyboardButtonPollTypeBase.type) -class Space: +class TestKeyboardButtonPollTypeBase: type = Poll.QUIZ -class TestKeyboardButtonPollTypeWithoutRequest: +class TestKeyboardButtonPollTypeWithoutRequest(TestKeyboardButtonPollTypeBase): def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): inst = keyboard_button_poll_type for attr in inst.__slots__: @@ -40,7 +40,7 @@ def test_slot_behaviour(self, keyboard_button_poll_type, mro_slots): def test_to_dict(self, keyboard_button_poll_type): keyboard_button_poll_type_dict = keyboard_button_poll_type.to_dict() assert isinstance(keyboard_button_poll_type_dict, dict) - assert keyboard_button_poll_type_dict["type"] == Space.type + assert keyboard_button_poll_type_dict["type"] == self.type def test_equality(self): a = KeyboardButtonPollType(Poll.QUIZ) diff --git a/tests/test_labeledprice.py b/tests/test_labeledprice.py index e8492c7ecd9..e5c61c51bde 100644 --- a/tests/test_labeledprice.py +++ b/tests/test_labeledprice.py @@ -23,15 +23,15 @@ @pytest.fixture(scope="module") def labeled_price(): - return LabeledPrice(Space.label, Space.amount) + return LabeledPrice(TestLabeledPriceBase.label, TestLabeledPriceBase.amount) -class Space: +class TestLabeledPriceBase: label = "label" amount = 100 -class TestLabeledPriceWithoutRequest: +class TestLabeledPriceWithoutRequest(TestLabeledPriceBase): def test_slot_behaviour(self, labeled_price, mro_slots): inst = labeled_price for attr in inst.__slots__: @@ -39,8 +39,8 @@ def test_slot_behaviour(self, labeled_price, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, labeled_price): - assert labeled_price.label == Space.label - assert labeled_price.amount == Space.amount + 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() diff --git a/tests/test_location.py b/tests/test_location.py index cd8f7d4f8cf..06ac34c4d38 100644 --- a/tests/test_location.py +++ b/tests/test_location.py @@ -28,16 +28,16 @@ @pytest.fixture(scope="module") def location(): return Location( - latitude=Space.latitude, - longitude=Space.longitude, - horizontal_accuracy=Space.horizontal_accuracy, - live_period=Space.live_period, - heading=Space.live_period, - proximity_alert_radius=Space.proximity_alert_radius, + latitude=TestLocationBase.latitude, + longitude=TestLocationBase.longitude, + horizontal_accuracy=TestLocationBase.horizontal_accuracy, + live_period=TestLocationBase.live_period, + heading=TestLocationBase.live_period, + proximity_alert_radius=TestLocationBase.proximity_alert_radius, ) -class Space: +class TestLocationBase: latitude = -23.691288 longitude = -46.788279 horizontal_accuracy = 999 @@ -46,7 +46,7 @@ class Space: proximity_alert_radius = 50 -class TestLocationWithoutRequest: +class TestLocationWithoutRequest(TestLocationBase): def test_slot_behaviour(self, location, mro_slots): for attr in location.__slots__: assert getattr(location, attr, "err") != "err", f"got extra slot '{attr}'" @@ -54,22 +54,22 @@ def test_slot_behaviour(self, location, mro_slots): def test_de_json(self, bot): json_dict = { - "latitude": Space.latitude, - "longitude": Space.longitude, - "horizontal_accuracy": Space.horizontal_accuracy, - "live_period": Space.live_period, - "heading": Space.heading, - "proximity_alert_radius": Space.proximity_alert_radius, + "latitude": self.latitude, + "longitude": self.longitude, + "horizontal_accuracy": self.horizontal_accuracy, + "live_period": self.live_period, + "heading": self.heading, + "proximity_alert_radius": self.proximity_alert_radius, } location = Location.de_json(json_dict, bot) assert location.api_kwargs == {} - assert location.latitude == Space.latitude - assert location.longitude == Space.longitude - assert location.horizontal_accuracy == Space.horizontal_accuracy - assert location.live_period == Space.live_period - assert location.heading == Space.heading - assert location.proximity_alert_radius == Space.proximity_alert_radius + assert location.latitude == self.latitude + assert location.longitude == self.longitude + assert location.horizontal_accuracy == self.horizontal_accuracy + assert location.live_period == self.live_period + assert location.heading == self.heading + assert location.proximity_alert_radius == self.proximity_alert_radius def test_to_dict(self, location): location_dict = location.to_dict() @@ -82,9 +82,9 @@ def test_to_dict(self, location): assert location["proximity_alert_radius"] == location.proximity_alert_radius def test_equality(self): - a = Location(Space.longitude, Space.latitude) - b = Location(Space.longitude, Space.latitude) - d = Location(0, Space.latitude) + a = Location(self.longitude, self.latitude) + b = Location(self.longitude, self.latitude) + d = Location(0, self.latitude) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index 7d735b248ea..09fd40569ff 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -24,21 +24,21 @@ @pytest.fixture(scope="module") def login_url(): return LoginUrl( - url=Space.url, - forward_text=Space.forward_text, - bot_username=Space.bot_username, - request_write_access=Space.request_write_access, + url=TestLoginUrlBase.url, + forward_text=TestLoginUrlBase.forward_text, + bot_username=TestLoginUrlBase.bot_username, + request_write_access=TestLoginUrlBase.request_write_access, ) -class Space: +class TestLoginUrlBase: url = "http://www.google.com" forward_text = "Send me forward!" bot_username = "botname" request_write_access = True -class TestLoginUrlWithoutRequest: +class TestLoginUrlWithoutRequest(TestLoginUrlBase): def test_slot_behaviour(self, login_url, mro_slots): for attr in login_url.__slots__: assert getattr(login_url, attr, "err") != "err", f"got extra slot '{attr}'" @@ -48,18 +48,16 @@ def test_to_dict(self, login_url): login_url_dict = login_url.to_dict() assert isinstance(login_url_dict, dict) - assert login_url_dict["url"] == Space.url - assert login_url_dict["forward_text"] == Space.forward_text - assert login_url_dict["bot_username"] == Space.bot_username - assert login_url_dict["request_write_access"] == Space.request_write_access + assert login_url_dict["url"] == self.url + assert login_url_dict["forward_text"] == self.forward_text + assert login_url_dict["bot_username"] == self.bot_username + assert login_url_dict["request_write_access"] == self.request_write_access def test_equality(self): - a = LoginUrl(Space.url, Space.forward_text, Space.bot_username, Space.request_write_access) - b = LoginUrl(Space.url, Space.forward_text, Space.bot_username, Space.request_write_access) - c = LoginUrl(Space.url) - d = LoginUrl( - "text.com", Space.forward_text, Space.bot_username, Space.request_write_access - ) + a = LoginUrl(self.url, self.forward_text, self.bot_username, self.request_write_access) + b = LoginUrl(self.url, self.forward_text, self.bot_username, self.request_write_access) + c = LoginUrl(self.url) + d = LoginUrl("text.com", self.forward_text, self.bot_username, self.request_write_access) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_menubutton.py b/tests/test_menubutton.py index e725b4de590..091bbdb2d41 100644 --- a/tests/test_menubutton.py +++ b/tests/test_menubutton.py @@ -82,20 +82,20 @@ def menu_button(scope_class_and_type): return scope_class_and_type[0].de_json( dict( type=scope_class_and_type[1], - text=Space.text, - web_app=Space.web_app.to_dict(), + text=TestMenuButtonselfBase.text, + web_app=TestMenuButtonselfBase.web_app.to_dict(), ), bot=None, ) -class Space: +class TestMenuButtonselfBase: text = "button_text" web_app = WebAppInfo(url="https://python-telegram-bot.org/web_app") # All the scope types are very similar, so we test everything via parametrization -class TestMenuButtonWithoutRequest: +class TestMenuButtonWithoutRequest(TestMenuButtonselfBase): def test_slot_behaviour(self, menu_button, mro_slots): for attr in menu_button.__slots__: assert getattr(menu_button, attr, "err") != "err", f"got extra slot '{attr}'" @@ -105,7 +105,7 @@ def test_de_json(self, bot, scope_class_and_type): cls = scope_class_and_type[0] type_ = scope_class_and_type[1] - json_dict = {"type": type_, "text": Space.text, "web_app": Space.web_app.to_dict()} + json_dict = {"type": type_, "text": self.text, "web_app": self.web_app.to_dict()} menu_button = MenuButton.de_json(json_dict, bot) assert set(menu_button.api_kwargs.keys()) == {"text", "web_app"} - set(cls.__slots__) @@ -113,17 +113,17 @@ def test_de_json(self, bot, scope_class_and_type): assert type(menu_button) is cls assert menu_button.type == type_ if "web_app" in cls.__slots__: - assert menu_button.web_app == Space.web_app + assert menu_button.web_app == self.web_app if "text" in cls.__slots__: - assert menu_button.text == Space.text + assert menu_button.text == self.text assert cls.de_json(None, bot) is None assert MenuButton.de_json({}, bot) is None def test_de_json_invalid_type(self, bot): - json_dict = {"type": "invalid", "text": Space.text, "web_app": Space.web_app.to_dict()} + json_dict = {"type": "invalid", "text": self.text, "web_app": self.web_app.to_dict()} menu_button = MenuButton.de_json(json_dict, bot) - assert menu_button.api_kwargs == {"text": Space.text, "web_app": Space.web_app.to_dict()} + assert menu_button.api_kwargs == {"text": self.text, "web_app": self.web_app.to_dict()} assert type(menu_button) is MenuButton assert menu_button.type == "invalid" @@ -131,7 +131,7 @@ def test_de_json_invalid_type(self, bot): def test_de_json_subclass(self, scope_class, bot): """This makes sure that e.g. MenuButtonDefault(data) never returns a MenuButtonChat instance.""" - json_dict = {"type": "invalid", "text": Space.text, "web_app": Space.web_app.to_dict()} + json_dict = {"type": "invalid", "text": self.text, "web_app": self.web_app.to_dict()} assert type(scope_class.de_json(json_dict, bot)) is scope_class def test_to_dict(self, menu_button): diff --git a/tests/test_message.py b/tests/test_message.py index debf44eaf9e..4a60efa1f67 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -67,10 +67,10 @@ @pytest.fixture(scope="module") def message(bot): message = Message( - message_id=Space.id_, - date=Space.date, - chat=copy(Space.chat), - from_user=copy(Space.from_user), + message_id=TestMessageBase.id_, + date=TestMessageBase.date, + chat=copy(TestMessageBase.chat), + from_user=copy(TestMessageBase.from_user), ) message.set_bot(bot) message._unfreeze() @@ -265,17 +265,17 @@ def message(bot): ) def message_params(bot, request): message = Message( - message_id=Space.id_, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + message_id=TestMessageBase.id_, + from_user=TestMessageBase.from_user, + date=TestMessageBase.date, + chat=TestMessageBase.chat, **request.param, ) message.set_bot(bot) return message -class Space: +class TestMessageBase: id_ = 1 from_user = User(2, "testuser", False) date = datetime.utcnow() @@ -342,7 +342,7 @@ class Space: ) -class TestMessageWithoutRequest: +class TestMessageWithoutRequest(TestMessageBase): def test_slot_behaviour(self, message, mro_slots): for attr in message.__slots__: assert getattr(message, attr, "err") != "err", f"got extra slot '{attr}'" @@ -361,10 +361,10 @@ def test_all_possibilities_de_json_and_to_dict(self, bot, message_params): def test_equality(self): id_ = 1 - a = Message(id_, Space.date, Space.chat, from_user=Space.from_user) - b = Message(id_, Space.date, Space.chat, from_user=Space.from_user) - c = Message(id_, Space.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) - d = Message(0, Space.date, Space.chat, from_user=Space.from_user) + a = Message(id_, self.date, self.chat, from_user=self.from_user) + b = Message(id_, self.date, self.chat, from_user=self.from_user) + c = Message(id_, self.date, Chat(123, Chat.GROUP), from_user=User(0, "", False)) + d = Message(0, self.date, self.chat, from_user=self.from_user) e = Update(id_) assert a == b @@ -388,16 +388,16 @@ async def test_parse_entity(self): entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, text=text, entities=[entity], ) assert message.parse_entity(entity) == "http://google.com" with pytest.raises(RuntimeError, match="Message has no"): - Message(message_id=1, date=Space.date, chat=Space.chat).parse_entity(entity) + Message(message_id=1, date=self.date, chat=self.chat).parse_entity(entity) async def test_parse_caption_entity(self): caption = ( @@ -407,16 +407,16 @@ async def test_parse_caption_entity(self): entity = MessageEntity(type=MessageEntity.URL, offset=13, length=17) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, caption=caption, caption_entities=[entity], ) assert message.parse_caption_entity(entity) == "http://google.com" with pytest.raises(RuntimeError, match="Message has no"): - Message(message_id=1, date=Space.date, chat=Space.chat).parse_entity(entity) + Message(message_id=1, date=self.date, chat=self.chat).parse_entity(entity) async def test_parse_entities(self): text = ( @@ -427,9 +427,9 @@ async def test_parse_entities(self): entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, text=text, entities=[entity_2, entity], ) @@ -445,9 +445,9 @@ async def test_parse_caption_entities(self): entity_2 = MessageEntity(type=MessageEntity.BOLD, offset=13, length=1) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, caption=text, caption_entities=[entity_2, entity], ) @@ -468,7 +468,7 @@ def test_text_html_simple(self): '
Python pre
. ' 'Spoiled.' ) - text_html = Space.test_message_v2.text_html + text_html = self.test_message_v2.text_html assert text_html == test_html_string def test_text_html_empty(self, message): @@ -487,7 +487,7 @@ def test_text_html_urled(self): '
Python pre
. ' 'Spoiled.' ) - text_html = Space.test_message_v2.text_html_urled + text_html = self.test_message_v2.text_html_urled assert text_html == test_html_string def test_text_markdown_simple(self): @@ -497,7 +497,7 @@ def test_text_markdown_simple(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " r"http://google.com/ab\_" ) - text_markdown = Space.test_message.text_markdown + text_markdown = self.test_message.text_markdown assert text_markdown == test_md_string def test_text_markdown_v2_simple(self): @@ -508,7 +508,7 @@ def test_text_markdown_v2_simple(self): r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. " "```python\nPython pre```\\. ||Spoiled||\\." ) - text_markdown = Space.test_message_v2.text_markdown_v2 + text_markdown = self.test_message_v2.text_markdown_v2 assert text_markdown == test_md_string def test_text_markdown_new_in_v2(self, message): @@ -547,7 +547,7 @@ def test_text_markdown_urled(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " "[http://google.com/ab_](http://google.com/ab_)" ) - text_markdown = Space.test_message.text_markdown_urled + text_markdown = self.test_message.text_markdown_urled assert text_markdown == test_md_string def test_text_markdown_v2_urled(self): @@ -558,7 +558,7 @@ def test_text_markdown_v2_urled(self): r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ " "nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\." ) - text_markdown = Space.test_message_v2.text_markdown_v2_urled + text_markdown = self.test_message_v2.text_markdown_v2_urled assert text_markdown == test_md_string def test_text_html_emoji(self): @@ -567,9 +567,9 @@ def test_text_html_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, text=text, entities=[bold_entity], ) @@ -580,7 +580,7 @@ def test_text_markdown_emoji(self): expected = b"\\U0001f469\\u200d\\U0001f469\\u200d *ABC*".decode("unicode-escape") bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( - 1, Space.date, Space.chat, Space.from_user, text=text, entities=[bold_entity] + 1, self.date, self.chat, self.from_user, text=text, entities=[bold_entity] ) assert expected == message.text_markdown @@ -606,9 +606,9 @@ def test_text_custom_emoji(self, type_): ) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, text=text, entities=[emoji_entity], ) @@ -625,7 +625,7 @@ def test_caption_html_simple(self): '
Python pre
. ' 'Spoiled.' ) - caption_html = Space.test_message_v2.caption_html + caption_html = self.test_message_v2.caption_html assert caption_html == test_html_string def test_caption_html_empty(self, message): @@ -644,7 +644,7 @@ def test_caption_html_urled(self): '
Python pre
. ' 'Spoiled.' ) - caption_html = Space.test_message_v2.caption_html_urled + caption_html = self.test_message_v2.caption_html_urled assert caption_html == test_html_string def test_caption_markdown_simple(self): @@ -654,7 +654,7 @@ def test_caption_markdown_simple(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " r"http://google.com/ab\_" ) - caption_markdown = Space.test_message.caption_markdown + caption_markdown = self.test_message.caption_markdown assert caption_markdown == test_md_string def test_caption_markdown_v2_simple(self): @@ -665,7 +665,7 @@ def test_caption_markdown_v2_simple(self): r"http://google\.com and _bold *nested in ~strk\>trgh~ nested in* italic_\. " "```python\nPython pre```\\. ||Spoiled||\\." ) - caption_markdown = Space.test_message_v2.caption_markdown_v2 + caption_markdown = self.test_message_v2.caption_markdown_v2 assert caption_markdown == test_md_string def test_caption_markdown_empty(self, message): @@ -681,7 +681,7 @@ def test_caption_markdown_urled(self): "[text-mention](tg://user?id=123456789) and ```python\npre```. " "[http://google.com/ab_](http://google.com/ab_)" ) - caption_markdown = Space.test_message.caption_markdown_urled + caption_markdown = self.test_message.caption_markdown_urled assert caption_markdown == test_md_string def test_caption_markdown_v2_urled(self): @@ -692,7 +692,7 @@ def test_caption_markdown_v2_urled(self): r"[http://google\.com](http://google.com) and _bold *nested in ~strk\>trgh~ " "nested in* italic_\\. ```python\nPython pre```\\. ||Spoiled||\\." ) - caption_markdown = Space.test_message_v2.caption_markdown_v2_urled + caption_markdown = self.test_message_v2.caption_markdown_v2_urled assert caption_markdown == test_md_string def test_caption_html_emoji(self): @@ -701,9 +701,9 @@ def test_caption_html_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, caption=caption, caption_entities=[bold_entity], ) @@ -715,9 +715,9 @@ def test_caption_markdown_emoji(self): bold_entity = MessageEntity(type=MessageEntity.BOLD, offset=7, length=3) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, caption=caption, caption_entities=[bold_entity], ) @@ -745,9 +745,9 @@ def test_caption_custom_emoji(self, type_): ) message = Message( 1, - from_user=Space.from_user, - date=Space.date, - chat=Space.chat, + from_user=self.from_user, + date=self.date, + chat=self.chat, caption=caption, caption_entities=[emoji_entity], ) @@ -758,7 +758,7 @@ async def test_parse_entities_url_emoji(self): text = "some url" link_entity = MessageEntity(type=MessageEntity.URL, offset=0, length=8, url=url) message = Message( - 1, Space.from_user, Space.date, Space.chat, text=text, entities=[link_entity] + 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 @@ -878,14 +878,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_markdown = Space.test_message.text_markdown + text_markdown = self.test_message.text_markdown assert text_markdown == test_md_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_markdown(Space.test_message.text_markdown) - assert await message.reply_markdown(Space.test_message.text_markdown, quote=True) + assert await message.reply_markdown(self.test_message.text_markdown) + assert await message.reply_markdown(self.test_message.text_markdown, quote=True) assert await message.reply_markdown( - Space.test_message.text_markdown, reply_to_message_id=message.message_id, quote=True + self.test_message.text_markdown, reply_to_message_id=message.message_id, quote=True ) async def test_reply_markdown_v2(self, monkeypatch, message): @@ -913,14 +913,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_markdown = Space.test_message_v2.text_markdown_v2 + text_markdown = self.test_message_v2.text_markdown_v2 assert text_markdown == test_md_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_markdown_v2(Space.test_message_v2.text_markdown_v2) - assert await message.reply_markdown_v2(Space.test_message_v2.text_markdown_v2, quote=True) + assert await message.reply_markdown_v2(self.test_message_v2.text_markdown_v2) + assert await message.reply_markdown_v2(self.test_message_v2.text_markdown_v2, quote=True) assert await message.reply_markdown_v2( - Space.test_message_v2.text_markdown_v2, + self.test_message_v2.text_markdown_v2, reply_to_message_id=message.message_id, quote=True, ) @@ -953,14 +953,14 @@ async def make_assertion(*_, **kwargs): assert await check_shortcut_call(message.reply_text, message.get_bot(), "send_message") assert await check_defaults_handling(message.reply_text, message.get_bot()) - text_html = Space.test_message_v2.text_html + text_html = self.test_message_v2.text_html assert text_html == test_html_string monkeypatch.setattr(message.get_bot(), "send_message", make_assertion) - assert await message.reply_html(Space.test_message_v2.text_html) - assert await message.reply_html(Space.test_message_v2.text_html, quote=True) + assert await message.reply_html(self.test_message_v2.text_html) + assert await message.reply_html(self.test_message_v2.text_html, quote=True) assert await message.reply_html( - Space.test_message_v2.text_html, reply_to_message_id=message.message_id, quote=True + self.test_message_v2.text_html, reply_to_message_id=message.message_id, quote=True ) async def test_reply_media_group(self, monkeypatch, message): diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 49f1c76479e..40faeff5b45 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -37,14 +37,14 @@ def message_entity(request): return MessageEntity(type_, 1, 3, url=url, user=user, language=language) -class Space: +class TestMessageEntityBase: type_ = "url" offset = 1 length = 2 url = "url" -class TestMessageEntityWithoutRequest: +class TestMessageEntityWithoutRequest(TestMessageEntityBase): def test_slot_behaviour(self, message_entity, mro_slots): inst = message_entity for attr in inst.__slots__: @@ -52,13 +52,13 @@ def test_slot_behaviour(self, message_entity, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json(self, bot): - json_dict = {"type": Space.type_, "offset": Space.offset, "length": Space.length} + json_dict = {"type": self.type_, "offset": self.offset, "length": self.length} entity = MessageEntity.de_json(json_dict, bot) assert entity.api_kwargs == {} - assert entity.type == Space.type_ - assert entity.offset == Space.offset - assert entity.length == Space.length + assert entity.type == self.type_ + assert entity.offset == self.offset + assert entity.length == self.length def test_to_dict(self, message_entity): entity_dict = message_entity.to_dict() diff --git a/tests/test_orderinfo.py b/tests/test_orderinfo.py index 3d9ec178d79..1700e2d2da0 100644 --- a/tests/test_orderinfo.py +++ b/tests/test_orderinfo.py @@ -23,17 +23,22 @@ @pytest.fixture(scope="module") def order_info(): - return OrderInfo(Space.name, Space.phone_number, Space.email, Space.shipping_address) + return OrderInfo( + TestOrderInfoBase.name, + TestOrderInfoBase.phone_number, + TestOrderInfoBase.email, + TestOrderInfoBase.shipping_address, + ) -class Space: +class TestOrderInfoBase: name = "name" phone_number = "phone_number" email = "email" shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestOrderInfoWithoutRequest: +class TestOrderInfoWithoutRequest(TestOrderInfoBase): def test_slot_behaviour(self, order_info, mro_slots): for attr in order_info.__slots__: assert getattr(order_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -41,18 +46,18 @@ def test_slot_behaviour(self, order_info, mro_slots): def test_de_json(self, bot): json_dict = { - "name": Space.name, - "phone_number": Space.phone_number, - "email": Space.email, - "shipping_address": Space.shipping_address.to_dict(), + "name": self.name, + "phone_number": self.phone_number, + "email": self.email, + "shipping_address": self.shipping_address.to_dict(), } order_info = OrderInfo.de_json(json_dict, bot) assert order_info.api_kwargs == {} - assert order_info.name == Space.name - assert order_info.phone_number == Space.phone_number - assert order_info.email == Space.email - assert order_info.shipping_address == Space.shipping_address + 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 def test_to_dict(self, order_info): order_info_dict = order_info.to_dict() diff --git a/tests/test_passport.py b/tests/test_passport.py index 4bca9536d3d..09e1b076e8f 100644 --- a/tests/test_passport.py +++ b/tests/test_passport.py @@ -219,7 +219,7 @@ def passport_data(bot): return PassportData.de_json(RAW_PASSPORT_DATA, bot=bot) -class Space: +class TestPassportBase: driver_license_selfie_file_id = "DgADBAADEQQAAkopgFNr6oi-wISRtAI" driver_license_selfie_file_unique_id = "d4e390cca57b4da5a65322b304762a12" driver_license_front_side_file_id = "DgADBAADxwMAApnQgVPK2-ckL2eXVAI" @@ -242,7 +242,7 @@ class Space: driver_license_selfie_credentials_secret = "tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E=" -class TestPassportWithoutRequest: +class TestPassportWithoutRequest(TestPassportBase): def test_slot_behaviour(self, passport_data, mro_slots): inst = passport_data for attr in inst.__slots__: @@ -261,58 +261,58 @@ def test_expected_encrypted_values(self, passport_data): assert driver_license.type == "driver_license" assert driver_license.data == RAW_PASSPORT_DATA["data"][1]["data"] assert isinstance(driver_license.selfie, PassportFile) - assert driver_license.selfie.file_id == Space.driver_license_selfie_file_id - assert driver_license.selfie.file_unique_id == Space.driver_license_selfie_file_unique_id + assert driver_license.selfie.file_id == self.driver_license_selfie_file_id + assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id assert isinstance(driver_license.front_side, PassportFile) - assert driver_license.front_side.file_id == Space.driver_license_front_side_file_id + assert driver_license.front_side.file_id == self.driver_license_front_side_file_id assert ( driver_license.front_side.file_unique_id - == Space.driver_license_front_side_file_unique_id + == self.driver_license_front_side_file_unique_id ) assert isinstance(driver_license.reverse_side, PassportFile) - assert driver_license.reverse_side.file_id == Space.driver_license_reverse_side_file_id + assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id assert ( driver_license.reverse_side.file_unique_id - == Space.driver_license_reverse_side_file_unique_id + == self.driver_license_reverse_side_file_unique_id ) assert isinstance(driver_license.translation[0], PassportFile) - assert driver_license.translation[0].file_id == Space.driver_license_translation_1_file_id + assert driver_license.translation[0].file_id == self.driver_license_translation_1_file_id assert ( driver_license.translation[0].file_unique_id - == Space.driver_license_translation_1_file_unique_id + == self.driver_license_translation_1_file_unique_id ) assert isinstance(driver_license.translation[1], PassportFile) - assert driver_license.translation[1].file_id == Space.driver_license_translation_2_file_id + assert driver_license.translation[1].file_id == self.driver_license_translation_2_file_id assert ( driver_license.translation[1].file_unique_id - == Space.driver_license_translation_2_file_unique_id + == self.driver_license_translation_2_file_unique_id ) assert utility_bill.type == "utility_bill" assert isinstance(utility_bill.files[0], PassportFile) - assert utility_bill.files[0].file_id == Space.utility_bill_1_file_id - assert utility_bill.files[0].file_unique_id == Space.utility_bill_1_file_unique_id + assert utility_bill.files[0].file_id == self.utility_bill_1_file_id + assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id assert isinstance(utility_bill.files[1], PassportFile) - assert utility_bill.files[1].file_id == Space.utility_bill_2_file_id - assert utility_bill.files[1].file_unique_id == Space.utility_bill_2_file_unique_id + assert utility_bill.files[1].file_id == self.utility_bill_2_file_id + assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id assert isinstance(utility_bill.translation[0], PassportFile) - assert utility_bill.translation[0].file_id == Space.utility_bill_translation_1_file_id + assert utility_bill.translation[0].file_id == self.utility_bill_translation_1_file_id assert ( utility_bill.translation[0].file_unique_id - == Space.utility_bill_translation_1_file_unique_id + == self.utility_bill_translation_1_file_unique_id ) assert isinstance(utility_bill.translation[1], PassportFile) - assert utility_bill.translation[1].file_id == Space.utility_bill_translation_2_file_id + assert utility_bill.translation[1].file_id == self.utility_bill_translation_2_file_id assert ( utility_bill.translation[1].file_unique_id - == Space.utility_bill_translation_2_file_unique_id + == self.utility_bill_translation_2_file_unique_id ) assert address.type == "address" @@ -350,21 +350,21 @@ def test_expected_decrypted_values(self, passport_data): "document_no": "DOCUMENT_NO", } assert isinstance(driver_license.selfie, PassportFile) - assert driver_license.selfie.file_id == Space.driver_license_selfie_file_id - assert driver_license.selfie.file_unique_id == Space.driver_license_selfie_file_unique_id + assert driver_license.selfie.file_id == self.driver_license_selfie_file_id + assert driver_license.selfie.file_unique_id == self.driver_license_selfie_file_unique_id assert isinstance(driver_license.front_side, PassportFile) - assert driver_license.front_side.file_id == Space.driver_license_front_side_file_id + assert driver_license.front_side.file_id == self.driver_license_front_side_file_id assert ( driver_license.front_side.file_unique_id - == Space.driver_license_front_side_file_unique_id + == self.driver_license_front_side_file_unique_id ) assert isinstance(driver_license.reverse_side, PassportFile) - assert driver_license.reverse_side.file_id == Space.driver_license_reverse_side_file_id + assert driver_license.reverse_side.file_id == self.driver_license_reverse_side_file_id assert ( driver_license.reverse_side.file_unique_id - == Space.driver_license_reverse_side_file_unique_id + == self.driver_license_reverse_side_file_unique_id ) assert address.type == "address" @@ -379,12 +379,12 @@ def test_expected_decrypted_values(self, passport_data): assert utility_bill.type == "utility_bill" assert isinstance(utility_bill.files[0], PassportFile) - assert utility_bill.files[0].file_id == Space.utility_bill_1_file_id - assert utility_bill.files[0].file_unique_id == Space.utility_bill_1_file_unique_id + assert utility_bill.files[0].file_id == self.utility_bill_1_file_id + assert utility_bill.files[0].file_unique_id == self.utility_bill_1_file_unique_id assert isinstance(utility_bill.files[1], PassportFile) - assert utility_bill.files[1].file_id == Space.utility_bill_2_file_id - assert utility_bill.files[1].file_unique_id == Space.utility_bill_2_file_unique_id + assert utility_bill.files[1].file_id == self.utility_bill_2_file_id + assert utility_bill.files[1].file_unique_id == self.utility_bill_2_file_unique_id assert email.type == "email" assert email.email == "fb3e3i47zt@dispostable.com" @@ -494,8 +494,8 @@ async def get_file(*_, **kwargs): file = await selfie.get_file() assert file.file_id == selfie.file_id assert file.file_unique_id == selfie.file_unique_id - assert file._credentials.file_hash == Space.driver_license_selfie_credentials_file_hash - assert file._credentials.secret == Space.driver_license_selfie_credentials_secret + assert file._credentials.file_hash == self.driver_license_selfie_credentials_file_hash + assert file._credentials.secret == self.driver_license_selfie_credentials_secret async def test_mocked_set_passport_data_errors(self, monkeypatch, bot, chat_id, passport_data): async def make_assertion(url, request_data: RequestData, *args, **kwargs): diff --git a/tests/test_passportelementerrordatafield.py b/tests/test_passportelementerrordatafield.py index 4aff2f1cb5f..82b1793956d 100644 --- a/tests/test_passportelementerrordatafield.py +++ b/tests/test_passportelementerrordatafield.py @@ -24,14 +24,14 @@ @pytest.fixture(scope="module") def passport_element_error_data_field(): return PassportElementErrorDataField( - Space.type_, - Space.field_name, - Space.data_hash, - Space.message, + TestPassportElementErrorDataFieldBase.type_, + TestPassportElementErrorDataFieldBase.field_name, + TestPassportElementErrorDataFieldBase.data_hash, + TestPassportElementErrorDataFieldBase.message, ) -class Space: +class TestPassportElementErrorDataFieldBase: source = "data" type_ = "test_type" field_name = "test_field" @@ -39,7 +39,7 @@ class Space: message = "Error message" -class TestPassportElementErrorDataFieldWithoutRequest: +class TestPassportElementErrorDataFieldWithoutRequest(TestPassportElementErrorDataFieldBase): def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): inst = passport_element_error_data_field for attr in inst.__slots__: @@ -47,11 +47,11 @@ def test_slot_behaviour(self, passport_element_error_data_field, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_data_field): - assert passport_element_error_data_field.source == Space.source - assert passport_element_error_data_field.type == Space.type_ - assert passport_element_error_data_field.field_name == Space.field_name - assert passport_element_error_data_field.data_hash == Space.data_hash - assert passport_element_error_data_field.message == Space.message + assert passport_element_error_data_field.source == self.source + assert passport_element_error_data_field.type == self.type_ + assert passport_element_error_data_field.field_name == self.field_name + assert passport_element_error_data_field.data_hash == self.data_hash + assert passport_element_error_data_field.message == self.message def test_to_dict(self, passport_element_error_data_field): passport_element_error_data_field_dict = passport_element_error_data_field.to_dict() @@ -80,16 +80,16 @@ def test_to_dict(self, passport_element_error_data_field): def test_equality(self): a = PassportElementErrorDataField( - Space.type_, Space.field_name, Space.data_hash, Space.message + self.type_, self.field_name, self.data_hash, self.message ) b = PassportElementErrorDataField( - Space.type_, Space.field_name, Space.data_hash, Space.message + self.type_, self.field_name, self.data_hash, self.message ) - c = PassportElementErrorDataField(Space.type_, "", "", "") - d = PassportElementErrorDataField("", Space.field_name, "", "") - e = PassportElementErrorDataField("", "", Space.data_hash, "") - f = PassportElementErrorDataField("", "", "", Space.message) - g = PassportElementErrorSelfie(Space.type_, "", Space.message) + c = PassportElementErrorDataField(self.type_, "", "", "") + d = PassportElementErrorDataField("", self.field_name, "", "") + e = PassportElementErrorDataField("", "", self.data_hash, "") + f = PassportElementErrorDataField("", "", "", self.message) + g = PassportElementErrorSelfie(self.type_, "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfile.py b/tests/test_passportelementerrorfile.py index cd1a668498a..c47ac4a3768 100644 --- a/tests/test_passportelementerrorfile.py +++ b/tests/test_passportelementerrorfile.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_file(): - return PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) + return PassportElementErrorFile( + TestPassportElementErrorFileBase.type_, + TestPassportElementErrorFileBase.file_hash, + TestPassportElementErrorFileBase.message, + ) -class Space: +class TestPassportElementErrorFileBase: source = "file" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorFileWithoutRequest: +class TestPassportElementErrorFileWithoutRequest(TestPassportElementErrorFileBase): def test_slot_behaviour(self, passport_element_error_file, mro_slots): inst = passport_element_error_file for attr in inst.__slots__: @@ -41,10 +45,10 @@ def test_slot_behaviour(self, passport_element_error_file, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_file): - assert passport_element_error_file.source == Space.source - assert passport_element_error_file.type == Space.type_ - assert passport_element_error_file.file_hash == Space.file_hash - assert passport_element_error_file.message == Space.message + assert passport_element_error_file.source == self.source + assert passport_element_error_file.type == self.type_ + assert passport_element_error_file.file_hash == self.file_hash + assert passport_element_error_file.message == self.message def test_to_dict(self, passport_element_error_file): passport_element_error_file_dict = passport_element_error_file.to_dict() @@ -58,12 +62,12 @@ def test_to_dict(self, passport_element_error_file): assert passport_element_error_file_dict["message"] == passport_element_error_file.message def test_equality(self): - a = PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) - b = PassportElementErrorFile(Space.type_, Space.file_hash, Space.message) - c = PassportElementErrorFile(Space.type_, "", "") - d = PassportElementErrorFile("", Space.file_hash, "") - e = PassportElementErrorFile("", "", Space.message) - f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + a = PassportElementErrorFile(self.type_, self.file_hash, self.message) + b = PassportElementErrorFile(self.type_, self.file_hash, self.message) + c = PassportElementErrorFile(self.type_, "", "") + d = PassportElementErrorFile("", self.file_hash, "") + e = PassportElementErrorFile("", "", self.message) + f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfiles.py b/tests/test_passportelementerrorfiles.py index c43d53a8c79..7e6301b008a 100644 --- a/tests/test_passportelementerrorfiles.py +++ b/tests/test_passportelementerrorfiles.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_files(): - return PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) + return PassportElementErrorFiles( + TestPassportElementErrorFilesBase.type_, + TestPassportElementErrorFilesBase.file_hashes, + TestPassportElementErrorFilesBase.message, + ) -class Space: +class TestPassportElementErrorFilesBase: source = "files" type_ = "test_type" file_hashes = ["hash1", "hash2"] message = "Error message" -class TestPassportElementErrorFilesWithoutRequest: +class TestPassportElementErrorFilesWithoutRequest(TestPassportElementErrorFilesBase): def test_slot_behaviour(self, passport_element_error_files, mro_slots): inst = passport_element_error_files for attr in inst.__slots__: @@ -41,11 +45,11 @@ def test_slot_behaviour(self, passport_element_error_files, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_files): - assert passport_element_error_files.source == Space.source - assert passport_element_error_files.type == Space.type_ + assert passport_element_error_files.source == self.source + assert passport_element_error_files.type == self.type_ assert isinstance(passport_element_error_files.file_hashes, list) - assert passport_element_error_files.file_hashes == Space.file_hashes - assert passport_element_error_files.message == Space.message + assert passport_element_error_files.file_hashes == self.file_hashes + assert passport_element_error_files.message == self.message def test_to_dict(self, passport_element_error_files): passport_element_error_files_dict = passport_element_error_files.to_dict() @@ -60,12 +64,12 @@ def test_to_dict(self, passport_element_error_files): assert passport_element_error_files_dict["message"] == passport_element_error_files.message def test_equality(self): - a = PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) - b = PassportElementErrorFiles(Space.type_, Space.file_hashes, Space.message) - c = PassportElementErrorFiles(Space.type_, "", "") - d = PassportElementErrorFiles("", Space.file_hashes, "") - e = PassportElementErrorFiles("", "", Space.message) - f = PassportElementErrorSelfie(Space.type_, "", Space.message) + a = PassportElementErrorFiles(self.type_, self.file_hashes, self.message) + b = PassportElementErrorFiles(self.type_, self.file_hashes, self.message) + c = PassportElementErrorFiles(self.type_, "", "") + d = PassportElementErrorFiles("", self.file_hashes, "") + e = PassportElementErrorFiles("", "", self.message) + f = PassportElementErrorSelfie(self.type_, "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorfrontside.py b/tests/test_passportelementerrorfrontside.py index dd3ec765390..d45a4a60382 100644 --- a/tests/test_passportelementerrorfrontside.py +++ b/tests/test_passportelementerrorfrontside.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_front_side(): - return PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) + return PassportElementErrorFrontSide( + TestPassportElementErrorFrontSideBase.type_, + TestPassportElementErrorFrontSideBase.file_hash, + TestPassportElementErrorFrontSideBase.message, + ) -class Space: +class TestPassportElementErrorFrontSideBase: source = "front_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorFrontSideWithoutRequest: +class TestPassportElementErrorFrontSideWithoutRequest(TestPassportElementErrorFrontSideBase): def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): inst = passport_element_error_front_side for attr in inst.__slots__: @@ -41,10 +45,10 @@ def test_slot_behaviour(self, passport_element_error_front_side, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_front_side): - assert passport_element_error_front_side.source == Space.source - assert passport_element_error_front_side.type == Space.type_ - assert passport_element_error_front_side.file_hash == Space.file_hash - assert passport_element_error_front_side.message == Space.message + assert passport_element_error_front_side.source == self.source + assert passport_element_error_front_side.type == self.type_ + assert passport_element_error_front_side.file_hash == self.file_hash + assert passport_element_error_front_side.message == self.message def test_to_dict(self, passport_element_error_front_side): passport_element_error_front_side_dict = passport_element_error_front_side.to_dict() @@ -68,12 +72,12 @@ def test_to_dict(self, passport_element_error_front_side): ) def test_equality(self): - a = PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) - b = PassportElementErrorFrontSide(Space.type_, Space.file_hash, Space.message) - c = PassportElementErrorFrontSide(Space.type_, "", "") - d = PassportElementErrorFrontSide("", Space.file_hash, "") - e = PassportElementErrorFrontSide("", "", Space.message) - f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + a = PassportElementErrorFrontSide(self.type_, self.file_hash, self.message) + b = PassportElementErrorFrontSide(self.type_, self.file_hash, self.message) + c = PassportElementErrorFrontSide(self.type_, "", "") + d = PassportElementErrorFrontSide("", self.file_hash, "") + e = PassportElementErrorFrontSide("", "", self.message) + f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorreverseside.py b/tests/test_passportelementerrorreverseside.py index f239af073b9..1808e63dfa7 100644 --- a/tests/test_passportelementerrorreverseside.py +++ b/tests/test_passportelementerrorreverseside.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_reverse_side(): - return PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) + return PassportElementErrorReverseSide( + TestPassportElementErrorReverseSideBase.type_, + TestPassportElementErrorReverseSideBase.file_hash, + TestPassportElementErrorReverseSideBase.message, + ) -class Space: +class TestPassportElementErrorReverseSideBase: source = "reverse_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorReverseSideWithoutRequest: +class TestPassportElementErrorReverseSideWithoutRequest(TestPassportElementErrorReverseSideBase): def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): inst = passport_element_error_reverse_side for attr in inst.__slots__: @@ -41,10 +45,10 @@ def test_slot_behaviour(self, passport_element_error_reverse_side, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_reverse_side): - assert passport_element_error_reverse_side.source == Space.source - assert passport_element_error_reverse_side.type == Space.type_ - assert passport_element_error_reverse_side.file_hash == Space.file_hash - assert passport_element_error_reverse_side.message == Space.message + assert passport_element_error_reverse_side.source == self.source + assert passport_element_error_reverse_side.type == self.type_ + assert passport_element_error_reverse_side.file_hash == self.file_hash + assert passport_element_error_reverse_side.message == self.message def test_to_dict(self, passport_element_error_reverse_side): passport_element_error_reverse_side_dict = passport_element_error_reverse_side.to_dict() @@ -68,12 +72,12 @@ def test_to_dict(self, passport_element_error_reverse_side): ) def test_equality(self): - a = PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) - b = PassportElementErrorReverseSide(Space.type_, Space.file_hash, Space.message) - c = PassportElementErrorReverseSide(Space.type_, "", "") - d = PassportElementErrorReverseSide("", Space.file_hash, "") - e = PassportElementErrorReverseSide("", "", Space.message) - f = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + a = PassportElementErrorReverseSide(self.type_, self.file_hash, self.message) + b = PassportElementErrorReverseSide(self.type_, self.file_hash, self.message) + c = PassportElementErrorReverseSide(self.type_, "", "") + d = PassportElementErrorReverseSide("", self.file_hash, "") + e = PassportElementErrorReverseSide("", "", self.message) + f = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorselfie.py b/tests/test_passportelementerrorselfie.py index b8c8c7c4eb3..892e5a76987 100644 --- a/tests/test_passportelementerrorselfie.py +++ b/tests/test_passportelementerrorselfie.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_selfie(): - return PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) + return PassportElementErrorSelfie( + TestPassportElementErrorSelfieBase.type_, + TestPassportElementErrorSelfieBase.file_hash, + TestPassportElementErrorSelfieBase.message, + ) -class Space: +class TestPassportElementErrorSelfieBase: source = "selfie" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorSelfieWithoutRequest: +class TestPassportElementErrorSelfieWithoutRequest(TestPassportElementErrorSelfieBase): def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): inst = passport_element_error_selfie for attr in inst.__slots__: @@ -41,10 +45,10 @@ def test_slot_behaviour(self, passport_element_error_selfie, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_selfie): - assert passport_element_error_selfie.source == Space.source - assert passport_element_error_selfie.type == Space.type_ - assert passport_element_error_selfie.file_hash == Space.file_hash - assert passport_element_error_selfie.message == Space.message + assert passport_element_error_selfie.source == self.source + assert passport_element_error_selfie.type == self.type_ + assert passport_element_error_selfie.file_hash == self.file_hash + assert passport_element_error_selfie.message == self.message def test_to_dict(self, passport_element_error_selfie): passport_element_error_selfie_dict = passport_element_error_selfie.to_dict() @@ -61,12 +65,12 @@ def test_to_dict(self, passport_element_error_selfie): ) def test_equality(self): - a = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) - b = PassportElementErrorSelfie(Space.type_, Space.file_hash, Space.message) - c = PassportElementErrorSelfie(Space.type_, "", "") - d = PassportElementErrorSelfie("", Space.file_hash, "") - e = PassportElementErrorSelfie("", "", Space.message) - f = PassportElementErrorDataField(Space.type_, "", "", Space.message) + a = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) + b = PassportElementErrorSelfie(self.type_, self.file_hash, self.message) + c = PassportElementErrorSelfie(self.type_, "", "") + d = PassportElementErrorSelfie("", self.file_hash, "") + e = PassportElementErrorSelfie("", "", self.message) + f = PassportElementErrorDataField(self.type_, "", "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrortranslationfile.py b/tests/test_passportelementerrortranslationfile.py index f0aa2c1ee01..71930bc0f3d 100644 --- a/tests/test_passportelementerrortranslationfile.py +++ b/tests/test_passportelementerrortranslationfile.py @@ -23,17 +23,23 @@ @pytest.fixture(scope="module") def passport_element_error_translation_file(): - return PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) + return PassportElementErrorTranslationFile( + TestPassportElementErrorTranslationFileBase.type_, + TestPassportElementErrorTranslationFileBase.file_hash, + TestPassportElementErrorTranslationFileBase.message, + ) -class Space: +class TestPassportElementErrorTranslationFileBase: source = "translation_file" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorTranslationFileWithoutRequest: +class TestPassportElementErrorTranslationFileWithoutRequest( + TestPassportElementErrorTranslationFileBase +): def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots): inst = passport_element_error_translation_file for attr in inst.__slots__: @@ -41,10 +47,10 @@ def test_slot_behaviour(self, passport_element_error_translation_file, mro_slots assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_translation_file): - assert passport_element_error_translation_file.source == Space.source - assert passport_element_error_translation_file.type == Space.type_ - assert passport_element_error_translation_file.file_hash == Space.file_hash - assert passport_element_error_translation_file.message == Space.message + assert passport_element_error_translation_file.source == self.source + assert passport_element_error_translation_file.type == self.type_ + assert passport_element_error_translation_file.file_hash == self.file_hash + assert passport_element_error_translation_file.message == self.message def test_to_dict(self, passport_element_error_translation_file): passport_element_error_translation_file_dict = ( @@ -70,12 +76,12 @@ def test_to_dict(self, passport_element_error_translation_file): ) def test_equality(self): - a = PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) - b = PassportElementErrorTranslationFile(Space.type_, Space.file_hash, Space.message) - c = PassportElementErrorTranslationFile(Space.type_, "", "") - d = PassportElementErrorTranslationFile("", Space.file_hash, "") - e = PassportElementErrorTranslationFile("", "", Space.message) - f = PassportElementErrorDataField(Space.type_, "", "", Space.message) + a = PassportElementErrorTranslationFile(self.type_, self.file_hash, self.message) + b = PassportElementErrorTranslationFile(self.type_, self.file_hash, self.message) + c = PassportElementErrorTranslationFile(self.type_, "", "") + d = PassportElementErrorTranslationFile("", self.file_hash, "") + e = PassportElementErrorTranslationFile("", "", self.message) + f = PassportElementErrorDataField(self.type_, "", "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrortranslationfiles.py b/tests/test_passportelementerrortranslationfiles.py index 954031b985a..09493c4eef8 100644 --- a/tests/test_passportelementerrortranslationfiles.py +++ b/tests/test_passportelementerrortranslationfiles.py @@ -23,17 +23,23 @@ @pytest.fixture(scope="module") def passport_element_error_translation_files(): - return PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) + return PassportElementErrorTranslationFiles( + TestPassportElementErrorTranslationFilesBase.type_, + TestPassportElementErrorTranslationFilesBase.file_hashes, + TestPassportElementErrorTranslationFilesBase.message, + ) -class Space: +class TestPassportElementErrorTranslationFilesBase: source = "translation_files" type_ = "test_type" file_hashes = ["hash1", "hash2"] message = "Error message" -class TestPassportElementErrorTranslationFilesWithoutRequest: +class TestPassportElementErrorTranslationFilesWithoutRequest( + TestPassportElementErrorTranslationFilesBase +): def test_slot_behaviour(self, passport_element_error_translation_files, mro_slots): inst = passport_element_error_translation_files for attr in inst.__slots__: @@ -41,11 +47,11 @@ def test_slot_behaviour(self, passport_element_error_translation_files, mro_slot assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_translation_files): - assert passport_element_error_translation_files.source == Space.source - assert passport_element_error_translation_files.type == Space.type_ + assert passport_element_error_translation_files.source == self.source + assert passport_element_error_translation_files.type == self.type_ assert isinstance(passport_element_error_translation_files.file_hashes, list) - assert passport_element_error_translation_files.file_hashes == Space.file_hashes - assert passport_element_error_translation_files.message == Space.message + assert passport_element_error_translation_files.file_hashes == self.file_hashes + assert passport_element_error_translation_files.message == self.message def test_to_dict(self, passport_element_error_translation_files): passport_element_error_translation_files_dict = ( @@ -71,12 +77,12 @@ def test_to_dict(self, passport_element_error_translation_files): ) def test_equality(self): - a = PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) - b = PassportElementErrorTranslationFiles(Space.type_, Space.file_hashes, Space.message) - c = PassportElementErrorTranslationFiles(Space.type_, "", "") - d = PassportElementErrorTranslationFiles("", Space.file_hashes, "") - e = PassportElementErrorTranslationFiles("", "", Space.message) - f = PassportElementErrorSelfie(Space.type_, "", Space.message) + a = PassportElementErrorTranslationFiles(self.type_, self.file_hashes, self.message) + b = PassportElementErrorTranslationFiles(self.type_, self.file_hashes, self.message) + c = PassportElementErrorTranslationFiles(self.type_, "", "") + d = PassportElementErrorTranslationFiles("", self.file_hashes, "") + e = PassportElementErrorTranslationFiles("", "", self.message) + f = PassportElementErrorSelfie(self.type_, "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportelementerrorunspecified.py b/tests/test_passportelementerrorunspecified.py index 5b6c106817e..4c80b3db399 100644 --- a/tests/test_passportelementerrorunspecified.py +++ b/tests/test_passportelementerrorunspecified.py @@ -23,17 +23,21 @@ @pytest.fixture(scope="module") def passport_element_error_unspecified(): - return PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) + return PassportElementErrorUnspecified( + TestPassportElementErrorUnspecifiedBase.type_, + TestPassportElementErrorUnspecifiedBase.element_hash, + TestPassportElementErrorUnspecifiedBase.message, + ) -class Space: +class TestPassportElementErrorUnspecifiedBase: source = "unspecified" type_ = "test_type" element_hash = "element_hash" message = "Error message" -class TestPassportElementErrorUnspecifiedWithoutRequest: +class TestPassportElementErrorUnspecifiedWithoutRequest(TestPassportElementErrorUnspecifiedBase): def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): inst = passport_element_error_unspecified for attr in inst.__slots__: @@ -41,10 +45,10 @@ def test_slot_behaviour(self, passport_element_error_unspecified, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_element_error_unspecified): - assert passport_element_error_unspecified.source == Space.source - assert passport_element_error_unspecified.type == Space.type_ - assert passport_element_error_unspecified.element_hash == Space.element_hash - assert passport_element_error_unspecified.message == Space.message + assert passport_element_error_unspecified.source == self.source + assert passport_element_error_unspecified.type == self.type_ + assert passport_element_error_unspecified.element_hash == self.element_hash + assert passport_element_error_unspecified.message == self.message def test_to_dict(self, passport_element_error_unspecified): passport_element_error_unspecified_dict = passport_element_error_unspecified.to_dict() @@ -68,12 +72,12 @@ def test_to_dict(self, passport_element_error_unspecified): ) def test_equality(self): - a = PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) - b = PassportElementErrorUnspecified(Space.type_, Space.element_hash, Space.message) - c = PassportElementErrorUnspecified(Space.type_, "", "") - d = PassportElementErrorUnspecified("", Space.element_hash, "") - e = PassportElementErrorUnspecified("", "", Space.message) - f = PassportElementErrorDataField(Space.type_, "", "", Space.message) + a = PassportElementErrorUnspecified(self.type_, self.element_hash, self.message) + b = PassportElementErrorUnspecified(self.type_, self.element_hash, self.message) + c = PassportElementErrorUnspecified(self.type_, "", "") + d = PassportElementErrorUnspecified("", self.element_hash, "") + e = PassportElementErrorUnspecified("", "", self.message) + f = PassportElementErrorDataField(self.type_, "", "", self.message) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_passportfile.py b/tests/test_passportfile.py index c49133cc02a..4b5837fcdbd 100644 --- a/tests/test_passportfile.py +++ b/tests/test_passportfile.py @@ -29,23 +29,23 @@ @pytest.fixture(scope="class") def passport_file(bot): pf = PassportFile( - file_id=Space.file_id, - file_unique_id=Space.file_unique_id, - file_size=Space.file_size, - file_date=Space.file_date, + file_id=TestPassportFileBase.file_id, + file_unique_id=TestPassportFileBase.file_unique_id, + file_size=TestPassportFileBase.file_size, + file_date=TestPassportFileBase.file_date, ) pf.set_bot(bot) return pf -class Space: +class TestPassportFileBase: file_id = "data" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_size = 50 file_date = 1532879128 -class TestPassportFileWithoutRequest: +class TestPassportFileWithoutRequest(TestPassportFileBase): def test_slot_behaviour(self, passport_file, mro_slots): inst = passport_file for attr in inst.__slots__: @@ -53,10 +53,10 @@ def test_slot_behaviour(self, passport_file, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, passport_file): - assert passport_file.file_id == Space.file_id - assert passport_file.file_unique_id == Space.file_unique_id - assert passport_file.file_size == Space.file_size - assert passport_file.file_date == Space.file_date + assert passport_file.file_id == self.file_id + assert passport_file.file_unique_id == self.file_unique_id + assert passport_file.file_size == self.file_size + assert passport_file.file_date == self.file_date def test_to_dict(self, passport_file): passport_file_dict = passport_file.to_dict() @@ -68,10 +68,10 @@ def test_to_dict(self, passport_file): assert passport_file_dict["file_date"] == passport_file.file_date def test_equality(self): - a = PassportFile(Space.file_id, Space.file_unique_id, Space.file_size, Space.file_date) - b = PassportFile("", Space.file_unique_id, Space.file_size, Space.file_date) - c = PassportFile(Space.file_id, Space.file_unique_id, "", "") - d = PassportFile("", "", Space.file_size, Space.file_date) + a = PassportFile(self.file_id, self.file_unique_id, self.file_size, self.file_date) + b = PassportFile("", self.file_unique_id, self.file_size, self.file_date) + c = PassportFile(self.file_id, self.file_unique_id, "", "") + d = PassportFile("", "", self.file_size, self.file_date) e = PassportElementError("source", "type", "message") assert a == b diff --git a/tests/test_photo.py b/tests/test_photo.py index bcc5cc05146..bed123f637e 100644 --- a/tests/test_photo.py +++ b/tests/test_photo.py @@ -61,7 +61,7 @@ def photo(_photo): return _photo[-1] -class Space: +class TestPhotoBase: width = 800 height = 800 caption = "PhotoTest - *Caption*" @@ -71,7 +71,7 @@ class Space: file_size = [29176, 27662] -class TestPhotoWithoutRequest: +class TestPhotoWithoutRequest(TestPhotoBase): def test_slot_behaviour(self, photo, mro_slots): for attr in photo.__slots__: assert getattr(photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -92,9 +92,9 @@ def test_creation(self, thumb, photo): assert thumb.file_unique_id != "" def test_expected_values(self, photo, thumb): - assert photo.width == Space.width - assert photo.height == Space.height - assert photo.file_size in Space.file_size + assert photo.width == self.width + assert photo.height == self.height + assert photo.file_size in self.file_size assert thumb.width == 90 assert thumb.height == 90 assert thumb.file_size == 1477 @@ -103,18 +103,18 @@ def test_de_json(self, bot, photo): json_dict = { "file_id": photo.file_id, "file_unique_id": photo.file_unique_id, - "width": Space.width, - "height": Space.height, - "file_size": Space.file_size, + "width": self.width, + "height": self.height, + "file_size": self.file_size, } json_photo = PhotoSize.de_json(json_dict, bot) assert json_photo.api_kwargs == {} assert json_photo.file_id == photo.file_id assert json_photo.file_unique_id == photo.file_unique_id - assert json_photo.width == Space.width - assert json_photo.height == Space.height - assert json_photo.file_size == Space.file_size + assert json_photo.width == self.width + assert json_photo.height == self.height + assert json_photo.file_size == self.file_size def test_to_dict(self, photo): photo_dict = photo.to_dict() @@ -127,15 +127,15 @@ def test_to_dict(self, photo): assert photo_dict["file_size"] == photo.file_size def test_equality(self, photo): - a = PhotoSize(photo.file_id, photo.file_unique_id, Space.width, Space.height) - b = PhotoSize("", photo.file_unique_id, Space.width, Space.height) + a = PhotoSize(photo.file_id, photo.file_unique_id, self.width, self.height) + b = PhotoSize("", photo.file_unique_id, self.width, self.height) c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0) - d = PhotoSize("", "", Space.width, Space.height) + d = PhotoSize("", "", self.width, self.height) e = Sticker( photo.file_id, photo.file_unique_id, - Space.width, - Space.height, + self.width, + self.height, False, False, Sticker.REGULAR, @@ -206,12 +206,12 @@ async def make_assertion(*_, **kwargs): assert await photo.get_file() -class TestPhotoWithRequest: +class TestPhotoWithRequest(TestPhotoBase): async def test_send_photo_all_args(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, photo_file, - caption=Space.caption, + caption=self.caption, disable_notification=False, protect_content=True, parse_mode="Markdown", @@ -230,13 +230,13 @@ async def test_send_photo_all_args(self, bot, chat_id, photo_file): assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == Space.caption.replace("*", "") + assert message.caption == self.caption.replace("*", "") assert message.has_protected_content assert message.has_media_spoiler async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file): message = await bot.send_photo( - chat_id, photo_file, caption=Space.caption, parse_mode="Markdown" + chat_id, photo_file, caption=self.caption, parse_mode="Markdown" ) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) @@ -250,12 +250,12 @@ async def test_send_photo_parse_mode_markdown(self, bot, chat_id, photo_file): assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == Space.caption.replace("*", "") + assert message.caption == self.caption.replace("*", "") assert len(message.caption_entities) == 1 async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file): message = await bot.send_photo( - chat_id, photo_file, caption=Space.caption, parse_mode="HTML" + chat_id, photo_file, caption=self.caption, parse_mode="HTML" ) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) @@ -269,7 +269,7 @@ async def test_send_photo_parse_mode_html(self, bot, chat_id, photo_file): assert message.photo[-1].file_id != "" assert message.photo[-1].file_unique_id != "" - assert message.caption == Space.caption.replace("", "").replace("", "") + assert message.caption == self.caption.replace("", "").replace("", "") assert len(message.caption_entities) == 1 async def test_send_photo_caption_entities(self, bot, chat_id, photo_file): @@ -374,7 +374,7 @@ async def test_get_and_download(self, bot, photo): assert path.is_file() async def test_send_url_jpg_file(self, bot, chat_id): - message = await bot.send_photo(chat_id, photo=Space.photo_file_url) + message = await bot.send_photo(chat_id, photo=self.photo_file_url) assert isinstance(message.photo[-2], PhotoSize) assert isinstance(message.photo[-2].file_id, str) diff --git a/tests/test_poll.py b/tests/test_poll.py index f7813c141ce..3fc49f46d64 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -26,29 +26,29 @@ @pytest.fixture(scope="module") def poll_option(): - out = PollOption(text=PollOptionSpace.text, voter_count=PollOptionSpace.voter_count) + out = PollOption(text=TestPollOptionBase.text, voter_count=TestPollOptionBase.voter_count) out._unfreeze() return out -class PollOptionSpace: +class TestPollOptionBase: text = "test option" voter_count = 3 -class TestPollOptionWithoutRequest: +class TestPollOptionWithoutRequest(TestPollOptionBase): def test_slot_behaviour(self, poll_option, mro_slots): for attr in poll_option.__slots__: assert getattr(poll_option, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(poll_option)) == len(set(mro_slots(poll_option))), "duplicate slot" def test_de_json(self): - json_dict = {"text": PollOptionSpace.text, "voter_count": PollOptionSpace.voter_count} + json_dict = {"text": self.text, "voter_count": self.voter_count} poll_option = PollOption.de_json(json_dict, None) assert poll_option.api_kwargs == {} - assert poll_option.text == PollOptionSpace.text - assert poll_option.voter_count == PollOptionSpace.voter_count + assert poll_option.text == self.text + assert poll_option.voter_count == self.voter_count def test_to_dict(self, poll_option): poll_option_dict = poll_option.to_dict() @@ -79,28 +79,30 @@ def test_equality(self): @pytest.fixture(scope="module") def poll_answer(): - return PollAnswer(PollAnswerSpace.poll_id, PollAnswerSpace.user, PollAnswerSpace.poll_id) + return PollAnswer( + TestPollAnswerBase.poll_id, TestPollAnswerBase.user, TestPollAnswerBase.poll_id + ) -class PollAnswerSpace: +class TestPollAnswerBase: poll_id = "id" user = User(1, "", False) option_ids = [2] -class TestPollAnswerWithoutRequest: +class TestPollAnswerWithoutRequest(TestPollAnswerBase): def test_de_json(self): json_dict = { - "poll_id": PollAnswerSpace.poll_id, - "user": PollAnswerSpace.user.to_dict(), - "option_ids": PollAnswerSpace.option_ids, + "poll_id": self.poll_id, + "user": self.user.to_dict(), + "option_ids": self.option_ids, } poll_answer = PollAnswer.de_json(json_dict, None) assert poll_answer.api_kwargs == {} - assert poll_answer.poll_id == PollAnswerSpace.poll_id - assert poll_answer.user == PollAnswerSpace.user - assert poll_answer.option_ids == tuple(PollAnswerSpace.option_ids) + assert poll_answer.poll_id == self.poll_id + assert poll_answer.user == self.user + assert poll_answer.option_ids == tuple(self.option_ids) def test_to_dict(self, poll_answer): poll_answer_dict = poll_answer.to_dict() @@ -111,10 +113,10 @@ def test_to_dict(self, poll_answer): assert poll_answer_dict["option_ids"] == list(poll_answer.option_ids) def test_equality(self): - a = PollAnswer(123, PollAnswerSpace.user, [2]) + a = PollAnswer(123, self.user, [2]) b = PollAnswer(123, User(1, "first", False), [2]) - c = PollAnswer(123, PollAnswerSpace.user, [1, 2]) - d = PollAnswer(456, PollAnswerSpace.user, [2]) + c = PollAnswer(123, self.user, [1, 2]) + d = PollAnswer(456, self.user, [2]) e = PollOption("Text", 1) assert a == b @@ -133,24 +135,24 @@ def test_equality(self): @pytest.fixture(scope="module") def poll(): poll = Poll( - PollSpace.id_, - PollSpace.question, - PollSpace.options, - PollSpace.total_voter_count, - PollSpace.is_closed, - PollSpace.is_anonymous, - PollSpace.type, - PollSpace.allows_multiple_answers, - explanation=PollSpace.explanation, - explanation_entities=PollSpace.explanation_entities, - open_period=PollSpace.open_period, - close_date=PollSpace.close_date, + TestPollBase.id_, + TestPollBase.question, + TestPollBase.options, + TestPollBase.total_voter_count, + TestPollBase.is_closed, + TestPollBase.is_anonymous, + TestPollBase.type, + TestPollBase.allows_multiple_answers, + explanation=TestPollBase.explanation, + explanation_entities=TestPollBase.explanation_entities, + open_period=TestPollBase.open_period, + close_date=TestPollBase.close_date, ) poll._unfreeze() return poll -class PollSpace: +class TestPollBase: id_ = "id" question = "Test?" options = [PollOption("test", 10), PollOption("test2", 11)] @@ -168,42 +170,42 @@ class PollSpace: close_date = datetime.now(timezone.utc) -class TestPollWithoutRequest: +class TestPollWithoutRequest(TestPollBase): def test_de_json(self, bot): json_dict = { - "id": PollSpace.id_, - "question": PollSpace.question, - "options": [o.to_dict() for o in PollSpace.options], - "total_voter_count": PollSpace.total_voter_count, - "is_closed": PollSpace.is_closed, - "is_anonymous": PollSpace.is_anonymous, - "type": PollSpace.type, - "allows_multiple_answers": PollSpace.allows_multiple_answers, - "explanation": PollSpace.explanation, - "explanation_entities": [PollSpace.explanation_entities[0].to_dict()], - "open_period": PollSpace.open_period, - "close_date": to_timestamp(PollSpace.close_date), + "id": self.id_, + "question": self.question, + "options": [o.to_dict() for o in self.options], + "total_voter_count": self.total_voter_count, + "is_closed": self.is_closed, + "is_anonymous": self.is_anonymous, + "type": self.type, + "allows_multiple_answers": self.allows_multiple_answers, + "explanation": self.explanation, + "explanation_entities": [self.explanation_entities[0].to_dict()], + "open_period": self.open_period, + "close_date": to_timestamp(self.close_date), } poll = Poll.de_json(json_dict, bot) assert poll.api_kwargs == {} - assert poll.id == PollSpace.id_ - assert poll.question == PollSpace.question - assert poll.options == tuple(PollSpace.options) - assert poll.options[0].text == PollSpace.options[0].text - assert poll.options[0].voter_count == PollSpace.options[0].voter_count - assert poll.options[1].text == PollSpace.options[1].text - assert poll.options[1].voter_count == PollSpace.options[1].voter_count - assert poll.total_voter_count == PollSpace.total_voter_count - assert poll.is_closed == PollSpace.is_closed - assert poll.is_anonymous == PollSpace.is_anonymous - assert poll.type == PollSpace.type - assert poll.allows_multiple_answers == PollSpace.allows_multiple_answers - assert poll.explanation == PollSpace.explanation - assert poll.explanation_entities == tuple(PollSpace.explanation_entities) - assert poll.open_period == PollSpace.open_period - assert abs(poll.close_date - PollSpace.close_date) < timedelta(seconds=1) - assert to_timestamp(poll.close_date) == to_timestamp(PollSpace.close_date) + assert poll.id == self.id_ + assert poll.question == self.question + assert poll.options == tuple(self.options) + assert poll.options[0].text == self.options[0].text + assert poll.options[0].voter_count == self.options[0].voter_count + assert poll.options[1].text == self.options[1].text + assert poll.options[1].voter_count == self.options[1].voter_count + assert poll.total_voter_count == self.total_voter_count + assert poll.is_closed == self.is_closed + assert poll.is_anonymous == self.is_anonymous + assert poll.type == self.type + assert poll.allows_multiple_answers == self.allows_multiple_answers + assert poll.explanation == self.explanation + assert poll.explanation_entities == tuple(self.explanation_entities) + assert poll.open_period == self.open_period + assert abs(poll.close_date - self.close_date) < timedelta(seconds=1) + assert to_timestamp(poll.close_date) == to_timestamp(self.close_date) def test_to_dict(self, poll): poll_dict = poll.to_dict() diff --git a/tests/test_precheckoutquery.py b/tests/test_precheckoutquery.py index 124c3584070..61cb8a3e27e 100644 --- a/tests/test_precheckoutquery.py +++ b/tests/test_precheckoutquery.py @@ -30,19 +30,19 @@ @pytest.fixture(scope="module") def pre_checkout_query(bot): pcq = PreCheckoutQuery( - Space.id_, - Space.from_user, - Space.currency, - Space.total_amount, - Space.invoice_payload, - shipping_option_id=Space.shipping_option_id, - order_info=Space.order_info, + TestPreCheckoutQueryBase.id_, + TestPreCheckoutQueryBase.from_user, + TestPreCheckoutQueryBase.currency, + TestPreCheckoutQueryBase.total_amount, + TestPreCheckoutQueryBase.invoice_payload, + shipping_option_id=TestPreCheckoutQueryBase.shipping_option_id, + order_info=TestPreCheckoutQueryBase.order_info, ) pcq.set_bot(bot) return pcq -class Space: +class TestPreCheckoutQueryBase: id_ = 5 invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" @@ -52,7 +52,7 @@ class Space: order_info = OrderInfo() -class TestPreCheckoutQueryWithoutRequest: +class TestPreCheckoutQueryWithoutRequest(TestPreCheckoutQueryBase): def test_slot_behaviour(self, pre_checkout_query, mro_slots): inst = pre_checkout_query for attr in inst.__slots__: @@ -61,24 +61,24 @@ def test_slot_behaviour(self, pre_checkout_query, mro_slots): def test_de_json(self, bot): json_dict = { - "id": Space.id_, - "invoice_payload": Space.invoice_payload, - "shipping_option_id": Space.shipping_option_id, - "currency": Space.currency, - "total_amount": Space.total_amount, - "from": Space.from_user.to_dict(), - "order_info": Space.order_info.to_dict(), + "id": self.id_, + "invoice_payload": self.invoice_payload, + "shipping_option_id": self.shipping_option_id, + "currency": self.currency, + "total_amount": self.total_amount, + "from": self.from_user.to_dict(), + "order_info": self.order_info.to_dict(), } pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot) assert pre_checkout_query.api_kwargs == {} assert pre_checkout_query.get_bot() is bot - assert pre_checkout_query.id == Space.id_ - assert pre_checkout_query.invoice_payload == Space.invoice_payload - assert pre_checkout_query.shipping_option_id == Space.shipping_option_id - assert pre_checkout_query.currency == Space.currency - assert pre_checkout_query.from_user == Space.from_user - assert pre_checkout_query.order_info == Space.order_info + 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 def test_to_dict(self, pre_checkout_query): pre_checkout_query_dict = pre_checkout_query.to_dict() @@ -95,16 +95,16 @@ def test_to_dict(self, pre_checkout_query): def test_equality(self): a = PreCheckoutQuery( - Space.id_, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload + self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload ) b = PreCheckoutQuery( - Space.id_, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload + self.id_, self.from_user, self.currency, self.total_amount, self.invoice_payload ) - c = PreCheckoutQuery(Space.id_, None, "", 0, "") + c = PreCheckoutQuery(self.id_, None, "", 0, "") d = PreCheckoutQuery( - 0, Space.from_user, Space.currency, Space.total_amount, Space.invoice_payload + 0, self.from_user, self.currency, self.total_amount, self.invoice_payload ) - e = Update(Space.id_) + e = Update(self.id_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index 78008c34be2..456c72b36ba 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -24,19 +24,19 @@ @pytest.fixture(scope="module") def proximity_alert_triggered(): return ProximityAlertTriggered( - Space.traveler, - Space.watcher, - Space.distance, + TestProximityAlertTriggeredBase.traveler, + TestProximityAlertTriggeredBase.watcher, + TestProximityAlertTriggeredBase.distance, ) -class Space: +class TestProximityAlertTriggeredBase: traveler = User(1, "foo", False) watcher = User(2, "bar", False) distance = 42 -class TestProximityAlertTriggeredWithoutRequest: +class TestProximityAlertTriggeredWithoutRequest(TestProximityAlertTriggeredBase): def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): inst = proximity_alert_triggered for attr in inst.__slots__: @@ -45,18 +45,18 @@ def test_slot_behaviour(self, proximity_alert_triggered, mro_slots): def test_de_json(self, bot): json_dict = { - "traveler": Space.traveler.to_dict(), - "watcher": Space.watcher.to_dict(), - "distance": Space.distance, + "traveler": self.traveler.to_dict(), + "watcher": self.watcher.to_dict(), + "distance": self.distance, } proximity_alert_triggered = ProximityAlertTriggered.de_json(json_dict, bot) assert proximity_alert_triggered.api_kwargs == {} - assert proximity_alert_triggered.traveler == Space.traveler - assert proximity_alert_triggered.traveler.first_name == Space.traveler.first_name - assert proximity_alert_triggered.watcher == Space.watcher - assert proximity_alert_triggered.watcher.first_name == Space.watcher.first_name - assert proximity_alert_triggered.distance == Space.distance + assert proximity_alert_triggered.traveler == self.traveler + assert proximity_alert_triggered.traveler.first_name == self.traveler.first_name + assert proximity_alert_triggered.watcher == self.watcher + assert proximity_alert_triggered.watcher.first_name == self.watcher.first_name + assert proximity_alert_triggered.distance == self.distance def test_to_dict(self, proximity_alert_triggered): proximity_alert_triggered_dict = proximity_alert_triggered.to_dict() diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index b10b2dbff51..f56f3c8df7e 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -25,15 +25,15 @@ @pytest.fixture(scope="module") def reply_keyboard_markup(): return ReplyKeyboardMarkup( - Space.keyboard, - resize_keyboard=Space.resize_keyboard, - one_time_keyboard=Space.one_time_keyboard, - selective=Space.selective, - is_persistent=Space.is_persistent, + TestReplyKeyboardMarkupBase.keyboard, + resize_keyboard=TestReplyKeyboardMarkupBase.resize_keyboard, + one_time_keyboard=TestReplyKeyboardMarkupBase.one_time_keyboard, + selective=TestReplyKeyboardMarkupBase.selective, + is_persistent=TestReplyKeyboardMarkupBase.is_persistent, ) -class Space: +class TestReplyKeyboardMarkupBase: keyboard = [[KeyboardButton("button1"), KeyboardButton("button2")]] resize_keyboard = True one_time_keyboard = True @@ -41,7 +41,7 @@ class Space: is_persistent = True -class TestReplyKeyboardMarkupWithoutRequest: +class TestReplyKeyboardMarkupWithoutRequest(TestReplyKeyboardMarkupBase): def test_slot_behaviour(self, reply_keyboard_markup, mro_slots): inst = reply_keyboard_markup for attr in inst.__slots__: @@ -53,10 +53,10 @@ def test_expected_values(self, reply_keyboard_markup): assert all(isinstance(row, tuple) for row in reply_keyboard_markup.keyboard) assert isinstance(reply_keyboard_markup.keyboard[0][0], KeyboardButton) assert isinstance(reply_keyboard_markup.keyboard[0][1], KeyboardButton) - assert reply_keyboard_markup.resize_keyboard == Space.resize_keyboard - assert reply_keyboard_markup.one_time_keyboard == Space.one_time_keyboard - assert reply_keyboard_markup.selective == Space.selective - assert reply_keyboard_markup.is_persistent == Space.is_persistent + 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 + assert reply_keyboard_markup.is_persistent == self.is_persistent def test_to_dict(self, reply_keyboard_markup): reply_keyboard_markup_dict = reply_keyboard_markup.to_dict() @@ -151,7 +151,7 @@ def test_from_column(self): assert len(reply_keyboard_markup[1]) == 1 -class TestReplyKeyboardMarkupWithRequest: +class TestReplyKeyboardMarkupWithRequest(TestReplyKeyboardMarkupBase): async def test_send_message_with_reply_keyboard_markup( self, bot, chat_id, reply_keyboard_markup ): diff --git a/tests/test_replykeyboardremove.py b/tests/test_replykeyboardremove.py index db37015852b..3845f5fc5cd 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -23,15 +23,15 @@ @pytest.fixture(scope="module") def reply_keyboard_remove(): - return ReplyKeyboardRemove(selective=Space.selective) + return ReplyKeyboardRemove(selective=TestReplyKeyboardRemoveBase.selective) -class Space: +class TestReplyKeyboardRemoveBase: remove_keyboard = True selective = True -class TestReplyKeyboardRemoveWithoutRequest: +class TestReplyKeyboardRemoveWithoutRequest(TestReplyKeyboardRemoveBase): def test_slot_behaviour(self, reply_keyboard_remove, mro_slots): inst = reply_keyboard_remove for attr in inst.__slots__: @@ -39,8 +39,8 @@ def test_slot_behaviour(self, reply_keyboard_remove, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, reply_keyboard_remove): - assert reply_keyboard_remove.remove_keyboard == Space.remove_keyboard - assert reply_keyboard_remove.selective == Space.selective + 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() @@ -51,7 +51,7 @@ def test_to_dict(self, reply_keyboard_remove): assert reply_keyboard_remove_dict["selective"] == reply_keyboard_remove.selective -class TestReplyKeyboardRemoveWithRequest: +class TestReplyKeyboardRemoveWithRequest(TestReplyKeyboardRemoveBase): async def test_send_message_with_reply_keyboard_remove( self, bot, chat_id, reply_keyboard_remove ): diff --git a/tests/test_sentwebappmessage.py b/tests/test_sentwebappmessage.py index dae0f0bfabd..4304ab6bf25 100644 --- a/tests/test_sentwebappmessage.py +++ b/tests/test_sentwebappmessage.py @@ -24,14 +24,14 @@ @pytest.fixture(scope="module") def sent_web_app_message(): - return SentWebAppMessage(inline_message_id=Space.inline_message_id) + return SentWebAppMessage(inline_message_id=TestSentWebAppMessageBase.inline_message_id) -class Space: +class TestSentWebAppMessageBase: inline_message_id = "123" -class TestSentWebAppMessageWithoutRequest: +class TestSentWebAppMessageWithoutRequest(TestSentWebAppMessageBase): def test_slot_behaviour(self, sent_web_app_message, mro_slots): inst = sent_web_app_message for attr in inst.__slots__: @@ -42,17 +42,17 @@ def test_to_dict(self, sent_web_app_message): sent_web_app_message_dict = sent_web_app_message.to_dict() assert isinstance(sent_web_app_message_dict, dict) - assert sent_web_app_message_dict["inline_message_id"] == Space.inline_message_id + assert sent_web_app_message_dict["inline_message_id"] == self.inline_message_id def test_de_json(self, bot): - data = {"inline_message_id": Space.inline_message_id} + data = {"inline_message_id": self.inline_message_id} m = SentWebAppMessage.de_json(data, None) assert m.api_kwargs == {} - assert m.inline_message_id == Space.inline_message_id + assert m.inline_message_id == self.inline_message_id def test_equality(self): - a = SentWebAppMessage(Space.inline_message_id) - b = SentWebAppMessage(Space.inline_message_id) + a = SentWebAppMessage(self.inline_message_id) + b = SentWebAppMessage(self.inline_message_id) c = SentWebAppMessage("") d = SentWebAppMessage("not_inline_message_id") diff --git a/tests/test_shippingaddress.py b/tests/test_shippingaddress.py index 4d4a9bcdd29..439af462518 100644 --- a/tests/test_shippingaddress.py +++ b/tests/test_shippingaddress.py @@ -24,16 +24,16 @@ @pytest.fixture(scope="module") def shipping_address(): return ShippingAddress( - Space.country_code, - Space.state, - Space.city, - Space.street_line1, - Space.street_line2, - Space.post_code, + TestShippingAddressBase.country_code, + TestShippingAddressBase.state, + TestShippingAddressBase.city, + TestShippingAddressBase.street_line1, + TestShippingAddressBase.street_line2, + TestShippingAddressBase.post_code, ) -class Space: +class TestShippingAddressBase: country_code = "GB" state = "state" city = "London" @@ -42,7 +42,7 @@ class Space: post_code = "WC1" -class TestShippingAddressWithoutRequest: +class TestShippingAddressWithoutRequest(TestShippingAddressBase): def test_slot_behaviour(self, shipping_address, mro_slots): inst = shipping_address for attr in inst.__slots__: @@ -51,22 +51,22 @@ def test_slot_behaviour(self, shipping_address, mro_slots): def test_de_json(self, bot): json_dict = { - "country_code": Space.country_code, - "state": Space.state, - "city": Space.city, - "street_line1": Space.street_line1, - "street_line2": Space.street_line2, - "post_code": Space.post_code, + "country_code": self.country_code, + "state": self.state, + "city": self.city, + "street_line1": self.street_line1, + "street_line2": self.street_line2, + "post_code": self.post_code, } shipping_address = ShippingAddress.de_json(json_dict, bot) assert shipping_address.api_kwargs == {} - assert shipping_address.country_code == Space.country_code - assert shipping_address.state == Space.state - assert shipping_address.city == Space.city - assert shipping_address.street_line1 == Space.street_line1 - assert shipping_address.street_line2 == Space.street_line2 - assert shipping_address.post_code == Space.post_code + 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 def test_to_dict(self, shipping_address): shipping_address_dict = shipping_address.to_dict() @@ -81,48 +81,48 @@ def test_to_dict(self, shipping_address): def test_equality(self): a = ShippingAddress( - Space.country_code, - Space.state, - Space.city, - Space.street_line1, - Space.street_line2, - Space.post_code, + self.country_code, + self.state, + self.city, + self.street_line1, + self.street_line2, + self.post_code, ) b = ShippingAddress( - Space.country_code, - Space.state, - Space.city, - Space.street_line1, - Space.street_line2, - Space.post_code, + self.country_code, + self.state, + self.city, + self.street_line1, + self.street_line2, + self.post_code, ) d = ShippingAddress( - "", Space.state, Space.city, Space.street_line1, Space.street_line2, Space.post_code + "", self.state, self.city, self.street_line1, self.street_line2, self.post_code ) d2 = ShippingAddress( - Space.country_code, + self.country_code, "", - Space.city, - Space.street_line1, - Space.street_line2, - Space.post_code, + self.city, + self.street_line1, + self.street_line2, + self.post_code, ) d3 = ShippingAddress( - Space.country_code, - Space.state, + self.country_code, + self.state, "", - Space.street_line1, - Space.street_line2, - Space.post_code, + self.street_line1, + self.street_line2, + self.post_code, ) d4 = ShippingAddress( - Space.country_code, Space.state, Space.city, "", Space.street_line2, Space.post_code + self.country_code, self.state, self.city, "", self.street_line2, self.post_code ) d5 = ShippingAddress( - Space.country_code, Space.state, Space.city, Space.street_line1, "", Space.post_code + self.country_code, self.state, self.city, self.street_line1, "", self.post_code ) d6 = ShippingAddress( - Space.country_code, Space.state, Space.city, Space.street_line1, Space.street_line2, "" + self.country_code, self.state, self.city, self.street_line1, self.street_line2, "" ) assert a == b diff --git a/tests/test_shippingoption.py b/tests/test_shippingoption.py index 16e059b8515..05832e9317b 100644 --- a/tests/test_shippingoption.py +++ b/tests/test_shippingoption.py @@ -23,16 +23,18 @@ @pytest.fixture(scope="module") def shipping_option(): - return ShippingOption(Space.id_, Space.title, Space.prices) + return ShippingOption( + TestShippingOptionBase.id_, TestShippingOptionBase.title, TestShippingOptionBase.prices + ) -class Space: +class TestShippingOptionBase: id_ = "id" title = "title" prices = [LabeledPrice("Fish Container", 100), LabeledPrice("Premium Fish Container", 1000)] -class TestShippingOptionWithoutRequest: +class TestShippingOptionWithoutRequest(TestShippingOptionBase): def test_slot_behaviour(self, shipping_option, mro_slots): inst = shipping_option for attr in inst.__slots__: @@ -40,9 +42,9 @@ def test_slot_behaviour(self, shipping_option, mro_slots): assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_expected_values(self, shipping_option): - assert shipping_option.id == Space.id_ - assert shipping_option.title == Space.title - assert shipping_option.prices == tuple(Space.prices) + assert shipping_option.id == self.id_ + assert shipping_option.title == self.title + assert shipping_option.prices == tuple(self.prices) def test_to_dict(self, shipping_option): shipping_option_dict = shipping_option.to_dict() @@ -54,11 +56,11 @@ def test_to_dict(self, shipping_option): assert shipping_option_dict["prices"][1] == shipping_option.prices[1].to_dict() def test_equality(self): - a = ShippingOption(Space.id_, Space.title, Space.prices) - b = ShippingOption(Space.id_, Space.title, Space.prices) - c = ShippingOption(Space.id_, "", []) - d = ShippingOption(0, Space.title, Space.prices) - e = Voice(Space.id_, "someid", 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_, "someid", 0) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_shippingquery.py b/tests/test_shippingquery.py index a5df651724a..4855119180c 100644 --- a/tests/test_shippingquery.py +++ b/tests/test_shippingquery.py @@ -29,19 +29,24 @@ @pytest.fixture(scope="module") def shipping_query(bot): - sq = ShippingQuery(Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address) + sq = ShippingQuery( + TestShippingQueryBase.id_, + TestShippingQueryBase.from_user, + TestShippingQueryBase.invoice_payload, + TestShippingQueryBase.shipping_address, + ) sq.set_bot(bot) return sq -class Space: +class TestShippingQueryBase: id_ = "5" invoice_payload = "invoice_payload" from_user = User(0, "", False) shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestShippingQueryWithoutRequest: +class TestShippingQueryWithoutRequest(TestShippingQueryBase): def test_slot_behaviour(self, shipping_query, mro_slots): inst = shipping_query for attr in inst.__slots__: @@ -50,18 +55,18 @@ def test_slot_behaviour(self, shipping_query, mro_slots): def test_de_json(self, bot): json_dict = { - "id": Space.id_, - "invoice_payload": Space.invoice_payload, - "from": Space.from_user.to_dict(), - "shipping_address": Space.shipping_address.to_dict(), + "id": self.id_, + "invoice_payload": self.invoice_payload, + "from": self.from_user.to_dict(), + "shipping_address": self.shipping_address.to_dict(), } shipping_query = ShippingQuery.de_json(json_dict, bot) assert shipping_query.api_kwargs == {} - assert shipping_query.id == Space.id_ - assert shipping_query.invoice_payload == Space.invoice_payload - assert shipping_query.from_user == Space.from_user - assert shipping_query.shipping_address == Space.shipping_address + 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 assert shipping_query.get_bot() is bot def test_to_dict(self, shipping_query): @@ -74,15 +79,11 @@ def test_to_dict(self, shipping_query): assert shipping_query_dict["shipping_address"] == shipping_query.shipping_address.to_dict() def test_equality(self): - a = ShippingQuery( - Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address - ) - b = ShippingQuery( - Space.id_, Space.from_user, Space.invoice_payload, Space.shipping_address - ) - c = ShippingQuery(Space.id_, None, "", None) - d = ShippingQuery(0, Space.from_user, Space.invoice_payload, Space.shipping_address) - e = Update(Space.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_) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_sticker.py b/tests/test_sticker.py index ec61fbf1fd4..75ff7a9341b 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -69,7 +69,7 @@ def video_sticker(bot, chat_id): return bot.send_sticker(chat_id, sticker=f, timeout=50).sticker -class StickerSpace: +class TestStickerBase: # 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 = ( @@ -95,7 +95,7 @@ class StickerSpace: premium_animation = File("this_is_an_id", "this_is_an_unique_id") -class TestStickerWithoutRequest: +class TestStickerWithoutRequest(TestStickerBase): def test_slot_behaviour(self, sticker, mro_slots): for attr in sticker.__slots__: assert getattr(sticker, attr, "err") != "err", f"got extra slot '{attr}'" @@ -115,17 +115,17 @@ def test_creation(self, sticker): assert sticker.thumb.file_unique_id != "" def test_expected_values(self, sticker): - assert sticker.width == StickerSpace.width - assert sticker.height == StickerSpace.height - assert sticker.is_animated == StickerSpace.is_animated - assert sticker.is_video == StickerSpace.is_video - assert sticker.file_size == StickerSpace.file_size - assert sticker.thumb.width == StickerSpace.thumb_width - assert sticker.thumb.height == StickerSpace.thumb_height - assert sticker.thumb.file_size == StickerSpace.thumb_file_size - assert sticker.type == StickerSpace.type + assert sticker.width == self.width + assert sticker.height == self.height + assert sticker.is_animated == self.is_animated + assert sticker.is_video == self.is_video + assert sticker.file_size == self.file_size + assert sticker.thumb.width == self.thumb_width + assert sticker.thumb.height == self.thumb_height + assert sticker.thumb.file_size == self.thumb_file_size + assert sticker.type == self.type # we need to be a premium TG user to send a premium sticker, so the below is not tested - # assert sticker.premium_animation == StickerSpace.premium_animation + # assert sticker.premium_animation == self.premium_animation def test_to_dict(self, sticker): sticker_dict = sticker.to_dict() @@ -143,53 +143,53 @@ def test_to_dict(self, sticker): def test_de_json(self, bot, sticker): json_dict = { - "file_id": StickerSpace.sticker_file_id, - "file_unique_id": StickerSpace.sticker_file_unique_id, - "width": StickerSpace.width, - "height": StickerSpace.height, - "is_animated": StickerSpace.is_animated, - "is_video": StickerSpace.is_video, + "file_id": self.sticker_file_id, + "file_unique_id": self.sticker_file_unique_id, + "width": self.width, + "height": self.height, + "is_animated": self.is_animated, + "is_video": self.is_video, "thumb": sticker.thumb.to_dict(), - "emoji": StickerSpace.emoji, - "file_size": StickerSpace.file_size, - "premium_animation": StickerSpace.premium_animation.to_dict(), - "type": StickerSpace.type, - "custom_emoji_id": StickerSpace.custom_emoji_id, + "emoji": self.emoji, + "file_size": self.file_size, + "premium_animation": self.premium_animation.to_dict(), + "type": self.type, + "custom_emoji_id": self.custom_emoji_id, } json_sticker = Sticker.de_json(json_dict, bot) assert json_sticker.api_kwargs == {} - assert json_sticker.file_id == StickerSpace.sticker_file_id - assert json_sticker.file_unique_id == StickerSpace.sticker_file_unique_id - assert json_sticker.width == StickerSpace.width - assert json_sticker.height == StickerSpace.height - assert json_sticker.is_animated == StickerSpace.is_animated - assert json_sticker.is_video == StickerSpace.is_video - assert json_sticker.emoji == StickerSpace.emoji - assert json_sticker.file_size == StickerSpace.file_size + assert json_sticker.file_id == self.sticker_file_id + assert json_sticker.file_unique_id == self.sticker_file_unique_id + assert json_sticker.width == self.width + assert json_sticker.height == self.height + assert json_sticker.is_animated == self.is_animated + assert json_sticker.is_video == self.is_video + assert json_sticker.emoji == self.emoji + assert json_sticker.file_size == self.file_size assert json_sticker.thumb == sticker.thumb - assert json_sticker.premium_animation == StickerSpace.premium_animation - assert json_sticker.type == StickerSpace.type - assert json_sticker.custom_emoji_id == StickerSpace.custom_emoji_id + assert json_sticker.premium_animation == self.premium_animation + assert json_sticker.type == self.type + assert json_sticker.custom_emoji_id == self.custom_emoji_id def test_equality(self, sticker): a = Sticker( sticker.file_id, sticker.file_unique_id, - StickerSpace.width, - StickerSpace.height, - StickerSpace.is_animated, - StickerSpace.is_video, - StickerSpace.type, + self.width, + self.height, + self.is_animated, + self.is_video, + self.type, ) b = Sticker( "", sticker.file_unique_id, - StickerSpace.width, - StickerSpace.height, - StickerSpace.is_animated, - StickerSpace.is_video, - StickerSpace.type, + self.width, + self.height, + self.is_animated, + self.is_video, + self.type, ) c = Sticker( sticker.file_id, @@ -198,23 +198,23 @@ def test_equality(self, sticker): 0, False, True, - StickerSpace.type, + self.type, ) d = Sticker( "", "", - StickerSpace.width, - StickerSpace.height, - StickerSpace.is_animated, - StickerSpace.is_video, - StickerSpace.type, + self.width, + self.height, + self.is_animated, + self.is_video, + self.type, ) e = PhotoSize( sticker.file_id, sticker.file_unique_id, - StickerSpace.width, - StickerSpace.height, - StickerSpace.is_animated, + self.width, + self.height, + self.is_animated, ) assert a == b @@ -264,7 +264,7 @@ async def make_assertion(_, data, *args, **kwargs): bot._local_mode = False -class TestStickerWithRequest: +class TestStickerWithRequest(TestStickerBase): async def test_send_all_args(self, bot, chat_id, sticker_file, sticker): message = await bot.send_sticker( chat_id, sticker=sticker_file, disable_notification=False, protect_content=True @@ -320,10 +320,10 @@ async def test_send_on_server_emoji(self, bot, chat_id): server_file_id = "CAADAQADHAADyIsGAAFZfq1bphjqlgI" message = await bot.send_sticker(chat_id=chat_id, sticker=server_file_id) sticker = message.sticker - assert sticker.emoji == StickerSpace.emoji + assert sticker.emoji == self.emoji async def test_send_from_url(self, bot, chat_id): - message = await bot.send_sticker(chat_id=chat_id, sticker=StickerSpace.sticker_file_url) + message = await bot.send_sticker(chat_id=chat_id, sticker=self.sticker_file_url) sticker = message.sticker assert isinstance(message.sticker, Sticker) @@ -491,7 +491,7 @@ def sticker_set_thumb_file(): yield file -class SetSpace: +class TestStickerSetBase: title = "Test stickers" is_animated = True is_video = True @@ -501,9 +501,9 @@ class SetSpace: contains_masks = True -class TestStickerSetWithoutRequest: +class TestStickerSetWithoutRequest(TestStickerSetBase): def test_slot_behaviour(self, mro_slots): - inst = StickerSet("this", "is", True, SetSpace.stickers, True, "not") + inst = StickerSet("this", "is", True, self.stickers, True, "not") for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" @@ -512,24 +512,24 @@ def test_de_json(self, bot, sticker): name = f"test_by_{bot.username}" json_dict = { "name": name, - "title": SetSpace.title, - "is_animated": SetSpace.is_animated, - "is_video": SetSpace.is_video, - "stickers": [x.to_dict() for x in SetSpace.stickers], + "title": self.title, + "is_animated": self.is_animated, + "is_video": self.is_video, + "stickers": [x.to_dict() for x in self.stickers], "thumb": sticker.thumb.to_dict(), - "sticker_type": SetSpace.sticker_type, - "contains_masks": SetSpace.contains_masks, + "sticker_type": self.sticker_type, + "contains_masks": self.contains_masks, } sticker_set = StickerSet.de_json(json_dict, bot) assert sticker_set.name == name - assert sticker_set.title == SetSpace.title - assert sticker_set.is_animated == SetSpace.is_animated - assert sticker_set.is_video == SetSpace.is_video - assert sticker_set.stickers == tuple(SetSpace.stickers) + assert sticker_set.title == self.title + assert sticker_set.is_animated == self.is_animated + assert sticker_set.is_video == self.is_video + assert sticker_set.stickers == tuple(self.stickers) assert sticker_set.thumb == sticker.thumb - assert sticker_set.sticker_type == SetSpace.sticker_type - assert sticker_set.api_kwargs == {"contains_masks": SetSpace.contains_masks} + assert sticker_set.sticker_type == self.sticker_type + assert sticker_set.api_kwargs == {"contains_masks": self.contains_masks} def test_sticker_set_to_dict(self, sticker_set): sticker_set_dict = sticker_set.to_dict() @@ -545,31 +545,31 @@ def test_sticker_set_to_dict(self, sticker_set): def test_equality(self): a = StickerSet( - SetSpace.name, - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, + self.name, + self.title, + self.is_animated, + self.stickers, + self.is_video, + self.sticker_type, ) b = StickerSet( - SetSpace.name, - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, + self.name, + self.title, + self.is_animated, + self.stickers, + self.is_video, + self.sticker_type, ) - c = StickerSet(SetSpace.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) + c = StickerSet(self.name, "title", False, [], True, Sticker.CUSTOM_EMOJI) d = StickerSet( "blah", - SetSpace.title, - SetSpace.is_animated, - SetSpace.stickers, - SetSpace.is_video, - SetSpace.sticker_type, + self.title, + self.is_animated, + self.stickers, + self.is_video, + self.sticker_type, ) - e = Audio(SetSpace.name, "", 0, None, None) + e = Audio(self.name, "", 0, None, None) assert a == b assert hash(a) == hash(b) @@ -872,17 +872,22 @@ async def test_bot_methods_4_webm(self, bot, video_sticker_set): @pytest.fixture(scope="module") def mask_position(): - return MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) + return MaskPosition( + TestMaskPositionBase.point, + TestMaskPositionBase.x_shift, + TestMaskPositionBase.y_shift, + TestMaskPositionBase.scale, + ) -class MaskSpace: +class TestMaskPositionBase: point = MaskPosition.EYES x_shift = -1 y_shift = 1 scale = 2 -class TestMaskPositionWithoutRequest: +class TestMaskPositionWithoutRequest(TestMaskPositionBase): def test_slot_behaviour(self, mask_position, mro_slots): inst = mask_position for attr in inst.__slots__: @@ -891,18 +896,18 @@ def test_slot_behaviour(self, mask_position, mro_slots): def test_mask_position_de_json(self, bot): json_dict = { - "point": MaskSpace.point, - "x_shift": MaskSpace.x_shift, - "y_shift": MaskSpace.y_shift, - "scale": MaskSpace.scale, + "point": self.point, + "x_shift": self.x_shift, + "y_shift": self.y_shift, + "scale": self.scale, } mask_position = MaskPosition.de_json(json_dict, bot) assert mask_position.api_kwargs == {} - assert mask_position.point == MaskSpace.point - assert mask_position.x_shift == MaskSpace.x_shift - assert mask_position.y_shift == MaskSpace.y_shift - assert mask_position.scale == MaskSpace.scale + 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 def test_mask_position_to_dict(self, mask_position): mask_position_dict = mask_position.to_dict() @@ -914,12 +919,10 @@ def test_mask_position_to_dict(self, mask_position): assert mask_position_dict["scale"] == mask_position.scale def test_equality(self): - a = MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) - b = MaskPosition(MaskSpace.point, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale) - c = MaskPosition( - MaskPosition.FOREHEAD, MaskSpace.x_shift, MaskSpace.y_shift, MaskSpace.scale - ) - d = MaskPosition(MaskSpace.point, 0, 0, MaskSpace.scale) + a = MaskPosition(self.point, self.x_shift, self.y_shift, self.scale) + b = MaskPosition(self.point, self.x_shift, self.y_shift, self.scale) + c = MaskPosition(MaskPosition.FOREHEAD, self.x_shift, self.y_shift, self.scale) + d = MaskPosition(self.point, 0, 0, self.scale) e = Audio("", "", 0, None, None) assert a == b diff --git a/tests/test_successfulpayment.py b/tests/test_successfulpayment.py index 64dc53600e5..80dce68fa0a 100644 --- a/tests/test_successfulpayment.py +++ b/tests/test_successfulpayment.py @@ -24,17 +24,17 @@ @pytest.fixture(scope="module") def successful_payment(): return SuccessfulPayment( - Space.currency, - Space.total_amount, - Space.invoice_payload, - Space.telegram_payment_charge_id, - Space.provider_payment_charge_id, - shipping_option_id=Space.shipping_option_id, - order_info=Space.order_info, + TestSuccessfulPaymentBase.currency, + TestSuccessfulPaymentBase.total_amount, + TestSuccessfulPaymentBase.invoice_payload, + TestSuccessfulPaymentBase.telegram_payment_charge_id, + TestSuccessfulPaymentBase.provider_payment_charge_id, + shipping_option_id=TestSuccessfulPaymentBase.shipping_option_id, + order_info=TestSuccessfulPaymentBase.order_info, ) -class Space: +class TestSuccessfulPaymentBase: invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" currency = "EUR" @@ -44,7 +44,7 @@ class Space: provider_payment_charge_id = "provider_payment_charge_id" -class TestSuccessfulPaymentWithoutRequest: +class TestSuccessfulPaymentWithoutRequest(TestSuccessfulPaymentBase): def test_slot_behaviour(self, successful_payment, mro_slots): inst = successful_payment for attr in inst.__slots__: @@ -53,23 +53,23 @@ def test_slot_behaviour(self, successful_payment, mro_slots): def test_de_json(self, bot): json_dict = { - "invoice_payload": Space.invoice_payload, - "shipping_option_id": Space.shipping_option_id, - "currency": Space.currency, - "total_amount": Space.total_amount, - "order_info": Space.order_info.to_dict(), - "telegram_payment_charge_id": Space.telegram_payment_charge_id, - "provider_payment_charge_id": Space.provider_payment_charge_id, + "invoice_payload": self.invoice_payload, + "shipping_option_id": self.shipping_option_id, + "currency": self.currency, + "total_amount": self.total_amount, + "order_info": self.order_info.to_dict(), + "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) assert successful_payment.api_kwargs == {} - assert successful_payment.invoice_payload == Space.invoice_payload - assert successful_payment.shipping_option_id == Space.shipping_option_id - assert successful_payment.currency == Space.currency - assert successful_payment.order_info == Space.order_info - assert successful_payment.telegram_payment_charge_id == Space.telegram_payment_charge_id - assert successful_payment.provider_payment_charge_id == Space.provider_payment_charge_id + 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 def test_to_dict(self, successful_payment): successful_payment_dict = successful_payment.to_dict() @@ -92,27 +92,27 @@ def test_to_dict(self, successful_payment): def test_equality(self): a = SuccessfulPayment( - Space.currency, - Space.total_amount, - Space.invoice_payload, - Space.telegram_payment_charge_id, - Space.provider_payment_charge_id, + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id, ) b = SuccessfulPayment( - Space.currency, - Space.total_amount, - Space.invoice_payload, - Space.telegram_payment_charge_id, - Space.provider_payment_charge_id, + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, + self.provider_payment_charge_id, ) c = SuccessfulPayment( - "", 0, "", Space.telegram_payment_charge_id, Space.provider_payment_charge_id + "", 0, "", self.telegram_payment_charge_id, self.provider_payment_charge_id ) d = SuccessfulPayment( - Space.currency, - Space.total_amount, - Space.invoice_payload, - Space.telegram_payment_charge_id, + self.currency, + self.total_amount, + self.invoice_payload, + self.telegram_payment_charge_id, "", ) diff --git a/tests/test_update.py b/tests/test_update.py index 24a3b257dcf..bbda3d6fb98 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -98,29 +98,29 @@ @pytest.fixture(scope="module", params=params, ids=ids) def update(request): - return Update(update_id=Space.update_id, **request.param) + return Update(update_id=TestUpdateBase.update_id, **request.param) -class Space: +class TestUpdateBase: update_id = 868573637 -class TestUpdateWithoutRequest: +class TestUpdateWithoutRequest(TestUpdateBase): def test_slot_behaviour(self, mro_slots): - update = Update(Space.update_id) + update = Update(self.update_id) for attr in update.__slots__: assert getattr(update, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(update)) == len(set(mro_slots(update))), "duplicate slot" @pytest.mark.parametrize("paramdict", argvalues=params, ids=ids) def test_de_json(self, bot, paramdict): - json_dict = {"update_id": Space.update_id} + json_dict = {"update_id": self.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) assert update.api_kwargs == {} - assert update.update_id == Space.update_id + assert update.update_id == self.update_id # Make sure only one thing in the update (other than update_id) is not None i = 0 @@ -145,11 +145,11 @@ def test_to_dict(self, update): assert update_dict[_type] == getattr(update, _type).to_dict() def test_equality(self): - a = Update(Space.update_id, message=message) - b = Update(Space.update_id, message=message) - c = Update(Space.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(Space.update_id, "", False) + e = User(self.update_id, "", False) assert a == b assert hash(a) == hash(b) diff --git a/tests/test_user.py b/tests/test_user.py index 5b9831c3afc..6ea946b9d39 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -30,41 +30,41 @@ @pytest.fixture(scope="module") def json_dict(): return { - "id": Space.id_, - "is_bot": Space.is_bot, - "first_name": Space.first_name, - "last_name": Space.last_name, - "username": Space.username, - "language_code": Space.language_code, - "can_join_groups": Space.can_join_groups, - "can_read_all_group_messages": Space.can_read_all_group_messages, - "supports_inline_queries": Space.supports_inline_queries, - "is_premium": Space.is_premium, - "added_to_attachment_menu": Space.added_to_attachment_menu, + "id": TestUserBase.id_, + "is_bot": TestUserBase.is_bot, + "first_name": TestUserBase.first_name, + "last_name": TestUserBase.last_name, + "username": TestUserBase.username, + "language_code": TestUserBase.language_code, + "can_join_groups": TestUserBase.can_join_groups, + "can_read_all_group_messages": TestUserBase.can_read_all_group_messages, + "supports_inline_queries": TestUserBase.supports_inline_queries, + "is_premium": TestUserBase.is_premium, + "added_to_attachment_menu": TestUserBase.added_to_attachment_menu, } @pytest.fixture(scope="function") def user(bot): user = User( - id=Space.id_, - first_name=Space.first_name, - is_bot=Space.is_bot, - last_name=Space.last_name, - username=Space.username, - language_code=Space.language_code, - can_join_groups=Space.can_join_groups, - can_read_all_group_messages=Space.can_read_all_group_messages, - supports_inline_queries=Space.supports_inline_queries, - is_premium=Space.is_premium, - added_to_attachment_menu=Space.added_to_attachment_menu, + id=TestUserBase.id_, + first_name=TestUserBase.first_name, + is_bot=TestUserBase.is_bot, + last_name=TestUserBase.last_name, + username=TestUserBase.username, + language_code=TestUserBase.language_code, + can_join_groups=TestUserBase.can_join_groups, + can_read_all_group_messages=TestUserBase.can_read_all_group_messages, + supports_inline_queries=TestUserBase.supports_inline_queries, + is_premium=TestUserBase.is_premium, + added_to_attachment_menu=TestUserBase.added_to_attachment_menu, ) user.set_bot(bot) user._unfreeze() return user -class Space: +class TestUserBase: id_ = 1 is_bot = True first_name = "first\u2022name" @@ -78,7 +78,7 @@ class Space: added_to_attachment_menu = False -class TestUserWithoutRequest: +class TestUserWithoutRequest(TestUserBase): def test_slot_behaviour(self, user, mro_slots): for attr in user.__slots__: assert getattr(user, attr, "err") != "err", f"got extra slot '{attr}'" @@ -88,17 +88,17 @@ def test_de_json(self, json_dict, bot): user = User.de_json(json_dict, bot) assert user.api_kwargs == {} - assert user.id == Space.id_ - assert user.is_bot == Space.is_bot - assert user.first_name == Space.first_name - assert user.last_name == Space.last_name - assert user.username == Space.username - assert user.language_code == Space.language_code - assert user.can_join_groups == Space.can_join_groups - assert user.can_read_all_group_messages == Space.can_read_all_group_messages - assert user.supports_inline_queries == Space.supports_inline_queries - assert user.is_premium == Space.is_premium - assert user.added_to_attachment_menu == Space.added_to_attachment_menu + assert user.id == self.id_ + assert user.is_bot == self.is_bot + 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 + assert user.can_join_groups == self.can_join_groups + assert user.can_read_all_group_messages == self.can_read_all_group_messages + assert user.supports_inline_queries == self.supports_inline_queries + assert user.is_premium == self.is_premium + assert user.added_to_attachment_menu == self.added_to_attachment_menu def test_to_dict(self, user): user_dict = user.to_dict() @@ -117,11 +117,11 @@ def test_to_dict(self, user): assert user_dict["added_to_attachment_menu"] == user.added_to_attachment_menu def test_equality(self): - a = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) - b = User(Space.id_, Space.first_name, Space.is_bot, Space.last_name) - c = User(Space.id_, Space.first_name, Space.is_bot) - d = User(0, Space.first_name, Space.is_bot, Space.last_name) - e = Update(Space.id_) + a = User(self.id_, self.first_name, self.is_bot, self.last_name) + b = User(self.id_, self.first_name, self.is_bot, self.last_name) + c = User(self.id_, self.first_name, self.is_bot) + d = User(0, self.first_name, self.is_bot, self.last_name) + e = Update(self.id_) assert a == b assert hash(a) == hash(b) @@ -142,7 +142,7 @@ def test_name(self, user): assert user.name == "first\u2022name last\u2022name" user.last_name = None assert user.name == "first\u2022name" - user.username = Space.username + user.username = self.username assert user.name == "@username" def test_full_name(self, user): diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index 7eea9912da7..da179e53e0d 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -19,7 +19,7 @@ from telegram import PhotoSize, UserProfilePhotos -class Space: +class TestUserProfilePhotosBase: total_count = 2 photos = [ [ @@ -33,22 +33,22 @@ class Space: ] -class TestUserProfilePhotosWithoutRequest: +class TestUserProfilePhotosWithoutRequest(TestUserProfilePhotosBase): def test_slot_behaviour(self, mro_slots): - inst = UserProfilePhotos(Space.total_count, Space.photos) + inst = UserProfilePhotos(self.total_count, self.photos) for attr in inst.__slots__: assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" def test_de_json(self, bot): - json_dict = {"total_count": 2, "photos": [[y.to_dict() for y in x] for x in Space.photos]} + json_dict = {"total_count": 2, "photos": [[y.to_dict() for y in x] for x in self.photos]} user_profile_photos = UserProfilePhotos.de_json(json_dict, bot) assert user_profile_photos.api_kwargs == {} - assert user_profile_photos.total_count == Space.total_count - assert user_profile_photos.photos == tuple(tuple(p) for p in Space.photos) + assert user_profile_photos.total_count == self.total_count + assert user_profile_photos.photos == tuple(tuple(p) for p in self.photos) def test_to_dict(self): - user_profile_photos = UserProfilePhotos(Space.total_count, Space.photos) + user_profile_photos = UserProfilePhotos(self.total_count, self.photos) user_profile_photos_dict = user_profile_photos.to_dict() assert user_profile_photos_dict["total_count"] == user_profile_photos.total_count for ix, x in enumerate(user_profile_photos_dict["photos"]): @@ -56,9 +56,9 @@ def test_to_dict(self): assert y == user_profile_photos.photos[ix][iy].to_dict() def test_equality(self): - a = UserProfilePhotos(2, Space.photos) - b = UserProfilePhotos(2, Space.photos) - c = UserProfilePhotos(1, [Space.photos[0]]) + a = UserProfilePhotos(2, self.photos) + b = UserProfilePhotos(2, self.photos) + c = UserProfilePhotos(1, [self.photos[0]]) d = PhotoSize("file_id1", "unique_id", 512, 512) assert a == b diff --git a/tests/test_venue.py b/tests/test_venue.py index 55c9e7138ef..55944c7b0d8 100644 --- a/tests/test_venue.py +++ b/tests/test_venue.py @@ -28,17 +28,17 @@ @pytest.fixture(scope="module") def venue(): return Venue( - Space.location, - Space.title, - Space.address, - foursquare_id=Space.foursquare_id, - foursquare_type=Space.foursquare_type, - google_place_id=Space.google_place_id, - google_place_type=Space.google_place_type, + TestVenueBase.location, + TestVenueBase.title, + TestVenueBase.address, + foursquare_id=TestVenueBase.foursquare_id, + foursquare_type=TestVenueBase.foursquare_type, + google_place_id=TestVenueBase.google_place_id, + google_place_type=TestVenueBase.google_place_type, ) -class Space: +class TestVenueBase: location = Location(longitude=-46.788279, latitude=-23.691288) title = "title" address = "address" @@ -48,7 +48,7 @@ class Space: google_place_type = "google place type" -class TestVenueWithoutRequest: +class TestVenueWithoutRequest(TestVenueBase): def test_slot_behaviour(self, venue, mro_slots): for attr in venue.__slots__: assert getattr(venue, attr, "err") != "err", f"got extra slot '{attr}'" @@ -56,24 +56,24 @@ def test_slot_behaviour(self, venue, mro_slots): def test_de_json(self, bot): json_dict = { - "location": Space.location.to_dict(), - "title": Space.title, - "address": Space.address, - "foursquare_id": Space.foursquare_id, - "foursquare_type": Space.foursquare_type, - "google_place_id": Space.google_place_id, - "google_place_type": Space.google_place_type, + "location": self.location.to_dict(), + "title": self.title, + "address": self.address, + "foursquare_id": self.foursquare_id, + "foursquare_type": self.foursquare_type, + "google_place_id": self.google_place_id, + "google_place_type": self.google_place_type, } venue = Venue.de_json(json_dict, bot) assert venue.api_kwargs == {} - assert venue.location == Space.location - assert venue.title == Space.title - assert venue.address == Space.address - assert venue.foursquare_id == Space.foursquare_id - assert venue.foursquare_type == Space.foursquare_type - assert venue.google_place_id == Space.google_place_id - assert venue.google_place_type == Space.google_place_type + assert venue.location == self.location + assert venue.title == self.title + assert venue.address == self.address + assert venue.foursquare_id == self.foursquare_id + assert venue.foursquare_type == self.foursquare_type + assert venue.google_place_id == self.google_place_id + assert venue.google_place_type == self.google_place_type def test_to_dict(self, venue): venue_dict = venue.to_dict() @@ -88,11 +88,11 @@ def test_to_dict(self, venue): assert venue_dict["google_place_type"] == venue.google_place_type def test_equality(self): - a = Venue(Location(0, 0), Space.title, Space.address) - b = Venue(Location(0, 0), Space.title, Space.address) - c = Venue(Location(0, 0), Space.title, "") - d = Venue(Location(0, 1), Space.title, Space.address) - d2 = Venue(Location(0, 0), "", Space.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) assert a == b assert hash(a) == hash(b) @@ -126,14 +126,14 @@ async def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters return ( - data["longitude"] == str(Space.location.longitude) - and data["latitude"] == str(Space.location.latitude) - and data["title"] == Space.title - and data["address"] == Space.address - and data["foursquare_id"] == Space.foursquare_id - and data["foursquare_type"] == Space.foursquare_type - and data["google_place_id"] == Space.google_place_id - and data["google_place_type"] == Space.google_place_type + data["longitude"] == str(self.location.longitude) + and data["latitude"] == str(self.location.latitude) + and data["title"] == self.title + and data["address"] == self.address + and data["foursquare_id"] == self.foursquare_id + and data["foursquare_type"] == self.foursquare_type + and data["google_place_id"] == self.google_place_id + and data["google_place_type"] == self.google_place_type ) monkeypatch.setattr(bot.request, "post", make_assertion) @@ -141,7 +141,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert message -class TestVenueWithRequest: +class TestVenueWithRequest(TestVenueBase): @pytest.mark.parametrize( "default_bot,custom", [ diff --git a/tests/test_video.py b/tests/test_video.py index 55ae4780594..dd97ccd71b1 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -46,7 +46,7 @@ async def video(bot, chat_id): return (await bot.send_video(chat_id, video=f, read_timeout=50)).video -class Space: +class TestVideoBase: width = 360 height = 640 duration = 5 @@ -63,7 +63,7 @@ class Space: video_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoWithoutRequest: +class TestVideoWithoutRequest(TestVideoBase): def test_slot_behaviour(self, video, mro_slots): for attr in video.__slots__: assert getattr(video, attr, "err") != "err", f"got extra slot '{attr}'" @@ -84,34 +84,34 @@ def test_creation(self, video): assert video.thumb.file_unique_id != "" def test_expected_values(self, video): - assert video.width == Space.width - assert video.height == Space.height - assert video.duration == Space.duration - assert video.file_size == Space.file_size - assert video.mime_type == Space.mime_type + 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 def test_de_json(self, bot): json_dict = { - "file_id": Space.video_file_id, - "file_unique_id": Space.video_file_unique_id, - "width": Space.width, - "height": Space.height, - "duration": Space.duration, - "mime_type": Space.mime_type, - "file_size": Space.file_size, - "file_name": Space.file_name, + "file_id": self.video_file_id, + "file_unique_id": self.video_file_unique_id, + "width": self.width, + "height": self.height, + "duration": self.duration, + "mime_type": self.mime_type, + "file_size": self.file_size, + "file_name": self.file_name, } json_video = Video.de_json(json_dict, bot) assert json_video.api_kwargs == {} - assert json_video.file_id == Space.video_file_id - assert json_video.file_unique_id == Space.video_file_unique_id - assert json_video.width == Space.width - assert json_video.height == Space.height - assert json_video.duration == Space.duration - assert json_video.mime_type == Space.mime_type - assert json_video.file_size == Space.file_size - assert json_video.file_name == Space.file_name + assert json_video.file_id == self.video_file_id + assert json_video.file_unique_id == self.video_file_unique_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 + assert json_video.file_name == self.file_name def test_to_dict(self, video): video_dict = video.to_dict() @@ -127,11 +127,11 @@ def test_to_dict(self, video): assert video_dict["file_name"] == video.file_name def test_equality(self, video): - a = Video(video.file_id, video.file_unique_id, Space.width, Space.height, Space.duration) - b = Video("", video.file_unique_id, Space.width, Space.height, Space.duration) + a = Video(video.file_id, video.file_unique_id, self.width, self.height, self.duration) + b = Video("", video.file_unique_id, self.width, self.height, self.duration) c = Video(video.file_id, video.file_unique_id, 0, 0, 0) - d = Video("", "", Space.width, Space.height, Space.duration) - e = Voice(video.file_id, video.file_unique_id, Space.duration) + d = Video("", "", self.width, self.height, self.duration) + e = Voice(video.file_id, video.file_unique_id, self.duration) assert a == b assert hash(a) == hash(b) @@ -201,14 +201,14 @@ async def make_assertion(*_, **kwargs): assert await video.get_file() -class TestVideoWithRequest: +class TestVideoWithRequest(TestVideoBase): async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): message = await bot.send_video( chat_id, video_file, - duration=Space.duration, - caption=Space.caption, - supports_streaming=Space.supports_streaming, + duration=self.duration, + caption=self.caption, + supports_streaming=self.supports_streaming, disable_notification=False, protect_content=True, width=video.width, @@ -228,13 +228,13 @@ async def test_send_all_args(self, bot, chat_id, video_file, video, thumb_file): assert message.video.duration == video.duration assert message.video.file_size == video.file_size - assert message.caption == Space.caption.replace("*", "") + assert message.caption == self.caption.replace("*", "") - assert message.video.thumb.file_size == Space.thumb_file_size - assert message.video.thumb.width == Space.thumb_width - assert message.video.thumb.height == Space.thumb_height + assert message.video.thumb.file_size == self.thumb_file_size + assert message.video.thumb.width == self.thumb_width + assert message.video.thumb.height == self.thumb_height - assert message.video.file_name == Space.file_name + assert message.video.file_name == self.file_name assert message.has_protected_content assert message.has_media_spoiler @@ -246,7 +246,7 @@ async def test_get_and_download(self, bot, video, chat_id): video = (await bot.send_video(chat_id, video.file_id, read_timeout=50)).video new_file = await bot.get_file(video.file_id) - assert new_file.file_size == Space.file_size + assert new_file.file_size == self.file_size assert new_file.file_id == video.file_id assert new_file.file_unique_id == video.file_unique_id assert new_file.file_path.startswith("https://") @@ -256,7 +256,7 @@ async def test_get_and_download(self, bot, video, chat_id): assert path.is_file() async def test_send_mp4_file_url(self, bot, chat_id, video): - message = await bot.send_video(chat_id, Space.video_file_url, caption=Space.caption) + message = await bot.send_video(chat_id, self.video_file_url, caption=self.caption) assert isinstance(message.video, Video) assert isinstance(message.video.file_id, str) @@ -273,11 +273,11 @@ async def test_send_mp4_file_url(self, bot, chat_id, video): assert isinstance(message.video.thumb.file_unique_id, str) assert message.video.thumb.file_id != "" assert message.video.thumb.file_unique_id != "" - assert message.video.thumb.width == 51 # This seems odd that it's not Space.thumb_width + assert message.video.thumb.width == 51 # This seems odd that it's not self.thumb_width assert message.video.thumb.height == 90 # Ditto assert message.video.thumb.file_size == 645 # same - assert message.caption == Space.caption + assert message.caption == self.caption async def test_send_video_caption_entities(self, bot, chat_id, video): test_string = "Italic Bold Code" diff --git a/tests/test_videonote.py b/tests/test_videonote.py index 16835a8727a..ff4c0acc306 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -45,7 +45,7 @@ async def video_note(bot, chat_id): return (await bot.send_video_note(chat_id, video_note=f, read_timeout=50)).video_note -class Space: +class TestVideoNoteBase: length = 240 duration = 3 file_size = 132084 @@ -57,7 +57,7 @@ class Space: videonote_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoNoteWithoutRequest: +class TestVideoNoteWithoutRequest(TestVideoNoteBase): def test_slot_behaviour(self, video_note, mro_slots): for attr in video_note.__slots__: assert getattr(video_note, attr, "err") != "err", f"got extra slot '{attr}'" @@ -78,26 +78,26 @@ def test_creation(self, video_note): assert video_note.thumb.file_unique_id != "" def test_expected_values(self, video_note): - assert video_note.length == Space.length - assert video_note.duration == Space.duration - assert video_note.file_size == Space.file_size + assert video_note.length == self.length + assert video_note.duration == self.duration + assert video_note.file_size == self.file_size def test_de_json(self, bot): json_dict = { - "file_id": Space.videonote_file_id, - "file_unique_id": Space.videonote_file_unique_id, - "length": Space.length, - "duration": Space.duration, - "file_size": Space.file_size, + "file_id": self.videonote_file_id, + "file_unique_id": self.videonote_file_unique_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.api_kwargs == {} - assert json_video_note.file_id == Space.videonote_file_id - assert json_video_note.file_unique_id == Space.videonote_file_unique_id - assert json_video_note.length == Space.length - assert json_video_note.duration == Space.duration - assert json_video_note.file_size == Space.file_size + assert json_video_note.file_id == self.videonote_file_id + assert json_video_note.file_unique_id == self.videonote_file_unique_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() @@ -110,11 +110,11 @@ def test_to_dict(self, video_note): assert video_note_dict["file_size"] == video_note.file_size def test_equality(self, video_note): - a = VideoNote(video_note.file_id, video_note.file_unique_id, Space.length, Space.duration) - b = VideoNote("", video_note.file_unique_id, Space.length, Space.duration) + a = VideoNote(video_note.file_id, video_note.file_unique_id, self.length, self.duration) + b = VideoNote("", video_note.file_unique_id, self.length, self.duration) c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0) - d = VideoNote("", "", Space.length, Space.duration) - e = Voice(video_note.file_id, video_note.file_unique_id, Space.duration) + d = VideoNote("", "", self.length, self.duration) + e = Voice(video_note.file_id, video_note.file_unique_id, self.duration) assert a == b assert hash(a) == hash(b) @@ -188,13 +188,13 @@ async def make_assertion(*_, **kwargs): assert await video_note.get_file() -class TestVideoNoteWithRequest: +class TestVideoNoteWithRequest(TestVideoNoteBase): async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, thumb_file): message = await bot.send_video_note( chat_id, video_note_file, - duration=Space.duration, - length=Space.length, + duration=self.duration, + length=self.length, disable_notification=False, protect_content=True, thumb=thumb_file, @@ -209,9 +209,9 @@ async def test_send_all_args(self, bot, chat_id, video_note_file, video_note, th assert message.video_note.duration == video_note.duration assert message.video_note.file_size == video_note.file_size - assert message.video_note.thumb.file_size == Space.thumb_file_size - assert message.video_note.thumb.width == Space.thumb_width - assert message.video_note.thumb.height == Space.thumb_height + assert message.video_note.thumb.file_size == self.thumb_file_size + assert message.video_note.thumb.width == self.thumb_width + assert message.video_note.thumb.height == self.thumb_height assert message.has_protected_content async def test_get_and_download(self, bot, video_note, chat_id): @@ -222,7 +222,7 @@ async def test_get_and_download(self, bot, video_note, chat_id): video_note = (await bot.send_video_note(chat_id, video_note, read_timeout=50)).video_note new_file = await bot.get_file(video_note.file_id) - assert new_file.file_size == Space.file_size + assert new_file.file_size == self.file_size assert new_file.file_id == video_note.file_id assert new_file.file_unique_id == video_note.file_unique_id assert new_file.file_path.startswith("https://") diff --git a/tests/test_voice.py b/tests/test_voice.py index 934b2d7cc54..1177840caf7 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -46,7 +46,7 @@ async def voice(bot, chat_id): return (await bot.send_voice(chat_id, voice=f, read_timeout=50)).voice -class Space: +class TestVoiceBase: duration = 3 mime_type = "audio/ogg" file_size = 9199 @@ -56,7 +56,7 @@ class Space: voice_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVoiceWithoutRequest: +class TestVoiceWithoutRequest(TestVoiceBase): def test_slot_behaviour(self, voice, mro_slots): for attr in voice.__slots__: assert getattr(voice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -71,26 +71,26 @@ async def test_creation(self, voice): assert voice.file_unique_id != "" def test_expected_values(self, voice): - assert voice.duration == Space.duration - assert voice.mime_type == Space.mime_type - assert voice.file_size == Space.file_size + assert voice.duration == self.duration + assert voice.mime_type == self.mime_type + assert voice.file_size == self.file_size def test_de_json(self, bot): json_dict = { - "file_id": Space.voice_file_id, - "file_unique_id": Space.voice_file_unique_id, - "duration": Space.duration, - "mime_type": Space.mime_type, - "file_size": Space.file_size, + "file_id": self.voice_file_id, + "file_unique_id": self.voice_file_unique_id, + "duration": self.duration, + "mime_type": self.mime_type, + "file_size": self.file_size, } json_voice = Voice.de_json(json_dict, bot) assert json_voice.api_kwargs == {} - assert json_voice.file_id == Space.voice_file_id - assert json_voice.file_unique_id == Space.voice_file_unique_id - assert json_voice.duration == Space.duration - assert json_voice.mime_type == Space.mime_type - assert json_voice.file_size == Space.file_size + assert json_voice.file_id == self.voice_file_id + assert json_voice.file_unique_id == self.voice_file_unique_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() @@ -103,11 +103,11 @@ def test_to_dict(self, voice): assert voice_dict["file_size"] == voice.file_size def test_equality(self, voice): - a = Voice(voice.file_id, voice.file_unique_id, Space.duration) - b = Voice("", voice.file_unique_id, Space.duration) + a = Voice(voice.file_id, voice.file_unique_id, self.duration) + b = Voice("", voice.file_unique_id, self.duration) c = Voice(voice.file_id, voice.file_unique_id, 0) - d = Voice("", "", Space.duration) - e = Audio(voice.file_id, voice.file_unique_id, Space.duration) + d = Voice("", "", self.duration) + e = Audio(voice.file_id, voice.file_unique_id, self.duration) assert a == b assert hash(a) == hash(b) @@ -175,13 +175,13 @@ async def make_assertion(*_, **kwargs): assert await voice.get_file() -class TestVoiceWithRequest: +class TestVoiceWithRequest(TestVoiceBase): async def test_send_all_args(self, bot, chat_id, voice_file, voice): message = await bot.send_voice( chat_id, voice_file, - duration=Space.duration, - caption=Space.caption, + duration=self.duration, + caption=self.caption, disable_notification=False, protect_content=True, parse_mode="Markdown", @@ -195,7 +195,7 @@ async def test_send_all_args(self, bot, chat_id, voice_file, voice): 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 == Space.caption.replace("*", "") + assert message.caption == self.caption.replace("*", "") assert message.has_protected_content async def test_get_and_download(self, bot, voice, chat_id): @@ -216,7 +216,7 @@ async def test_get_and_download(self, bot, voice, chat_id): assert path.is_file() async def test_send_ogg_url_file(self, bot, chat_id, voice): - message = await bot.sendVoice(chat_id, Space.voice_file_url, duration=Space.duration) + message = await bot.sendVoice(chat_id, self.voice_file_url, duration=self.duration) assert isinstance(message.voice, Voice) assert isinstance(message.voice.file_id, str) diff --git a/tests/test_webappdata.py b/tests/test_webappdata.py index d822723e717..c64f3894dc9 100644 --- a/tests/test_webappdata.py +++ b/tests/test_webappdata.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def web_app_data(): - return WebAppData(data=Space.data, button_text=Space.button_text) + return WebAppData(data=TestWebAppDataBase.data, button_text=TestWebAppDataBase.button_text) -class Space: +class TestWebAppDataBase: data = "data" button_text = "button_text" -class TestWebAppDataWithoutRequest: +class TestWebAppDataWithoutRequest(TestWebAppDataBase): def test_slot_behaviour(self, web_app_data, mro_slots): for attr in web_app_data.__slots__: assert getattr(web_app_data, attr, "err") != "err", f"got extra slot '{attr}'" @@ -42,20 +42,20 @@ def test_to_dict(self, web_app_data): web_app_data_dict = web_app_data.to_dict() assert isinstance(web_app_data_dict, dict) - assert web_app_data_dict["data"] == Space.data - assert web_app_data_dict["button_text"] == Space.button_text + assert web_app_data_dict["data"] == self.data + assert web_app_data_dict["button_text"] == self.button_text def test_de_json(self, bot): - json_dict = {"data": Space.data, "button_text": Space.button_text} + json_dict = {"data": self.data, "button_text": self.button_text} web_app_data = WebAppData.de_json(json_dict, bot) assert web_app_data.api_kwargs == {} - assert web_app_data.data == Space.data - assert web_app_data.button_text == Space.button_text + assert web_app_data.data == self.data + assert web_app_data.button_text == self.button_text def test_equality(self): - a = WebAppData(Space.data, Space.button_text) - b = WebAppData(Space.data, Space.button_text) + a = WebAppData(self.data, self.button_text) + b = WebAppData(self.data, self.button_text) c = WebAppData("", "") d = WebAppData("not_data", "not_button_text") diff --git a/tests/test_webappinfo.py b/tests/test_webappinfo.py index cec25822d93..cd1b0723315 100644 --- a/tests/test_webappinfo.py +++ b/tests/test_webappinfo.py @@ -24,14 +24,14 @@ @pytest.fixture(scope="module") def web_app_info(): - return WebAppInfo(url=Space.url) + return WebAppInfo(url=TestWebAppInfoBase.url) -class Space: +class TestWebAppInfoBase: url = "https://www.example.com" -class TestWebAppInfoWithoutRequest: +class TestWebAppInfoWithoutRequest(TestWebAppInfoBase): def test_slot_behaviour(self, web_app_info, mro_slots): for attr in web_app_info.__slots__: assert getattr(web_app_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -41,18 +41,18 @@ def test_to_dict(self, web_app_info): web_app_info_dict = web_app_info.to_dict() assert isinstance(web_app_info_dict, dict) - assert web_app_info_dict["url"] == Space.url + assert web_app_info_dict["url"] == self.url def test_de_json(self, bot): - json_dict = {"url": Space.url} + json_dict = {"url": self.url} web_app_info = WebAppInfo.de_json(json_dict, bot) assert web_app_info.api_kwargs == {} - assert web_app_info.url == Space.url + assert web_app_info.url == self.url def test_equality(self): - a = WebAppInfo(Space.url) - b = WebAppInfo(Space.url) + a = WebAppInfo(self.url) + b = WebAppInfo(self.url) c = WebAppInfo("") d = WebAppInfo("not_url") diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index c93f362273e..554db399222 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -28,18 +28,18 @@ @pytest.fixture(scope="module") def webhook_info(): return WebhookInfo( - url=Space.url, - has_custom_certificate=Space.has_custom_certificate, - pending_update_count=Space.pending_update_count, - ip_address=Space.ip_address, - last_error_date=Space.last_error_date, - max_connections=Space.max_connections, - allowed_updates=Space.allowed_updates, - last_synchronization_error_date=Space.last_synchronization_error_date, + url=TestWebhookInfoBase.url, + has_custom_certificate=TestWebhookInfoBase.has_custom_certificate, + pending_update_count=TestWebhookInfoBase.pending_update_count, + ip_address=TestWebhookInfoBase.ip_address, + last_error_date=TestWebhookInfoBase.last_error_date, + max_connections=TestWebhookInfoBase.max_connections, + allowed_updates=TestWebhookInfoBase.allowed_updates, + last_synchronization_error_date=TestWebhookInfoBase.last_synchronization_error_date, ) -class Space: +class TestWebhookInfoBase: url = "http://www.google.com" has_custom_certificate = False pending_update_count = 5 @@ -50,7 +50,7 @@ class Space: last_synchronization_error_date = time.time() -class TestWebhookInfoWithoutRequest: +class TestWebhookInfoWithoutRequest(TestWebhookInfoBase): def test_slot_behaviour(self, webhook_info, mro_slots): for attr in webhook_info.__slots__: assert getattr(webhook_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -60,42 +60,42 @@ def test_to_dict(self, webhook_info): webhook_info_dict = webhook_info.to_dict() assert isinstance(webhook_info_dict, dict) - assert webhook_info_dict["url"] == Space.url - assert webhook_info_dict["pending_update_count"] == Space.pending_update_count - assert webhook_info_dict["last_error_date"] == Space.last_error_date - assert webhook_info_dict["max_connections"] == Space.max_connections - assert webhook_info_dict["allowed_updates"] == Space.allowed_updates - assert webhook_info_dict["ip_address"] == Space.ip_address + assert webhook_info_dict["url"] == self.url + assert webhook_info_dict["pending_update_count"] == self.pending_update_count + assert webhook_info_dict["last_error_date"] == self.last_error_date + assert webhook_info_dict["max_connections"] == self.max_connections + assert webhook_info_dict["allowed_updates"] == self.allowed_updates + assert webhook_info_dict["ip_address"] == self.ip_address assert ( webhook_info_dict["last_synchronization_error_date"] - == Space.last_synchronization_error_date + == self.last_synchronization_error_date ) def test_de_json(self, bot): json_dict = { - "url": Space.url, - "has_custom_certificate": Space.has_custom_certificate, - "pending_update_count": Space.pending_update_count, - "last_error_date": Space.last_error_date, - "max_connections": Space.max_connections, - "allowed_updates": Space.allowed_updates, - "ip_address": Space.ip_address, - "last_synchronization_error_date": Space.last_synchronization_error_date, + "url": self.url, + "has_custom_certificate": self.has_custom_certificate, + "pending_update_count": self.pending_update_count, + "last_error_date": self.last_error_date, + "max_connections": self.max_connections, + "allowed_updates": self.allowed_updates, + "ip_address": self.ip_address, + "last_synchronization_error_date": self.last_synchronization_error_date, } webhook_info = WebhookInfo.de_json(json_dict, bot) assert webhook_info.api_kwargs == {} - assert webhook_info.url == Space.url - assert webhook_info.has_custom_certificate == Space.has_custom_certificate - assert webhook_info.pending_update_count == Space.pending_update_count + assert webhook_info.url == self.url + assert webhook_info.has_custom_certificate == self.has_custom_certificate + assert webhook_info.pending_update_count == self.pending_update_count assert isinstance(webhook_info.last_error_date, datetime) - assert webhook_info.last_error_date == from_timestamp(Space.last_error_date) - assert webhook_info.max_connections == Space.max_connections - assert webhook_info.allowed_updates == tuple(Space.allowed_updates) - assert webhook_info.ip_address == Space.ip_address + assert webhook_info.last_error_date == from_timestamp(self.last_error_date) + assert webhook_info.max_connections == self.max_connections + assert webhook_info.allowed_updates == tuple(self.allowed_updates) + assert webhook_info.ip_address == self.ip_address assert isinstance(webhook_info.last_synchronization_error_date, datetime) assert webhook_info.last_synchronization_error_date == from_timestamp( - Space.last_synchronization_error_date + self.last_synchronization_error_date ) none = WebhookInfo.de_json(None, bot) @@ -103,24 +103,24 @@ def test_de_json(self, bot): def test_always_tuple_allowed_updates(self): webhook_info = WebhookInfo( - Space.url, Space.has_custom_certificate, Space.pending_update_count + self.url, self.has_custom_certificate, self.pending_update_count ) assert webhook_info.allowed_updates == () def test_equality(self): a = WebhookInfo( - url=Space.url, - has_custom_certificate=Space.has_custom_certificate, - pending_update_count=Space.pending_update_count, - last_error_date=Space.last_error_date, - max_connections=Space.max_connections, + url=self.url, + has_custom_certificate=self.has_custom_certificate, + pending_update_count=self.pending_update_count, + last_error_date=self.last_error_date, + max_connections=self.max_connections, ) b = WebhookInfo( - url=Space.url, - has_custom_certificate=Space.has_custom_certificate, - pending_update_count=Space.pending_update_count, - last_error_date=Space.last_error_date, - max_connections=Space.max_connections, + url=self.url, + has_custom_certificate=self.has_custom_certificate, + pending_update_count=self.pending_update_count, + last_error_date=self.last_error_date, + max_connections=self.max_connections, ) c = WebhookInfo( url="http://github.com", From e079c6b1a5f631b4c9aeec1f4075dbfbbddad1fa Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Jan 2023 01:26:21 +0530 Subject: [PATCH 54/77] Address review of fc5aea4: Add docstring to TestBotWithoutRequest --- tests/test_bot.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_bot.py b/tests/test_bot.py index be9f545c263..cd5263e1724 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -193,6 +193,13 @@ def __init__( class TestBotWithoutRequest: + """ + Most are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot + + Behavior for init of ExtBot with missing optional dependency cachetools (for CallbackDataCache) + is tested in `test_callbackdatacache` + """ + @pytest.mark.parametrize("bot_class", [Bot, ExtBot]) def test_slot_behaviour(self, bot_class, bot, mro_slots): inst = bot_class(bot.token) From 53031be824f0e404a8078ab7af56064ae8d4bc19 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Jan 2023 02:17:32 +0530 Subject: [PATCH 55/77] Address review of 77ecda1: Changes in test_bot.py and conftest.py --- tests/conftest.py | 22 ++++++++++++---------- tests/test_bot.py | 11 +++-------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 59f7f729e7a..152c8139244 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -158,9 +158,7 @@ def __init__(self, *args, **kwargs): # Here we override get_me for caching because we don't want to call the API repeatedly in tests async def get_me(self, *args, **kwargs): - if self._bot_user is None: - self._bot_user = make_mock_user(self.token) - return self._bot_user + return await mocked_get_me(self) class DictBot(Bot): @@ -171,21 +169,25 @@ def __init__(self, *args, **kwargs): # Here we override get_me for caching because we don't want to call the API repeatedly in tests async def get_me(self, *args, **kwargs): - if self._bot_user is None: - self._bot_user = make_mock_user(self.token) - return self._bot_user + return await mocked_get_me(self) class DictApplication(Application): pass -def make_mock_user(token: str) -> User: +async def mocked_get_me(self): + if self._bot_user is None: + self._bot_user = get_bot_user(self.token) + return self._bot_user + + +def get_bot_user(token: str) -> User: """Used to return a mock user in bot.get_me(). This saves API calls on every init.""" bot_info = get_bot() - user_id = int(token.split(":")[0] or bot_info["token"].split(":")[0]) - first_name = bot_info.get("bot_name") or bot_info.get("name") - username = (bot_info.get("bot_username") or bot_info.get("username")).strip("@") + user_id = int(token.split(":")[0]) + first_name = bot_info.get("name") + username = bot_info.get("username").strip("@") return User( user_id, first_name, diff --git a/tests/test_bot.py b/tests/test_bot.py index cd5263e1724..e6d19f14af8 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -351,16 +351,11 @@ async def test_get_me_and_properties_not_initialized(self, bot: Bot, attribute): await bot.shutdown() async def test_get_me_and_properties(self, bot): - mocked = "mocked" - with bot._bot_user._unfrozen(): - bot._bot_user.username = mocked # set the attribute to a mocked value - assert bot.username == mocked # To test we are using the mocked bot - # call the parent class get_me method instead of the overriden get_me method - get_me_bot = await super(bot.__class__, bot).get_me() + get_me_bot = await ExtBot(bot.token).get_me() assert isinstance(get_me_bot, User) assert get_me_bot.id == bot.id - assert get_me_bot.username == bot.username != mocked # will be the real bot + 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 @@ -392,7 +387,7 @@ def test_api_methods_have_log_decorator(self, bot_class, bot_method_name, bot_me async def test_log_decorator(self, bot: DictExtBot, caplog): # Second argument makes sure that we ignore logs from e.g. httpx with caplog.at_level(logging.DEBUG, logger="telegram"): - await super(bot.__class__, bot).get_me() # call original get_me instead of overriden + await ExtBot(bot.token).get_me() # Only for stabilizing this test- if len(caplog.records) == 4: for idx, record in enumerate(caplog.records): From 2596d4c5f096a7b090720b58424334ea44331de6 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Jan 2023 13:50:05 +0530 Subject: [PATCH 56/77] Address review of 4fe9955: Change skipif reason --- tests/test_bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index e6d19f14af8..31949f6d479 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -2638,7 +2638,7 @@ async def test_create_chat_invite_link_basics( ) assert revoked_link.is_revoked - @pytest.mark.skipif(not TEST_WITH_OPT_DEPS, reason="requires pytz") + @pytest.mark.skipif(not TEST_WITH_OPT_DEPS, reason="This test's implementation requires pytz") @pytest.mark.parametrize("datetime", argvalues=[True, False], ids=["datetime", "integer"]) async def test_advanced_chat_invite_links(self, bot, channel_id, datetime): # we are testing this all in one function in order to save api calls From ab3be7e08ca8c296fde876f2168ae4290e16d446 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Jan 2023 14:06:56 +0530 Subject: [PATCH 57/77] Address review of 0920f95: Rename the bot used in app tests --- tests/test_application.py | 113 +++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 55 deletions(-) diff --git a/tests/test_application.py b/tests/test_application.py index 0d82b1703e5..7d3cd8e9cb5 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -63,7 +63,8 @@ @pytest.fixture(scope="function") -def test_bot(bot_info): # was needed since we get HTTPXRequest not initialized after app tests +def one_time_bot(bot_info): + """A function scoped bot since the session bot would shutdown when `async with app` finishes""" return make_bot(bot_info) @@ -124,8 +125,8 @@ async def callback_context(self, update, context): ): self.received = context.error.message - async def test_slot_behaviour(self, test_bot, mro_slots): - async with ApplicationBuilder().bot(test_bot).build() as app: + async def test_slot_behaviour(self, one_time_bot, mro_slots): + async with ApplicationBuilder().bot(one_time_bot).build() as app: for at in app.__slots__: at = f"_Application{at}" if at.startswith("__") and not at.endswith("__") else at assert getattr(app, at, "err") != "err", f"got extra slot '{at}'" @@ -155,12 +156,12 @@ def test_manual_init_warning(self, recwarn, updater): "concurrent_updates, expected", [(0, 0), (4, 4), (False, 0), (True, 256)] ) @pytest.mark.filterwarnings("ignore: `Application` instances should") - def test_init(self, test_bot, concurrent_updates, expected): + def test_init(self, one_time_bot, concurrent_updates, expected): update_queue = asyncio.Queue() job_queue = JobQueue() persistence = PicklePersistence("file_path") context_types = ContextTypes() - updater = Updater(bot=test_bot, update_queue=update_queue) + updater = Updater(bot=one_time_bot, update_queue=update_queue) async def post_init(application: Application) -> None: pass @@ -172,7 +173,7 @@ async def post_stop(application: Application) -> None: pass app = Application( - bot=test_bot, + bot=one_time_bot, update_queue=update_queue, job_queue=job_queue, persistence=persistence, @@ -183,7 +184,7 @@ async def post_stop(application: Application) -> None: post_shutdown=post_shutdown, post_stop=post_stop, ) - assert app.bot is test_bot + assert app.bot is one_time_bot assert app.update_queue is update_queue assert app.job_queue is job_queue assert app.persistence is persistence @@ -207,7 +208,7 @@ async def post_stop(application: Application) -> None: with pytest.raises(ValueError, match="must be a non-negative"): Application( - bot=test_bot, + bot=one_time_bot, update_queue=update_queue, job_queue=job_queue, persistence=persistence, @@ -219,19 +220,19 @@ async def post_stop(application: Application) -> None: post_stop=None, ) - def test_job_queue(self, test_bot, app, recwarn): + def test_job_queue(self, one_time_bot, app, recwarn): expected_warning = ( "No `JobQueue` set up. To use `JobQueue`, you must install PTB via " "`pip install python-telegram-bot[job-queue]`." ) assert app.job_queue is app._job_queue - application = ApplicationBuilder().bot(test_bot).job_queue(None).build() + application = ApplicationBuilder().bot(one_time_bot).job_queue(None).build() assert application.job_queue is None assert len(recwarn) == 1 assert str(recwarn[0].message) == expected_warning assert recwarn[0].filename == __file__, "wrong stacklevel" - def test_custom_context_init(self, bot): + def test_custom_context_init(self, one_time_bot): cc = ContextTypes( context=CustomContext, user_data=int, @@ -239,14 +240,14 @@ def test_custom_context_init(self, bot): bot_data=complex, ) - application = ApplicationBuilder().bot(test_bot).context_types(cc).build() + application = ApplicationBuilder().bot(one_time_bot).context_types(cc).build() assert isinstance(application.user_data[1], int) assert isinstance(application.chat_data[1], float) assert isinstance(application.bot_data, complex) @pytest.mark.parametrize("updater", (True, False)) - async def test_initialize(self, test_bot, monkeypatch, updater): + async def test_initialize(self, one_time_bot, monkeypatch, updater): """Initialization of persistence is tested test_basepersistence""" self.test_flag = set() @@ -262,18 +263,18 @@ async def after_initialize_updater(*args, **kwargs): ) if updater: - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() await app.initialize() assert self.test_flag == {"bot", "updater"} await app.shutdown() else: - app = ApplicationBuilder().bot(test_bot).updater(None).build() + app = ApplicationBuilder().bot(one_time_bot).updater(None).build() await app.initialize() assert self.test_flag == {"bot"} await app.shutdown() @pytest.mark.parametrize("updater", (True, False)) - async def test_shutdown(self, test_bot, monkeypatch, updater): + async def test_shutdown(self, one_time_bot, monkeypatch, updater): """Shutdown of persistence is tested in test_basepersistence""" self.test_flag = set() @@ -289,11 +290,11 @@ def after_updater_shutdown(*args, **kwargs): ) if updater: - async with ApplicationBuilder().bot(test_bot).build(): + async with ApplicationBuilder().bot(one_time_bot).build(): pass assert self.test_flag == {"bot", "updater"} else: - async with ApplicationBuilder().bot(test_bot).updater(None).build(): + async with ApplicationBuilder().bot(one_time_bot).updater(None).build(): pass assert self.test_flag == {"bot"} @@ -340,12 +341,12 @@ async def test_shutdown_while_running(self, app): await app.shutdown() await app.stop() - async def test_start_not_running_after_failure(self, test_bot, monkeypatch): + async def test_start_not_running_after_failure(self, one_time_bot, monkeypatch): def start(_): raise Exception("Test Exception") monkeypatch.setattr(JobQueue, "start", start) - app = ApplicationBuilder().bot(test_bot).job_queue(JobQueue()).build() + app = ApplicationBuilder().bot(one_time_bot).job_queue(JobQueue()).build() async with app: with pytest.raises(Exception, match="Test Exception"): @@ -416,12 +417,12 @@ def test_builder(self, app): @pytest.mark.parametrize("job_queue", (True, False)) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - async def test_start_stop_processing_updates(self, test_bot, job_queue): + async def test_start_stop_processing_updates(self, one_time_bot, job_queue): # TODO: repeat a similar test for create_task, persistence processing and job queue if job_queue: - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() else: - app = ApplicationBuilder().bot(test_bot).job_queue(None).build() + app = ApplicationBuilder().bot(one_time_bot).job_queue(None).build() async def callback(u, c): self.received = u @@ -655,7 +656,7 @@ def handle_update( await asyncio.sleep(0.05) await app.stop() - async def test_flow_stop(self, app, test_bot): + async def test_flow_stop(self, app, one_time_bot): passed = [] async def start1(b, u): @@ -680,8 +681,8 @@ async def start3(b, u): ], ), ) - await test_bot.initialize() - update.message.set_bot(test_bot) + await one_time_bot.initialize() + update.message.set_bot(one_time_bot) async with app: # If ApplicationHandlerStop raised handlers in other groups should not be called. @@ -741,7 +742,7 @@ async def test_error_in_handler_part_1(self, app): # Higher groups should still be called assert self.count == 42 - async def test_error_in_handler_part_2(self, app, test_bot): + async def test_error_in_handler_part_2(self, app, one_time_bot): passed = [] err = Exception("General exception") @@ -771,8 +772,8 @@ async def error(u, c): ], ), ) - await test_bot.initialize() - update.message.set_bot(test_bot) + await one_time_bot.initialize() + update.message.set_bot(one_time_bot) async with app: # If an unhandled exception was caught, no further handlers from the same group should @@ -851,7 +852,7 @@ async def test_error_handler_that_raises_errors(self, app, caplog): await app.stop() - async def test_custom_context_error_handler(self, test_bot): + async def test_custom_context_error_handler(self, one_time_bot): async def error_handler(_, context): self.received = ( type(context), @@ -862,7 +863,7 @@ async def error_handler(_, context): application = ( ApplicationBuilder() - .bot(test_bot) + .bot(one_time_bot) .context_types( ContextTypes( context=CustomContext, bot_data=int, user_data=float, chat_data=complex @@ -880,7 +881,7 @@ async def error_handler(_, context): await asyncio.sleep(0.05) assert self.received == (CustomContext, float, complex, int) - async def test_custom_context_handler_callback(self, test_bot): + async def test_custom_context_handler_callback(self, one_time_bot): async def callback(_, context): self.received = ( type(context), @@ -891,7 +892,7 @@ async def callback(_, context): application = ( ApplicationBuilder() - .bot(test_bot) + .bot(one_time_bot) .context_types( ContextTypes( context=CustomContext, bot_data=int, user_data=float, chat_data=complex @@ -1319,10 +1320,12 @@ async def callback(u, c): await app.stop() @pytest.mark.parametrize("concurrent_updates", (15, 50, 100)) - async def test_concurrent_updates(self, test_bot, concurrent_updates): + async def test_concurrent_updates(self, one_time_bot, concurrent_updates): # We don't test with `True` since the large number of parallel coroutines quickly leads # to test instabilities - app = Application.builder().bot(test_bot).concurrent_updates(concurrent_updates).build() + app = ( + Application.builder().bot(one_time_bot).concurrent_updates(concurrent_updates).build() + ) events = {i: asyncio.Event() for i in range(app.concurrent_updates + 10)} queue = asyncio.Queue() for event in events.values(): @@ -1353,8 +1356,8 @@ async def callback(u, c): await app.stop() - async def test_concurrent_updates_done_on_shutdown(self, test_bot): - app = Application.builder().bot(test_bot).concurrent_updates(True).build() + async def test_concurrent_updates_done_on_shutdown(self, one_time_bot): + app = Application.builder().bot(one_time_bot).concurrent_updates(True).build() event = asyncio.Event() async def callback(update, context): @@ -1438,7 +1441,7 @@ def thread_target(): platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_polling_post_init(self, test_bot, monkeypatch): + def test_run_polling_post_init(self, one_time_bot, monkeypatch): events = [] async def get_updates(*args, **kwargs): @@ -1459,7 +1462,7 @@ def thread_target(): async def post_init(app: Application) -> None: events.append("post_init") - app = Application.builder().bot(test_bot).post_init(post_init).build() + app = Application.builder().bot(one_time_bot).post_init(post_init).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "get_updates", get_updates) monkeypatch.setattr( @@ -1481,7 +1484,7 @@ async def post_init(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_polling_post_shutdown(self, test_bot, monkeypatch): + def test_run_polling_post_shutdown(self, one_time_bot, monkeypatch): events = [] async def get_updates(*args, **kwargs): @@ -1502,7 +1505,7 @@ def thread_target(): async def post_shutdown(app: Application) -> None: events.append("post_shutdown") - app = Application.builder().bot(test_bot).post_shutdown(post_shutdown).build() + app = Application.builder().bot(one_time_bot).post_shutdown(post_shutdown).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "get_updates", get_updates) monkeypatch.setattr( @@ -1707,7 +1710,7 @@ def thread_target(): platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_post_init(self, test_bot, monkeypatch): + def test_run_webhook_post_init(self, one_time_bot, monkeypatch): events = [] async def delete_webhook(*args, **kwargs): @@ -1734,7 +1737,7 @@ def thread_target(): async def post_init(app: Application) -> None: events.append("post_init") - app = Application.builder().bot(test_bot).post_init(post_init).build() + app = Application.builder().bot(one_time_bot).post_init(post_init).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "set_webhook", set_webhook) monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) @@ -1767,7 +1770,7 @@ async def post_init(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_post_shutdown(self, test_bot, monkeypatch): + def test_run_webhook_post_shutdown(self, one_time_bot, monkeypatch): events = [] async def delete_webhook(*args, **kwargs): @@ -1794,7 +1797,7 @@ def thread_target(): async def post_shutdown(app: Application) -> None: events.append("post_shutdown") - app = Application.builder().bot(test_bot).post_shutdown(post_shutdown).build() + app = Application.builder().bot(one_time_bot).post_shutdown(post_shutdown).build() app.bot._unfreeze() monkeypatch.setattr(app.bot, "set_webhook", set_webhook) monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) @@ -1899,7 +1902,7 @@ async def post_stop(app: Application) -> None: platform.system() == "Windows", reason="Can't send signals without stopping whole process on windows", ) - def test_run_webhook_parameters_passing(self, test_bot, monkeypatch): + def test_run_webhook_parameters_passing(self, one_time_bot, monkeypatch): # Check that we pass them correctly async def start_webhook(_, **kwargs): @@ -1914,7 +1917,7 @@ async def stop(_, **kwargs): monkeypatch.setattr(Updater, "start_webhook", start_webhook) monkeypatch.setattr(Updater, "stop", stop) - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() app_signature = inspect.signature(app.run_webhook) for name, param in updater_signature.parameters.items(): @@ -1955,8 +1958,8 @@ def thread_target(): assert set(self.received.keys()) == set(expected.keys()) assert self.received == expected - def test_run_without_updater(self, test_bot): - app = ApplicationBuilder().bot(test_bot).updater(None).build() + def test_run_without_updater(self, one_time_bot): + app = ApplicationBuilder().bot(one_time_bot).updater(None).build() with pytest.raises(RuntimeError, match="only available if the application has an Updater"): app.run_webhook() @@ -1966,7 +1969,7 @@ def test_run_without_updater(self, test_bot): @pytest.mark.parametrize("method", ["start", "initialize"]) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - def test_run_error_in_application(self, test_bot, monkeypatch, method): + def test_run_error_in_application(self, one_time_bot, monkeypatch, method): shutdowns = [] async def raise_method(*args, **kwargs): @@ -1987,7 +1990,7 @@ def _after_shutdown(*args, **kwargs): monkeypatch.setattr( Updater, "shutdown", call_after(Updater.shutdown, after_shutdown("updater")) ) - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() with pytest.raises(RuntimeError, match="Test Exception"): app.run_polling(close_loop=False) @@ -2002,7 +2005,7 @@ def _after_shutdown(*args, **kwargs): @pytest.mark.parametrize("method", ["start_polling", "start_webhook"]) @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - def test_run_error_in_updater(self, test_bot, monkeypatch, method): + def test_run_error_in_updater(self, one_time_bot, monkeypatch, method): shutdowns = [] async def raise_method(*args, **kwargs): @@ -2023,7 +2026,7 @@ def _after_shutdown(*args, **kwargs): monkeypatch.setattr( Updater, "shutdown", call_after(Updater.shutdown, after_shutdown("updater")) ) - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() with pytest.raises(RuntimeError, match="Test Exception"): if "polling" in method: app.run_polling(close_loop=False) @@ -2039,12 +2042,12 @@ def _after_shutdown(*args, **kwargs): reason="Only really relevant on windows", ) @pytest.mark.parametrize("method", ["start_polling", "start_webhook"]) - def test_run_stop_signal_warning_windows(self, test_bot, method, recwarn, monkeypatch): + def test_run_stop_signal_warning_windows(self, one_time_bot, method, recwarn, monkeypatch): async def raise_method(*args, **kwargs): raise RuntimeError("Prevent Actually Running") monkeypatch.setattr(Application, "initialize", raise_method) - app = ApplicationBuilder().bot(test_bot).build() + app = ApplicationBuilder().bot(one_time_bot).build() with pytest.raises(RuntimeError, match="Prevent Actually Running"): if "polling" in method: From ebecf27d8032b2629a0d4f4f0bafb807732682ee Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 01:02:43 +0530 Subject: [PATCH 58/77] fix some typos and tiny bugs in test_app.py --- tests/test_application.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_application.py b/tests/test_application.py index 7d3cd8e9cb5..ec155587c4c 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -695,16 +695,16 @@ async def start3(b, u): async def test_flow_stop_by_error_handler(self, app): passed = [] - exception = Exception("General excepition") + exception = Exception("General exception") - async def start1(b, u): + async def start1(u, c): passed.append("start1") raise exception - async def start2(b, u): + async def start2(u, c): passed.append("start2") - async def start3(b, u): + async def start3(u, c): passed.append("start3") async def error(u, c): @@ -986,7 +986,7 @@ async def callback(update, context): ), "incorrect stacklevel!" async def test_non_blocking_no_error_handler(self, app, caplog): - app.add_handler(TypeHandler(object, self.callback_raise_error, block=False)) + app.add_handler(TypeHandler(object, self.callback_raise_error("Test error"), block=False)) with caplog.at_level(logging.ERROR): async with app: @@ -1012,7 +1012,7 @@ async def normal_error_handler(update, context): app.add_error_handler(async_error_handler, block=False) app.add_error_handler(normal_error_handler) - app.add_handler(TypeHandler(object, self.callback_raise_error, block=handler_block)) + app.add_handler(TypeHandler(object, self.callback_raise_error("err"), block=handler_block)) async with app: await app.start() @@ -1064,7 +1064,7 @@ async def error_handler(*args, **kwargs): bot = make_bot(bot_info, defaults=Defaults(block=block)) app = Application.builder().bot(bot).build() async with app: - app.add_handler(TypeHandler(object, self.callback_raise_error)) + app.add_handler(TypeHandler(object, self.callback_raise_error("error"))) app.add_error_handler(error_handler) await app.process_update(1) await asyncio.sleep(0.05) @@ -1089,7 +1089,7 @@ async def test_default_block_handler(self, bot_info, block, expected_output): async def test_nonblocking_handler_raises_and_non_blocking_error_handler_raises( self, app, caplog, handler_block, error_handler_block ): - handler = TypeHandler(object, self.callback_raise_error, block=handler_block) + handler = TypeHandler(object, self.callback_raise_error("error"), block=handler_block) app.add_handler(handler) app.add_error_handler(self.error_handler_raise_error, block=error_handler_block) From e60d2e1a3d8d572b4e05d4dcb66e5acfc078e9a8 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 01:15:26 +0530 Subject: [PATCH 59/77] Address review of 857949a: slightly modify test logic --- tests/test_chatphoto.py | 11 +++++++---- tests/test_constants.py | 12 ++++++----- tests/test_invoice.py | 44 ++++++++++++++++++----------------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/tests/test_chatphoto.py b/tests/test_chatphoto.py index ed1410fce73..d2d4ad4fa8e 100644 --- a/tests/test_chatphoto.py +++ b/tests/test_chatphoto.py @@ -159,18 +159,21 @@ async def test_get_and_download(self, bot, chat_photo): jpg_file.unlink() tasks = {bot.get_file(chat_photo.small_file_id), bot.get_file(chat_photo.big_file_id)} + asserts = [] for task in asyncio.as_completed(tasks): file = await task - assert file.file_unique_id in ( - chat_photo.small_file_unique_id, - chat_photo.big_file_unique_id, - ) + if file.file_unique_id == chat_photo.small_file_unique_id: + asserts.append("small") + elif file.file_unique_id == chat_photo.big_file_unique_id: + asserts.append("big") assert file.file_path.startswith("https://") await file.download_to_drive(jpg_file) assert jpg_file.is_file() + assert "small" in asserts and "big" in asserts + async def test_send_all_args(self, bot, super_group_id, chatphoto_file): async def func(): assert await bot.set_chat_photo(super_group_id, chatphoto_file) diff --git a/tests/test_constants.py b/tests/test_constants.py index bfe4f82f17a..f69199ceb50 100644 --- a/tests/test_constants.py +++ b/tests/test_constants.py @@ -130,14 +130,16 @@ def test_bot_api_version_info(self): class TestConstantsWithRequest: async def test_max_message_length(self, bot, chat_id): + good_text = "a" * constants.MessageLimit.MAX_TEXT_LENGTH + bad_text = good_text + "Z" tasks = asyncio.gather( - bot.send_message(chat_id, text="a" * constants.MessageLimit.MAX_TEXT_LENGTH), - bot.send_message(chat_id, text="a" * (constants.MessageLimit.MAX_TEXT_LENGTH + 1)), + bot.send_message(chat_id, text=good_text), + bot.send_message(chat_id, text=bad_text), return_exceptions=True, ) - results = await tasks - assert len(results) == 2 - assert isinstance(results[1], BadRequest) and "Message is too long" in str(results[1]) + good_msg, bad_msg = await tasks + assert good_msg.text == good_text + assert isinstance(bad_msg, BadRequest) and "Message is too long" in str(bad_msg) async def test_max_caption_length(self, bot, chat_id): good_caption = "a" * constants.MessageLimit.CAPTION_LENGTH diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 877a366615d..209635ee008 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -184,39 +184,33 @@ def test_equality(self): class TestInvoiceWithRequest(TestInvoiceBase): async def test_send_required_args_only(self, bot, chat_id, provider_token): - send_inv_task = asyncio.create_task( - bot.send_invoice( - chat_id=chat_id, - title=self.title, - description=self.description, - payload=self.payload, - provider_token=provider_token, - currency=self.currency, - prices=self.prices, - ) - ) - create_inv_link_task = asyncio.create_task( - bot.create_invoice_link( - title=self.title, - description=self.description, - payload=self.payload, - provider_token=provider_token, - currency=self.currency, - prices=self.prices, - ) + message = await bot.send_invoice( + chat_id=chat_id, + title=self.title, + description=self.description, + payload=self.payload, + provider_token=provider_token, + currency=self.currency, + prices=self.prices, ) - message = await send_inv_task assert message.invoice.currency == self.currency assert message.invoice.start_parameter == "" assert message.invoice.description == self.description assert message.invoice.title == self.title assert message.invoice.total_amount == self.total_amount - link = await create_inv_link_task + link = await bot.create_invoice_link( + title=self.title, + description=self.description, + payload=self.payload, + provider_token=provider_token, + currency=self.currency, + prices=self.prices, + ) + assert isinstance(link, str) assert link != "" - assert send_inv_task.done() and create_inv_link_task.done() @pytest.mark.parametrize("default_bot", [{"protect_content": True}], indirect=True) async def test_send_invoice_default_protect_content( @@ -232,9 +226,9 @@ async def test_send_invoice_default_protect_content( provider_token, self.currency, self.prices, - **i, + **kwargs, ) - for i in ({}, {"protect_content": False}) + for kwargs in ({}, {"protect_content": False}) ) ) protected, unprotected = await tasks From 01c8b5c1c6cf87cb02013837334bbd237114719c Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 01:16:39 +0530 Subject: [PATCH 60/77] Address review of b330c97: change variable name i -> key --- tests/test_invoice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_invoice.py b/tests/test_invoice.py index 209635ee008..cc2a0b2fa30 100644 --- a/tests/test_invoice.py +++ b/tests/test_invoice.py @@ -89,7 +89,7 @@ async def test_send_invoice_all_args_mock(self, bot, monkeypatch): # parameters correctly because #2526 went unnoticed for 3 years … async def make_assertion(*args, **_): kwargs = args[1] - return all([kwargs[i] == i for i in kwargs]) + return all([kwargs[key] == key for key in kwargs]) monkeypatch.setattr(bot, "_send_message", make_assertion) assert await bot.send_invoice( From 6a9bbc04614c2aa9497cf2489fc56287c2c95b66 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 03:05:15 +0530 Subject: [PATCH 61/77] Address review of 6ea3515: Update test readme and add to index.html --- .github/CONTRIBUTING.rst | 31 ++---------- docs/source/index.rst | 1 + docs/source/testing.rst | 1 + requirements-dev.txt | 2 +- tests/README.md | 51 -------------------- tests/README.rst | 101 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 108 insertions(+), 79 deletions(-) create mode 100644 docs/source/testing.rst delete mode 100644 tests/README.md create mode 100644 tests/README.rst diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index 6b813ead8a4..f254a3260e0 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -84,35 +84,13 @@ Here's how to make a one-off code change. - In addition, PTB uses some formatting/styling and linting tools in the pre-commit setup. Some of those tools also have command line tools that can help to run these tools outside of the pre-commit step. If you'd like to leverage that, please have a look at the `pre-commit config file`_ for an overview of which tools (and which versions of them) are used. For example, we use `Black`_ for code formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything. - - Please ensure that the code you write is well-tested. + - Please ensure that the code you write is well-tested and that all automated tests still pass. We + have dedicated an :doc:`testing page ` to help you with that. - - In addition to that, we provide the `dev` marker for pytest. If you write one or multiple tests and want to run only those, you can decorate them via `@pytest.mark.dev` and then run it with minimal overhead with `pytest ./path/to/test_file.py -m dev`. - - - Don’t break backward compatibility. + - Don't break backward compatibility. - Add yourself to the AUTHORS.rst_ file in an alphabetical fashion. - - Before making a commit ensure that all automated tests still pass: - - .. code-block:: bash - - $ pytest -v - - Since the tests can take a while to run, you can speed things up by running them in parallel - using `pytest-xdist`_ (note that this may effect the result of the test in some rare cases): - - .. code-block:: bash - - $ pytest -v -n auto --dist=loadfile - - To run ``test_official`` (particularly useful if you made API changes), run - - .. code-block:: bash - - $ export TEST_OFFICIAL=true - - prior to running the tests. - - If you want run style & type checks before committing run .. code-block:: bash @@ -286,5 +264,4 @@ break the API classes. For example: .. _`RTD`: https://docs.python-telegram-bot.org/ .. _`RTD build`: https://docs.python-telegram-bot.org/en/doc-fixes .. _`CSI`: https://standards.mousepawmedia.com/en/stable/csi.html -.. _`section`: #documenting -.. _`pytest-xdist`: https://github.com/pytest-dev/pytest-xdist +.. _`section`: #documenting \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index c9e356dc7d7..a89a6f2f956 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,6 +33,7 @@ Telegram Channel Telegram User Group contributing + testing coc diff --git a/docs/source/testing.rst b/docs/source/testing.rst new file mode 100644 index 00000000000..c32693c242a --- /dev/null +++ b/docs/source/testing.rst @@ -0,0 +1 @@ +.. include:: ../../tests/README.rst \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 558dbc931e8..168a29c9a4a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -2,7 +2,7 @@ pre-commit # needed for pre-commit hooks in the git commit command # For the test suite pytest==7.2.0 -pytest-asyncio==0.20.3 # needed for async tests +pytest-asyncio==0.20.3 # needed because pytest doesn't come with native support for coroutines as tests pytest-xdist==3.1.0 # xdist runs tests in parallel flaky # Used for flaky tests (flaky decorator) beautifulsoup4 # used in test_official for parsing tg docs diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index c0ec78f4aa1..00000000000 --- a/tests/README.md +++ /dev/null @@ -1,51 +0,0 @@ -## Testing in PTB - -PTB uses [pytest](https://docs.pytest.org/en/latest/) for testing. To run the tests, you need to -have pytest installed along with a few other dependencies. You can find the list of dependencies -in the `requirements-dev.txt` file in the root of the repository. - -### Running tests - -To run the entire test suite, you can use the following command: - - $ pytest - -This will run all the tests, including the ones which make a request to the Telegram servers, which -may take a long time (about > 13 mins). To run only the tests that don't require a connection, you -can run the following command: - - $ pytest -m no_req - -To further speed up the tests, you can run them in parallel using the `-n` flag: - - $ pytest -n auto - -This will result in a significant speedup, but may cause some tests to fail. If you want to run -the failed tests in isolation, you can use the `--lf` flag: - - $ pytest --lf - - -### Writing tests - -PTB has a separate test file for every file in the `telegram.*` namespace. Further, the tests for -the `telegram` module are split into two classes, based on whether the test methods in them make a -request or not. When writing tests, make sure to split them into these two classes, and make sure -to name the test class as: `TestXXXWithoutRequest` for tests that don't make a request, and `TestXXXReq` for -tests that do. - -Writing tests is a creative process, where you can design your test however you'd like, but there -are a few conventions that you should follow: - -- Each new test class needs a `test_slot_behaviour`, `test_to_dict`, `test_de_json` and - `test_equality` (in most cases). - -- Make use of pytest's fixtures and parametrize wherever possible. Having knowledge of pytest's - tooling can help you as well. You can look at the existing tests for examples. - -We also have another marker, `@pytest.mark.dev`, which is used to mark tests that you want to run selectively. -Use as follows: - - $ pytest -m dev - -That's it! If you have any questions, feel free to ask them in the [PTB dev group](https://t.me/pythontelegrambotdev). \ No newline at end of file diff --git a/tests/README.rst b/tests/README.rst new file mode 100644 index 00000000000..fb2ffe14bf6 --- /dev/null +++ b/tests/README.rst @@ -0,0 +1,101 @@ +============== +Testing in PTB +============== + +PTB uses `pytest`_ for testing. To run the tests, you need to +have pytest installed along with a few other dependencies. You can find the list of dependencies +in the ``requirements-dev.txt`` file in the root of the repository. + +Running tests +============= + +To run the entire test suite, you can use the following command: + +.. code-block:: bash + + $ pytest + +This will run all the tests, including the ones which make a request to the Telegram servers, which +may take a long time (total > 13 mins). To run only the tests that don't require a connection, you +can run the following command: + +.. code-block:: bash + + $ pytest -m no_req + +Or alternatively, you can run the following command to run only the tests that require a connection: + +.. code-block:: bash + + $ pytest -m req + +To further speed up the tests, you can run them in parallel using the ``-n`` flag (requires `pytest-xdist`_). But beware that +this will use multiple CPU cores on your machine. The ``--dist`` flag is used to specify how the +tests will be distributed across the cores. The ``loadgroup`` option is used to distribute the tests +such that tests marked with ``@pytest.mark.xdist_group("name")`` are run on the same core — important if you want avoid race conditions in some tests: + +.. code-block:: bash + + $ pytest -n auto --dist=loadgroup + +This will result in a significant speedup, but may cause some tests to fail. If you want to run +the failed tests in isolation, you can use the ``--lf`` flag: + +.. code-block:: bash + + $ pytest --lf + + +Writing tests +============= + +PTB has a separate test file for every file in the ``telegram.*`` namespace. Further, the tests for +the ``telegram`` module are split into two classes, based on whether the test methods in them make a +request or not. When writing tests, make sure to split them into these two classes, and make sure +to name the test class as: ``TestXXXWithoutRequest`` for tests that don't make a request, and ``TestXXXWithRequest`` for tests that do. + +Writing tests is a creative process; allowing you to design your test however you'd like, but there +are a few conventions that you should follow: + +- Each new test class needs a ``test_slot_behaviour``, ``test_to_dict``, ``test_de_json`` and + ``test_equality`` (in most cases). + +- Make use of pytest's fixtures and parametrize wherever possible. Having knowledge of pytest's + tooling can help you as well. You can look at the existing tests for examples and inspiration. + +If you have made some API changes, you may want to run ``test_official`` to validate that the changes are +complete and correct. To run it, export an environment variable first: + +.. code-block:: bash + + $ export TEST_OFFICIAL=true + +and then run ``pytest tests/test_official.py``. + +We also have another marker, ``@pytest.mark.dev``, which you can add to tests that you want to run selectively. +Use as follows: + +.. code-block:: bash + + $ pytest -m dev + + +Bots used in tests +================== + +If you run the tests locally, the test setup will use one of the two public bots available. Which +bot of the two gets chosen for the test session is random. Whereas when the tests on the +Github Actions CI are run, the test setup allocates a different, but same bot for every combination of Python version and +OS. + +Thus, number of bots used for testing locally is 2 (called as fallback bots), and on the CI, +its [3.7, 3.8, 3.9, 3.10, 3.11] x [ubuntu-latest, macos-latest, windows-latest] = 15. Bringing the +total number of bots used for testing to 17. + + +That's it! If you have any questions, feel free to ask them in the `PTB dev +group`_. + +.. _pytest: https://docs.pytest.org/en/stable/ +.. _pytest-xdist: https://pypi.org/project/pytest-xdist/ +.. _PTB dev group: https://t.me/pythontelegrambotgroup \ No newline at end of file From 119858d1ad2918cf1d3e32f71473a52b1fc925b4 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 03:17:03 +0530 Subject: [PATCH 62/77] Address review of 4b55ee5: Drop testing of file_id with get_file --- tests/test_animation.py | 1 - tests/test_audio.py | 2 -- tests/test_document.py | 2 -- tests/test_sticker.py | 2 -- tests/test_video.py | 2 -- tests/test_videonote.py | 2 -- tests/test_voice.py | 2 -- 7 files changed, 13 deletions(-) diff --git a/tests/test_animation.py b/tests/test_animation.py index b093f6ca790..2a344f1327c 100644 --- a/tests/test_animation.py +++ b/tests/test_animation.py @@ -226,7 +226,6 @@ async def test_get_and_download(self, bot, animation): new_file = await bot.get_file(animation.file_id) - assert new_file.file_id == animation.file_id assert new_file.file_path.startswith("https://") new_filepath = await new_file.download_to_drive("game.gif") diff --git a/tests/test_audio.py b/tests/test_audio.py index e2a4e62f6d1..322e61f9e1e 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -232,11 +232,9 @@ async def test_get_and_download(self, bot, chat_id, audio): if path.is_file(): path.unlink() - audio = (await bot.send_audio(chat_id, audio.file_id, read_timeout=50)).audio new_file = await bot.get_file(audio.file_id) assert new_file.file_size == self.file_size - assert new_file.file_id == audio.file_id assert new_file.file_unique_id == audio.file_unique_id assert str(new_file.file_path).startswith("https://") diff --git a/tests/test_document.py b/tests/test_document.py index 40764ea68c7..93574a231e2 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -201,11 +201,9 @@ async def test_get_and_download(self, bot, document, chat_id): if path.is_file(): path.unlink() - document = (await bot.send_document(chat_id, document, read_timeout=50)).document new_file = await bot.get_file(document.file_id) assert new_file.file_size == document.file_size - assert new_file.file_id == document.file_id assert new_file.file_unique_id == document.file_unique_id assert new_file.file_path.startswith("https://") diff --git a/tests/test_sticker.py b/tests/test_sticker.py index 75ff7a9341b..b4c1c2ecd8e 100644 --- a/tests/test_sticker.py +++ b/tests/test_sticker.py @@ -299,11 +299,9 @@ async def test_get_and_download(self, bot, sticker, chat_id): if path.is_file(): path.unlink() - sticker = (await bot.send_sticker(chat_id, sticker, read_timeout=50)).sticker new_file = await bot.get_file(sticker.file_id) assert new_file.file_size == sticker.file_size - assert new_file.file_id == sticker.file_id assert new_file.file_unique_id == sticker.file_unique_id assert new_file.file_path.startswith("https://") diff --git a/tests/test_video.py b/tests/test_video.py index dd97ccd71b1..e88cb831ca3 100644 --- a/tests/test_video.py +++ b/tests/test_video.py @@ -243,11 +243,9 @@ async def test_get_and_download(self, bot, video, chat_id): if path.is_file(): path.unlink() - video = (await bot.send_video(chat_id, video.file_id, read_timeout=50)).video new_file = await bot.get_file(video.file_id) assert new_file.file_size == self.file_size - assert new_file.file_id == video.file_id assert new_file.file_unique_id == video.file_unique_id assert new_file.file_path.startswith("https://") diff --git a/tests/test_videonote.py b/tests/test_videonote.py index ff4c0acc306..9a857b0c387 100644 --- a/tests/test_videonote.py +++ b/tests/test_videonote.py @@ -219,11 +219,9 @@ async def test_get_and_download(self, bot, video_note, chat_id): if path.is_file(): path.unlink() - video_note = (await bot.send_video_note(chat_id, video_note, read_timeout=50)).video_note new_file = await bot.get_file(video_note.file_id) assert new_file.file_size == self.file_size - assert new_file.file_id == video_note.file_id assert new_file.file_unique_id == video_note.file_unique_id assert new_file.file_path.startswith("https://") diff --git a/tests/test_voice.py b/tests/test_voice.py index 1177840caf7..67557661a16 100644 --- a/tests/test_voice.py +++ b/tests/test_voice.py @@ -203,11 +203,9 @@ async def test_get_and_download(self, bot, voice, chat_id): if path.is_file(): path.unlink() - voice = (await bot.send_voice(chat_id, voice, read_timeout=50)).voice new_file = await bot.get_file(voice.file_id) assert new_file.file_size == voice.file_size - assert new_file.file_id == voice.file_id assert new_file.file_unique_id == voice.file_unique_id assert new_file.file_path.startswith("https://") From a9ce337478815b3ad3159dd6fb98f9f6661844c3 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 03:52:41 +0530 Subject: [PATCH 63/77] Address review of 4ea871e: put variable in class instead of global --- tests/bots.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/bots.py b/tests/bots.py index 772ad04976e..2098efa9bee 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -47,7 +47,9 @@ FALLBACKS = json.loads(base64.b64decode(FALLBACKS).decode("utf-8")) # type: list[dict[str, str]] -chosen_bot = {} + +class BotInfoProvider: + chosen_bot = {} def get(key, fallback): @@ -63,8 +65,7 @@ def get(key, fallback): def get_bot(): - global chosen_bot - if chosen_bot: - return chosen_bot - chosen_bot = {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} - return chosen_bot + if BotInfoProvider.chosen_bot: + return BotInfoProvider.chosen_bot + BotInfoProvider.chosen_bot = {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} + return BotInfoProvider.chosen_bot From 7d6404524fc68984312405b90a1fae1e4099c838 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sat, 14 Jan 2023 03:56:26 +0530 Subject: [PATCH 64/77] Address review of 4f69b52: Modify comment in test_signal_handlers --- tests/test_application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_application.py b/tests/test_application.py index ec155587c4c..0598ddc767f 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -2073,7 +2073,7 @@ async def raise_method(*args, **kwargs): assert len(recwarn) == 0 - @pytest.mark.flaky(3, 1) # We could run into a flood error from run_webhook + @pytest.mark.flaky(3, 1) # loop.call_later will error the test when a flood error is received def test_signal_handlers(self, app, monkeypatch): # this test should make sure that signal handlers are set by default on Linux + Mac, # and not on Windows. From 6acd3240b66a76432383397280f4abfdc023715a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:10:49 +0530 Subject: [PATCH 65/77] add CSI comment about shutting down bots --- tests/conftest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 152c8139244..3a282def361 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -225,6 +225,9 @@ async def raw_bot(bot_info): yield _bot +# Here we store the default bots so that we don't have to create them again and again. +# They are initialized but not shutdown on pytest_sessionfinish because it is causing +# problems with the event loop (Event loop is closed). default_bots = {} From ac14ae18d67259c2ad41d6b07f4f1ab379d2da52 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:11:53 +0530 Subject: [PATCH 66/77] add back test_flag as autouse function --- tests/test_bot.py | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/tests/test_bot.py b/tests/test_bot.py index 31949f6d479..1e4aaee2f29 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -200,6 +200,12 @@ class TestBotWithoutRequest: is tested in `test_callbackdatacache` """ + test_flag = None + + @pytest.fixture(scope="function", autouse=True) + def reset(self): + self.test_flag = None + @pytest.mark.parametrize("bot_class", [Bot, ExtBot]) def test_slot_behaviour(self, bot_class, bot, mro_slots): inst = bot_class(bot.token) @@ -222,15 +228,11 @@ async def test_to_dict(self, bot): assert to_dict_bot["last_name"] == bot.last_name async def test_initialize_and_shutdown(self, bot: DictExtBot, monkeypatch): - test_flag = [] - async def initialize(*args, **kwargs): - nonlocal test_flag - test_flag = ["initialize"] + self.test_flag = ["initialize"] async def stop(*args, **kwargs): - nonlocal test_flag - test_flag.append("stop") + self.test_flag.append("stop") temp_bot = DictBot(token=bot.token) orig_stop = temp_bot.request.shutdown @@ -239,11 +241,11 @@ async def stop(*args, **kwargs): monkeypatch.setattr(temp_bot.request, "initialize", initialize) monkeypatch.setattr(temp_bot.request, "shutdown", stop) await temp_bot.initialize() - assert test_flag == ["initialize"] + assert self.test_flag == ["initialize"] assert temp_bot.bot == bot.bot await temp_bot.shutdown() - assert test_flag == ["initialize", "stop"] + assert self.test_flag == ["initialize", "stop"] finally: await orig_stop() @@ -272,15 +274,11 @@ async def shutdown(*args, **kwargs): assert self.received["shutdown"] == 2 async def test_context_manager(self, monkeypatch, bot): - test_flag = [] - async def initialize(): - nonlocal test_flag - test_flag = ["initialize"] + self.test_flag = ["initialize"] async def shutdown(*args): - nonlocal test_flag - test_flag.append("stop") + self.test_flag.append("stop") monkeypatch.setattr(bot, "initialize", initialize) monkeypatch.setattr(bot, "shutdown", shutdown) @@ -288,17 +286,14 @@ async def shutdown(*args): async with bot: pass - assert test_flag == ["initialize", "stop"] + assert self.test_flag == ["initialize", "stop"] async def test_context_manager_exception_on_init(self, monkeypatch, bot): - test_flag = [] - async def initialize(): raise RuntimeError("initialize") async def shutdown(): - nonlocal test_flag - test_flag = "stop" + self.test_flag = "stop" monkeypatch.setattr(bot, "initialize", initialize) monkeypatch.setattr(bot, "shutdown", shutdown) @@ -307,7 +302,7 @@ async def shutdown(): async with bot: pass - assert test_flag == "stop" + assert self.test_flag == "stop" async def test_equality(self): async with make_bot(token=FALLBACKS[0]["token"]) as a, make_bot( @@ -1265,20 +1260,19 @@ async def test_set_chat_photo_local_files(self, monkeypatch, bot, chat_id, local try: bot._local_mode = local_mode # For just test that the correct paths are passed as we have no local bot API set up - test_flag = False + self.test_flag = False file = data_file("telegram.jpg") expected = file.as_uri() async def make_assertion(_, data, *args, **kwargs): - nonlocal test_flag if local_mode: - test_flag = data.get("photo") == expected + self.test_flag = data.get("photo") == expected else: - test_flag = isinstance(data.get("photo"), InputFile) + self.test_flag = isinstance(data.get("photo"), InputFile) monkeypatch.setattr(bot, "_post", make_assertion) await bot.set_chat_photo(chat_id, file) - assert test_flag + assert self.test_flag finally: bot._local_mode = False From eb8de6037261471025bc1e43b36fd9b0a861b0c6 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:26:30 +0530 Subject: [PATCH 67/77] add except TelegramError to an app test --- tests/test_application.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_application.py b/tests/test_application.py index 0598ddc767f..8f67df79155 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -454,7 +454,9 @@ async def callback(u, c): assert self.received == 1 try: # just in case start_polling times out await app.updater.start_polling() - finally: # stop the app so it doesn't crash on shutdown + except TelegramError: + pytest.xfail("start_polling timed out") + else: await app.stop() assert not app.running # app.stop() should not stop the updater! From 5d6a0c7e2b1872e828f6f8dac434e5a7281aeba6 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:35:12 +0530 Subject: [PATCH 68/77] fix link in contributing.rst --- .github/CONTRIBUTING.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst index f254a3260e0..f11eb3ce203 100644 --- a/.github/CONTRIBUTING.rst +++ b/.github/CONTRIBUTING.rst @@ -85,7 +85,7 @@ Here's how to make a one-off code change. - In addition, PTB uses some formatting/styling and linting tools in the pre-commit setup. Some of those tools also have command line tools that can help to run these tools outside of the pre-commit step. If you'd like to leverage that, please have a look at the `pre-commit config file`_ for an overview of which tools (and which versions of them) are used. For example, we use `Black`_ for code formatting. Plugins for Black exist for some `popular editors`_. You can use those instead of manually formatting everything. - Please ensure that the code you write is well-tested and that all automated tests still pass. We - have dedicated an :doc:`testing page ` to help you with that. + have dedicated an `testing page`_ to help you with that. - Don't break backward compatibility. @@ -264,4 +264,5 @@ break the API classes. For example: .. _`RTD`: https://docs.python-telegram-bot.org/ .. _`RTD build`: https://docs.python-telegram-bot.org/en/doc-fixes .. _`CSI`: https://standards.mousepawmedia.com/en/stable/csi.html -.. _`section`: #documenting \ No newline at end of file +.. _`section`: #documenting +.. _`testing page`: https://github.com/python-telegram-bot/python-telegram-bot/blob/master/tests/README.rst From 2587d97a6835b5220b37f3ec249ed621905ab52f Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:37:29 +0530 Subject: [PATCH 69/77] expand comment in test.yml --- .github/workflows/test.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 249c72f836f..5a78db73902 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -44,7 +44,13 @@ jobs: # The first & second one are achieved by mocking the corresponding import # See test_helpers.py & test_no_passport.py for details run: | - # We test without optional dependencies first. + # We test without optional dependencies first. This includes: + # - without pytz + # - without jobqueue + # - without ratelimiter + # - without webhooks + # - without arbitrary callback data + # - without socks suppport TO_TEST="test_no_passport.py or test_datetime.py or test_defaults.py or test_jobqueue.py or test_applicationbuilder.py or test_ratelimiter.py or test_updater.py or test_callbackdatacache.py or test_request.py" pytest -v --cov -k "${TO_TEST}" status=$? From 3da231fca3a8dd3b7a31c2ea8668b86e06f48a7f Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:38:37 +0530 Subject: [PATCH 70/77] move contributing and testing below coc --- docs/source/index.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/source/index.rst b/docs/source/index.rst index a89a6f2f956..adccdbef560 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -32,8 +32,6 @@ GitHub Repository Telegram Channel Telegram User Group + coc contributing testing - coc - - From 7a79ae4e6ee6a22a43380b7d29d0ea8f1a3c6141 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:48:56 +0530 Subject: [PATCH 71/77] make BotInfo a proper class --- tests/bots.py | 16 ++++++++-------- tests/conftest.py | 14 ++++++++------ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/tests/bots.py b/tests/bots.py index 2098efa9bee..70849d45a0b 100644 --- a/tests/bots.py +++ b/tests/bots.py @@ -49,7 +49,14 @@ class BotInfoProvider: - chosen_bot = {} + def __init__(self): + self._cached = {} + + def get_info(self): + if self._cached: + return self._cached + self._cached = {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} + return self._cached def get(key, fallback): @@ -62,10 +69,3 @@ def get(key, fallback): # Otherwise go with the fallback return fallback - - -def get_bot(): - if BotInfoProvider.chosen_bot: - return BotInfoProvider.chosen_bot - BotInfoProvider.chosen_bot = {k: get(k, v) for k, v in random.choice(FALLBACKS).items()} - return BotInfoProvider.chosen_bot diff --git a/tests/conftest.py b/tests/conftest.py index 3a282def361..c87acb849ba 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,7 +22,7 @@ import re import sys from pathlib import Path -from typing import Callable, List, Optional +from typing import Callable, Dict, List, Optional import pytest from httpx import AsyncClient, Response @@ -48,7 +48,9 @@ from telegram.request import RequestData from telegram.request._httpxrequest import HTTPXRequest from tests.auxil.object_conversions import env_var_2_bool -from tests.bots import get_bot +from tests.bots import BotInfoProvider + +BOT_INFO = BotInfoProvider() # This is here instead of in setup.cfg due to https://github.com/pytest-dev/pytest/issues/8343 @@ -118,8 +120,8 @@ def event_loop(request): @pytest.fixture(scope="session") -def bot_info(): - return get_bot() +def bot_info() -> Dict[str, str]: + return BOT_INFO.get_info() # Below classes are used to monkeypatch attributes since parent classes don't have __dict__ @@ -184,7 +186,7 @@ async def mocked_get_me(self): def get_bot_user(token: str) -> User: """Used to return a mock user in bot.get_me(). This saves API calls on every init.""" - bot_info = get_bot() + bot_info = BOT_INFO.get_info() user_id = int(token.split(":")[0]) first_name = bot_info.get("name") username = bot_info.get("username").strip("@") @@ -354,7 +356,7 @@ def make_message(text, **kwargs): """ bot = kwargs.pop("bot", None) if bot is None: - bot = make_bot(get_bot()) + bot = make_bot(BOT_INFO.get_info()) message = Message( message_id=1, from_user=kwargs.pop("user", User(id=1, first_name="", is_bot=False)), From ac401b2514bd19af8f26dc47cee796bff69bdbee Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:51:23 +0530 Subject: [PATCH 72/77] self -> bot --- tests/conftest.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index c87acb849ba..acd0bb81f6e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -178,10 +178,10 @@ class DictApplication(Application): pass -async def mocked_get_me(self): - if self._bot_user is None: - self._bot_user = get_bot_user(self.token) - return self._bot_user +async def mocked_get_me(bot: Bot): + if bot._bot_user is None: + bot._bot_user = get_bot_user(bot.token) + return bot._bot_user def get_bot_user(token: str) -> User: From e6eec745340a36431290b0cb3f6a71abf773ea4a Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 15:54:00 +0530 Subject: [PATCH 73/77] move one_time_bot from application.py to conftest --- tests/conftest.py | 6 ++++++ tests/test_application.py | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index acd0bb81f6e..a0f7203596a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -208,6 +208,12 @@ async def bot(bot_info): yield _bot +@pytest.fixture(scope="function") +def one_time_bot(bot_info): + """A function scoped bot since the session bot would shutdown when `async with app` finishes""" + return make_bot(bot_info) + + @pytest.fixture(scope="session") async def cdc_bot(bot_info): """Makes an ExtBot instance with the given bot_info that uses arbitrary callback_data""" diff --git a/tests/test_application.py b/tests/test_application.py index 8f67df79155..5af78fda0da 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -62,12 +62,6 @@ ) -@pytest.fixture(scope="function") -def one_time_bot(bot_info): - """A function scoped bot since the session bot would shutdown when `async with app` finishes""" - return make_bot(bot_info) - - class CustomContext(CallbackContext): pass From 38ca98789b820391f6bb987bae2da0601aa2caa1 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:00:54 +0530 Subject: [PATCH 74/77] add CSI comment about datetime test parametrization --- tests/test_datetime.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_datetime.py b/tests/test_datetime.py index 4076170c52b..1d7d0e19003 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -27,6 +27,9 @@ # sample time specification values categorised into absolute / delta / time-of-day from tests.conftest import TEST_WITH_OPT_DEPS +# We do not parametrize tests with these variables, since there's a tiny chance that there is an +# error while collecting the tests (happens when time goes from HH:59:00 -> HH+1:00:00) when we +# run the test suite with multiple workers DELTA_TIME_SPECS = [dtm.timedelta(hours=3, seconds=42, milliseconds=2), 30, 7.5] TIME_OF_DAY_TIME_SPECS = [ dtm.time(12, 42, tzinfo=dtm.timezone(dtm.timedelta(hours=-7))), @@ -96,6 +99,7 @@ def test_to_float_timestamp_absolute_no_reference(self): with pytest.raises(ValueError): tg_dtm.to_float_timestamp(dtm.datetime(2019, 11, 11), reference_timestamp=123) + # see note on parametrization at the top of this file def test_to_float_timestamp_delta(self): """Conversion from a 'delta' time specification to timestamp""" reference_t = 0 @@ -131,6 +135,7 @@ def test_to_float_timestamp_time_of_day_timezone(self, timezone): ref_t + (-utc_offset.total_seconds() % (24 * 60 * 60)) ) + # see note on parametrization at the top of this file def test_to_float_timestamp_default_reference(self): """The reference timestamp for relative time specifications should default to now""" for i in RELATIVE_TIME_SPECS: @@ -143,6 +148,7 @@ def test_to_float_timestamp_error(self): with pytest.raises(TypeError, match="Defaults"): tg_dtm.to_float_timestamp(Defaults()) + # see note on parametrization at the top of this file def test_to_timestamp(self): # delegate tests to `to_float_timestamp` for i in TIME_SPECS: From 5b45a0251e92d3150136acd943c74a97a5ed71ec Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:39:29 +0530 Subject: [PATCH 75/77] revert Experiment 1 --- tests/test_jobqueue.py | 137 +++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 89 deletions(-) diff --git a/tests/test_jobqueue.py b/tests/test_jobqueue.py index 48f9b4425d1..9376cbb1263 100644 --- a/tests/test_jobqueue.py +++ b/tests/test_jobqueue.py @@ -20,6 +20,8 @@ import calendar import datetime as dtm import logging +import os +import platform import time import pytest @@ -66,13 +68,15 @@ def test_init_job(self): @pytest.mark.skipif( not TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is installed" ) -# needed if we run pytest -n=number > no. of CPUs & since asyncio.Events aren't thread-safe. -@pytest.mark.flaky(4, 1) +@pytest.mark.skipif( + os.getenv("GITHUB_ACTIONS", False) and platform.system() in ["Windows", "Darwin"], + reason="On Windows & MacOS precise timings are not accurate.", +) +@pytest.mark.flaky(10, 1) # Timings aren't quite perfect class TestJobQueue: result = 0 job_time = 0 received_error = None - # we have 2 more variables which define in `reset` since it needs to be on the same event loop expected_warning = ( "Prior to v20.0 the `days` parameter was not aligned to that of cron's weekday scheme." @@ -84,30 +88,6 @@ def reset(self): self.result = 0 self.job_time = 0 self.received_error = None - self.done_with_cb = asyncio.Event() - self.done_with_err_cb = asyncio.Event() - - async def wait_for_cbs(self, number: int = 1): - async def _wait_for_cbs(): - for _ in range(number): - await self.done_with_cb.wait() - self.done_with_cb.clear() - - try: - await asyncio.wait_for(_wait_for_cbs(), 10) - except asyncio.TimeoutError: # just in case, don't want to hang the tests - pass - - async def wait_for_err_cbs(self, number: int = 1): - async def _wait_for_err_cbs(): - for _ in range(number): - await self.done_with_err_cb.wait() - self.done_with_err_cb.clear() - - try: - await asyncio.wait_for(_wait_for_err_cbs(), 10) - except asyncio.TimeoutError: # just in case, don't want to hang the tests - pass async def job_run_once(self, context): if ( @@ -119,30 +99,20 @@ async def job_run_once(self, context): and context.user_data is None and isinstance(context.bot_data, dict) ): - if not self.done_with_cb.is_set(): - self.result += 1 - self.done_with_cb.set() + self.result += 1 async def job_with_exception(self, context): - try: - raise Exception("Test Error") - finally: - if not self.done_with_err_cb.is_set(): - self.done_with_err_cb.set() + raise Exception("Test Error") async def job_remove_self(self, context): self.result += 1 context.job.schedule_removal() - self.done_with_cb.set() async def job_run_once_with_data(self, context): self.result += context.job.data - if not self.done_with_cb.is_set(): - self.done_with_cb.set() async def job_datetime_tests(self, context): self.job_time = time.time() - self.done_with_cb.set() async def error_handler_context(self, update, context): self.received_error = ( @@ -151,14 +121,9 @@ async def error_handler_context(self, update, context): context.user_data, context.chat_data, ) - self.done_with_cb.set() async def error_handler_raise_error(self, *args): - try: - raise Exception("Failing bigly") - finally: - if not self.done_with_cb.is_set(): - self.done_with_cb.set() + raise Exception("Failing bigly") def test_slot_behaviour(self, job_queue, mro_slots): for attr in job_queue.__slots__: @@ -178,7 +143,7 @@ def test_application_weakref(self, bot): async def test_run_once(self, job_queue): job_queue.run_once(self.job_run_once, 0.1) - await self.wait_for_cbs() + await asyncio.sleep(0.2) assert self.result == 1 async def test_run_once_timezone(self, job_queue, timezone): @@ -187,24 +152,24 @@ async def test_run_once_timezone(self, job_queue, timezone): # of an xpass when the test is run in a timezone with the same UTC offset when = dtm.datetime.now(timezone) job_queue.run_once(self.job_run_once, when) - await self.wait_for_cbs() + await asyncio.sleep(0.1) assert self.result == 1 async def test_job_with_data(self, job_queue): job_queue.run_once(self.job_run_once_with_data, 0.1, data=5) - await self.wait_for_cbs() + await asyncio.sleep(0.2) assert self.result == 5 async def test_run_repeating(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.1) - await self.wait_for_cbs(2) + await asyncio.sleep(0.25) assert self.result == 2 async def test_run_repeating_first(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.5, first=0.2) await asyncio.sleep(0.15) assert self.result == 0 - await self.wait_for_cbs() + await asyncio.sleep(0.1) assert self.result == 1 async def test_run_repeating_first_timezone(self, job_queue, timezone): @@ -212,23 +177,24 @@ async def test_run_repeating_first_timezone(self, job_queue, timezone): job_queue.run_repeating( self.job_run_once, 0.5, first=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.2) ) + await asyncio.sleep(0.05) assert self.result == 0 - await self.wait_for_cbs() + await asyncio.sleep(0.25) assert self.result == 1 async def test_run_repeating_last(self, job_queue): job_queue.run_repeating(self.job_run_once, 0.25, last=0.4) - await self.wait_for_cbs() - assert self.result == 1 await asyncio.sleep(0.3) assert self.result == 1 + await asyncio.sleep(0.4) + assert self.result == 1 async def test_run_repeating_last_timezone(self, job_queue, timezone): """Test correct scheduling of job when passing a timezone-aware datetime as ``last``""" job_queue.run_repeating( self.job_run_once, 0.25, last=dtm.datetime.now(timezone) + dtm.timedelta(seconds=0.4) ) - await self.wait_for_cbs() + await asyncio.sleep(0.3) assert self.result == 1 await asyncio.sleep(0.4) assert self.result == 1 @@ -239,19 +205,19 @@ async def test_run_repeating_last_before_first(self, job_queue): async def test_run_repeating_timedelta(self, job_queue): job_queue.run_repeating(self.job_run_once, dtm.timedelta(seconds=0.1)) - await self.wait_for_cbs(2) + await asyncio.sleep(0.25) assert self.result == 2 async def test_run_custom(self, job_queue): job_queue.run_custom(self.job_run_once, {"trigger": "interval", "seconds": 0.2}) - await self.wait_for_cbs(2) + await asyncio.sleep(0.5) assert self.result == 2 async def test_multiple(self, job_queue): job_queue.run_once(self.job_run_once, 0.1) job_queue.run_once(self.job_run_once, 0.2) job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(4) + await asyncio.sleep(0.55) assert self.result == 4 async def test_disabled(self, job_queue): @@ -267,15 +233,15 @@ async def test_disabled(self, job_queue): j1.enabled = True - await self.wait_for_cbs(1) + await asyncio.sleep(0.6) assert self.result == 1 async def test_schedule_removal(self, job_queue): - j1 = job_queue.run_once(self.job_run_once, 0.5) + j1 = job_queue.run_once(self.job_run_once, 0.3) j2 = job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(1) + await asyncio.sleep(0.25) assert self.result == 1 j1.schedule_removal() @@ -288,8 +254,7 @@ async def test_schedule_removal(self, job_queue): async def test_schedule_removal_from_within(self, job_queue): job_queue.run_repeating(self.job_remove_self, 0.1) - await self.wait_for_cbs(1) - await asyncio.sleep(0.3) + await asyncio.sleep(0.5) assert self.result == 1 @@ -297,15 +262,14 @@ async def test_longer_first(self, job_queue): job_queue.run_once(self.job_run_once, 0.2) job_queue.run_once(self.job_run_once, 0.1) - await self.wait_for_cbs(1) + await asyncio.sleep(0.15) assert self.result == 1 async def test_error(self, job_queue): job_queue.run_repeating(self.job_with_exception, 0.1) job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_err_cbs() - await self.wait_for_cbs() + await asyncio.sleep(0.3) assert self.result == 1 async def test_in_application(self, bot_info): @@ -316,7 +280,7 @@ async def test_in_application(self, bot_info): assert app.job_queue.scheduler.running app.job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(1) + await asyncio.sleep(0.3) assert self.result == 1 await app.stop() assert not app.job_queue.scheduler.running @@ -329,7 +293,7 @@ async def test_time_unit_int(self, job_queue): expected_time = time.time() + delta job_queue.run_once(self.job_datetime_tests, delta) - await self.wait_for_cbs() + await asyncio.sleep(0.6) assert pytest.approx(self.job_time) == expected_time async def test_time_unit_dt_timedelta(self, job_queue): @@ -339,7 +303,7 @@ async def test_time_unit_dt_timedelta(self, job_queue): expected_time = time.time() + interval.total_seconds() job_queue.run_once(self.job_datetime_tests, interval) - await self.wait_for_cbs() + await asyncio.sleep(0.6) assert pytest.approx(self.job_time) == expected_time async def test_time_unit_dt_datetime(self, job_queue): @@ -349,7 +313,7 @@ async def test_time_unit_dt_datetime(self, job_queue): expected_time = when.timestamp() job_queue.run_once(self.job_datetime_tests, when) - await self.wait_for_cbs() + await asyncio.sleep(0.6) assert self.job_time == pytest.approx(expected_time) async def test_time_unit_dt_time_today(self, job_queue): @@ -360,7 +324,7 @@ async def test_time_unit_dt_time_today(self, job_queue): expected_time = expected_time.timestamp() job_queue.run_once(self.job_datetime_tests, when) - await self.wait_for_cbs() + await asyncio.sleep(0.6) assert self.job_time == pytest.approx(expected_time) async def test_time_unit_dt_time_tomorrow(self, job_queue): @@ -380,7 +344,7 @@ async def test_run_daily(self, job_queue): expected_reschedule_time = (now + dtm.timedelta(seconds=delta, days=1)).timestamp() job_queue.run_daily(self.job_run_once, time_of_day) - await self.wait_for_cbs() + await asyncio.sleep(delta + 0.1) assert self.result == 1 scheduled_time = job_queue.jobs()[0].next_t.timestamp() assert scheduled_time == pytest.approx(expected_reschedule_time) @@ -437,7 +401,7 @@ async def test_run_monthly(self, job_queue, timezone): expected_reschedule_time = expected_reschedule_time.timestamp() job_queue.run_monthly(self.job_run_once, time_of_day, day) - await self.wait_for_cbs() + await asyncio.sleep(delta + 0.1) assert self.result == 1 scheduled_time = job_queue.jobs()[0].next_t.timestamp() assert scheduled_time == pytest.approx(expected_reschedule_time, rel=1e-3) @@ -470,7 +434,7 @@ async def test_default_tzinfo(self, tz_bot): when = dtm.datetime.now(tz_bot.defaults.tzinfo) + dtm.timedelta(seconds=0.1) jq.run_once(self.job_run_once, when.time()) - await self.wait_for_cbs() + await asyncio.sleep(0.15) assert self.result == 1 await jq.stop() @@ -498,20 +462,20 @@ async def test_job_run(self, app): async def test_enable_disable_job(self, job_queue): job = job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(2) + await asyncio.sleep(0.5) assert self.result == 2 job.enabled = False assert not job.enabled - await asyncio.sleep(0.25) + await asyncio.sleep(0.5) assert self.result == 2 job.enabled = True assert job.enabled - await self.wait_for_cbs(2) + await asyncio.sleep(0.5) assert self.result == 4 async def test_remove_job(self, job_queue): job = job_queue.run_repeating(self.job_run_once, 0.2) - await self.wait_for_cbs(2) + await asyncio.sleep(0.5) assert self.result == 2 assert not job.removed job.schedule_removal() @@ -538,8 +502,7 @@ async def test_process_error_context(self, job_queue, app): app.add_error_handler(self.error_handler_context) job = job_queue.run_once(self.job_with_exception, 0.1, chat_id=42, user_id=43) - await self.wait_for_err_cbs() - await self.wait_for_cbs() + await asyncio.sleep(0.15) assert self.received_error[0] == "Test Error" assert self.received_error[1] is job self.received_error = None @@ -554,7 +517,7 @@ async def test_process_error_context(self, job_queue, app): self.received_error = None job = job_queue.run_once(self.job_with_exception, 0.1) - await self.wait_for_err_cbs() + await asyncio.sleep(0.15) assert self.received_error is None await job.run(app) assert self.received_error is None @@ -564,8 +527,7 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.1) - await self.wait_for_err_cbs() - await self.wait_for_cbs() + await asyncio.sleep(0.15) assert len(caplog.records) == 1 rec = caplog.records[-1] assert "An error was raised and an uncaught" in rec.getMessage() @@ -573,7 +535,6 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): await job.run(app) - await self.wait_for_err_cbs() assert len(caplog.records) == 1 rec = caplog.records[-1] assert "uncaught error was raised while handling" in rec.getMessage() @@ -585,8 +546,7 @@ async def test_process_error_that_raises_errors(self, job_queue, app, caplog): with caplog.at_level(logging.ERROR): job = job_queue.run_once(self.job_with_exception, 0.1) - await self.wait_for_err_cbs() - await asyncio.sleep(0.1) # sleep for a bit so that caplog fixture registers an error + await asyncio.sleep(0.15) assert len(caplog.records) == 1 rec = caplog.records[-1] assert "No error handlers are registered" in rec.getMessage() @@ -618,10 +578,9 @@ async def callback(context): context.chat_data, type(context.bot_data), ) - self.done_with_cb.set() job_queue.run_once(callback, 0.1) - await self.wait_for_cbs() + await asyncio.sleep(0.15) assert self.result == (CustomContext, None, None, int) async def test_attribute_error(self): @@ -646,8 +605,8 @@ async def callback(_): if wait: assert not task.done() ready_event.set() - await task # no CancelledError here (see source code of JobQueue.stop for details) + await asyncio.sleep(0.1) # no CancelledError (see source of JobQueue.stop for details) assert task.done() else: - await task # unfortunately we will get a CancelledError here + await asyncio.sleep(0.1) # unfortunately we will get a CancelledError here assert task.done() From a3c4b03879b77ab0b82707689afe6d2b94fb13ba Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Sun, 5 Feb 2023 23:53:00 +0530 Subject: [PATCH 76/77] add csi comment in get_bot_user --- tests/conftest.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index a0f7203596a..4756931d252 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -187,6 +187,10 @@ async def mocked_get_me(bot: Bot): def get_bot_user(token: str) -> User: """Used to return a mock user in bot.get_me(). This saves API calls on every init.""" bot_info = BOT_INFO.get_info() + # We don't take token from bot_info, because we need to make a bot with a specific ID. So we + # generate the correct user_id from the token (token from bot_info is random each test run). + # This is important in e.g. bot equality tests. The other parameters like first_name don't + # matter as much. In the future we may provide a way to get all the correct info from the token user_id = int(token.split(":")[0]) first_name = bot_info.get("name") username = bot_info.get("username").strip("@") From 4d297215e27779e716a9c3ee1f65638d8e0644dd Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:14:43 +0530 Subject: [PATCH 77/77] Revert Experiment 2: tests are a bit too flaky specially on python 3.7. The xdist_group markers are kept so we can use them locally --- .github/workflows/test.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5a78db73902..1d042053a3e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -58,11 +58,10 @@ jobs: # Test the rest export TEST_WITH_OPT_DEPS='true' pip install -r requirements-opts.txt - # `-n auto --dist=loadgroup` uses pytest-xdist to run distribute each tests across - # available CPUs. Tests marked with `xdist_group` run in the same worker (in order). - # Increasing number of workers has little effect on test duration, but it seems to - # increase flakyness. - pytest -v --cov --cov-append -n auto --dist=loadgroup + # `-n auto --dist loadfile` uses pytest-xdist to run each test file on a different CPU + # worker. Increasing number of workers has little effect on test duration, but it seems + # to increase flakyness, specially on python 3.7 with --dist=loadgroup. + pytest -v --cov --cov-append -n auto --dist loadfile status=$(( $? > status ? $? : status)) exit ${status} env: