From b9d2efdec57b0e6b35868ff351d53457e2782f5f Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Tue, 3 Sep 2024 05:24:25 +0200 Subject: [PATCH 1/9] Rename Testing Base Classes (#4453) --- tests/_files/test_animation.py | 6 +- tests/_files/test_audio.py | 6 +- tests/_files/test_chatphoto.py | 4 +- tests/_files/test_contact.py | 14 +-- tests/_files/test_document.py | 6 +- tests/_files/test_file.py | 34 +++--- tests/_files/test_inputmedia.py | 110 +++++++++--------- tests/_files/test_inputsticker.py | 14 +-- tests/_files/test_location.py | 16 +-- tests/_files/test_photo.py | 6 +- tests/_files/test_sticker.py | 26 ++--- tests/_files/test_venue.py | 20 ++-- tests/_files/test_video.py | 6 +- tests/_files/test_videonote.py | 6 +- tests/_files/test_voice.py | 6 +- tests/_games/test_game.py | 16 +-- tests/_games/test_gamehighscore.py | 6 +- tests/_inline/test_inlinekeyboardbutton.py | 24 ++-- tests/_inline/test_inlinekeyboardmarkup.py | 8 +- tests/_inline/test_inlinequery.py | 14 +-- .../_inline/test_inlinequeryresultarticle.py | 24 ++-- tests/_inline/test_inlinequeryresultaudio.py | 24 ++-- .../test_inlinequeryresultcachedaudio.py | 18 +-- .../test_inlinequeryresultcacheddocument.py | 22 ++-- .../test_inlinequeryresultcachedgif.py | 22 ++-- .../test_inlinequeryresultcachedmpeg4gif.py | 22 ++-- .../test_inlinequeryresultcachedphoto.py | 24 ++-- .../test_inlinequeryresultcachedsticker.py | 12 +- .../test_inlinequeryresultcachedvideo.py | 24 ++-- .../test_inlinequeryresultcachedvoice.py | 20 ++-- .../_inline/test_inlinequeryresultcontact.py | 22 ++-- .../_inline/test_inlinequeryresultdocument.py | 30 ++--- tests/_inline/test_inlinequeryresultgame.py | 10 +- tests/_inline/test_inlinequeryresultgif.py | 32 ++--- .../_inline/test_inlinequeryresultlocation.py | 30 ++--- .../_inline/test_inlinequeryresultmpeg4gif.py | 32 ++--- tests/_inline/test_inlinequeryresultphoto.py | 30 ++--- tests/_inline/test_inlinequeryresultvenue.py | 32 ++--- tests/_inline/test_inlinequeryresultvideo.py | 34 +++--- tests/_inline/test_inlinequeryresultvoice.py | 22 ++-- .../test_inputcontactmessagecontent.py | 10 +- .../test_inputinvoicemessagecontent.py | 44 +++---- .../test_inputlocationmessagecontent.py | 16 +-- tests/_inline/test_inputtextmessagecontent.py | 12 +- .../_inline/test_inputvenuemessagecontent.py | 20 ++-- tests/_passport/test_encryptedcredentials.py | 10 +- .../test_encryptedpassportelement.py | 20 ++-- tests/_passport/test_passport.py | 4 +- .../test_passportelementerrordatafield.py | 12 +- .../test_passportelementerrorfile.py | 10 +- .../test_passportelementerrorfiles.py | 10 +- .../test_passportelementerrorfrontside.py | 10 +- .../test_passportelementerrorreverseside.py | 10 +- .../test_passportelementerrorselfie.py | 10 +- ...est_passportelementerrortranslationfile.py | 10 +- ...st_passportelementerrortranslationfiles.py | 10 +- .../test_passportelementerrorunspecified.py | 10 +- tests/_passport/test_passportfile.py | 12 +- tests/_payment/test_invoice.py | 16 +-- tests/_payment/test_labeledprice.py | 6 +- tests/_payment/test_orderinfo.py | 12 +- tests/_payment/test_precheckoutquery.py | 18 +-- tests/_payment/test_refundedpayment.py | 14 +-- tests/_payment/test_shippingaddress.py | 16 +-- tests/_payment/test_shippingoption.py | 6 +- tests/_payment/test_shippingquery.py | 12 +- tests/_payment/test_successfulpayment.py | 18 +-- tests/test_birthdate.py | 6 +- tests/test_botdescription.py | 10 +- tests/test_botname.py | 6 +- tests/test_business.py | 50 ++++---- tests/test_callbackquery.py | 22 ++-- tests/test_chat.py | 16 +-- tests/test_chatfullinfo.py | 82 ++++++------- tests/test_chatinvitelink.py | 24 ++-- tests/test_chatjoinrequest.py | 14 +-- tests/test_chatlocation.py | 6 +- tests/test_chatmemberupdated.py | 8 +- tests/test_chatpermissions.py | 4 +- tests/test_choseninlineresult.py | 6 +- tests/test_dice.py | 4 +- tests/test_forcereply.py | 8 +- tests/test_inlinequeryresultsbutton.py | 10 +- tests/test_keyboardbutton.py | 18 +-- tests/test_keyboardbuttonpolltype.py | 6 +- tests/test_keyboardbuttonrequest.py | 32 ++--- tests/test_linkpreviewoptions.py | 14 +-- tests/test_loginurl.py | 12 +- tests/test_maybeinaccessiblemessage.py | 10 +- tests/test_menubutton.py | 8 +- tests/test_message.py | 28 ++--- tests/test_messageentity.py | 4 +- tests/test_paidmedia.py | 24 ++-- tests/test_poll.py | 62 +++++----- tests/test_proximityalerttriggered.py | 10 +- tests/test_reply.py | 46 ++++---- tests/test_replykeyboardmarkup.py | 16 +-- tests/test_replykeyboardremove.py | 8 +- tests/test_sentwebappmessage.py | 6 +- tests/test_shared.py | 28 ++--- tests/test_stars.py | 26 ++--- tests/test_story.py | 6 +- tests/test_switchinlinequerychosenchat.py | 14 +-- tests/test_update.py | 6 +- tests/test_user.py | 56 ++++----- tests/test_userprofilephotos.py | 4 +- tests/test_webappdata.py | 6 +- tests/test_webappinfo.py | 6 +- tests/test_webhookinfo.py | 20 ++-- 109 files changed, 972 insertions(+), 972 deletions(-) diff --git a/tests/_files/test_animation.py b/tests/_files/test_animation.py index 5e991eabaa8..493d9bfae03 100644 --- a/tests/_files/test_animation.py +++ b/tests/_files/test_animation.py @@ -51,7 +51,7 @@ async def animation(bot, chat_id): ).animation -class TestAnimationBase: +class AnimationTestBase: animation_file_id = "CgADAQADngIAAuyVeEez0xRovKi9VAI" animation_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" width = 320 @@ -66,7 +66,7 @@ class TestAnimationBase: caption = "Test *animation*" -class TestAnimationWithoutRequest(TestAnimationBase): +class TestAnimationWithoutRequest(AnimationTestBase): def test_slot_behaviour(self, animation): for attr in animation.__slots__: assert getattr(animation, attr, "err") != "err", f"got extra slot '{attr}'" @@ -219,7 +219,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) -class TestAnimationWithRequest(TestAnimationBase): +class TestAnimationWithRequest(AnimationTestBase): 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/_files/test_audio.py b/tests/_files/test_audio.py index ced1a1d5d75..f6b76c1f0c9 100644 --- a/tests/_files/test_audio.py +++ b/tests/_files/test_audio.py @@ -49,7 +49,7 @@ async def audio(bot, chat_id): return (await bot.send_audio(chat_id, audio=f, read_timeout=50, thumbnail=thumb)).audio -class TestAudioBase: +class AudioTestBase: caption = "Test *audio*" performer = "Leandro Toledo" title = "Teste" @@ -67,7 +67,7 @@ class TestAudioBase: audio_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestAudioWithoutRequest(TestAudioBase): +class TestAudioWithoutRequest(AudioTestBase): def test_slot_behaviour(self, audio): for attr in audio.__slots__: assert getattr(audio, attr, "err") != "err", f"got extra slot '{attr}'" @@ -222,7 +222,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): await default_bot.send_audio(chat_id, audio, reply_parameters=ReplyParameters(**kwargs)) -class TestAudioWithRequest(TestAudioBase): +class TestAudioWithRequest(AudioTestBase): 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/_files/test_chatphoto.py b/tests/_files/test_chatphoto.py index 27f3a26ba39..5deaae38fb4 100644 --- a/tests/_files/test_chatphoto.py +++ b/tests/_files/test_chatphoto.py @@ -52,7 +52,7 @@ async def func(): ) -class TestChatPhotoBase: +class ChatPhotoTestBase: chatphoto_small_file_id = "smallCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_big_file_id = "bigCgADAQADngIAAuyVeEez0xRovKi9VAI" chatphoto_small_file_unique_id = "smalladc3145fd2e84d95b64d68eaa22aa33e" @@ -60,7 +60,7 @@ class TestChatPhotoBase: chatphoto_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.jpg" -class TestChatPhotoWithoutRequest(TestChatPhotoBase): +class TestChatPhotoWithoutRequest(ChatPhotoTestBase): def test_slot_behaviour(self, chat_photo): for attr in chat_photo.__slots__: assert getattr(chat_photo, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_files/test_contact.py b/tests/_files/test_contact.py index a4793c3faf5..cb5777eb4dd 100644 --- a/tests/_files/test_contact.py +++ b/tests/_files/test_contact.py @@ -32,21 +32,21 @@ @pytest.fixture(scope="module") def contact(): return Contact( - TestContactBase.phone_number, - TestContactBase.first_name, - TestContactBase.last_name, - TestContactBase.user_id, + ContactTestBase.phone_number, + ContactTestBase.first_name, + ContactTestBase.last_name, + ContactTestBase.user_id, ) -class TestContactBase: +class ContactTestBase: phone_number = "+11234567890" first_name = "Leandro" last_name = "Toledo" user_id = 23 -class TestContactWithoutRequest(TestContactBase): +class TestContactWithoutRequest(ContactTestBase): def test_slot_behaviour(self, contact): for attr in contact.__slots__: assert getattr(contact, attr, "err") != "err", f"got extra slot '{attr}'" @@ -156,7 +156,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) -class TestContactWithRequest(TestContactBase): +class TestContactWithRequest(ContactTestBase): @pytest.mark.parametrize( ("default_bot", "custom"), [ diff --git a/tests/_files/test_document.py b/tests/_files/test_document.py index 913e290f963..02f60ac464a 100644 --- a/tests/_files/test_document.py +++ b/tests/_files/test_document.py @@ -49,7 +49,7 @@ async def document(bot, chat_id): return (await bot.send_document(chat_id, document=f, read_timeout=50)).document -class TestDocumentBase: +class DocumentTestBase: caption = "DocumentTest - *Caption*" document_file_url = "https://python-telegram-bot.org/static/testfiles/telegram.gif" file_size = 12948 @@ -62,7 +62,7 @@ class TestDocumentBase: document_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestDocumentWithoutRequest(TestDocumentBase): +class TestDocumentWithoutRequest(DocumentTestBase): def test_slot_behaviour(self, document): for attr in document.__slots__: assert getattr(document, attr, "err") != "err", f"got extra slot '{attr}'" @@ -218,7 +218,7 @@ async def make_assertion(*_, **kwargs): assert await document.get_file() -class TestDocumentWithRequest(TestDocumentBase): +class TestDocumentWithRequest(DocumentTestBase): async def test_error_send_empty_file(self, bot, chat_id): with Path(os.devnull).open("rb") as f, pytest.raises(TelegramError): await bot.send_document(chat_id=chat_id, document=f) diff --git a/tests/_files/test_file.py b/tests/_files/test_file.py index 86979e4181c..ae9d92c0425 100644 --- a/tests/_files/test_file.py +++ b/tests/_files/test_file.py @@ -31,10 +31,10 @@ @pytest.fixture(scope="module") def file(bot): file = File( - TestFileBase.file_id, - TestFileBase.file_unique_id, - file_path=TestFileBase.file_path, - file_size=TestFileBase.file_size, + FileTestBase.file_id, + FileTestBase.file_unique_id, + file_path=FileTestBase.file_path, + file_size=FileTestBase.file_size, ) file.set_bot(bot) file._unfreeze() @@ -51,10 +51,10 @@ def encrypted_file(bot): "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) ef = File( - TestFileBase.file_id, - TestFileBase.file_unique_id, - TestFileBase.file_size, - TestFileBase.file_path, + FileTestBase.file_id, + FileTestBase.file_unique_id, + FileTestBase.file_size, + FileTestBase.file_path, ) ef.set_bot(bot) ef.set_credentials(fc) @@ -69,9 +69,9 @@ def encrypted_local_file(bot): "Pt7fKPgYWKA/7a8E64Ea1X8C+Wf7Ky1tF4ANBl63vl4=", ) ef = File( - TestFileBase.file_id, - TestFileBase.file_unique_id, - TestFileBase.file_size, + FileTestBase.file_id, + FileTestBase.file_unique_id, + FileTestBase.file_size, file_path=str(data_file("image_encrypted.jpg")), ) ef.set_bot(bot) @@ -82,16 +82,16 @@ def encrypted_local_file(bot): @pytest.fixture(scope="module") def local_file(bot): file = File( - TestFileBase.file_id, - TestFileBase.file_unique_id, + FileTestBase.file_id, + FileTestBase.file_unique_id, file_path=str(data_file("local_file.txt")), - file_size=TestFileBase.file_size, + file_size=FileTestBase.file_size, ) file.set_bot(bot) return file -class TestFileBase: +class FileTestBase: file_id = "NOTVALIDDOESNOTMATTER" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_path = ( @@ -101,7 +101,7 @@ class TestFileBase: file_content = "Saint-Saëns".encode() # Intentionally contains unicode chars. -class TestFileWithoutRequest(TestFileBase): +class TestFileWithoutRequest(FileTestBase): def test_slot_behaviour(self, file): for attr in file.__slots__: assert getattr(file, attr, "err") != "err", f"got extra slot '{attr}'" @@ -273,7 +273,7 @@ async def test(*args, **kwargs): assert buf2[: len(buf)] == buf -class TestFileWithRequest(TestFileBase): +class TestFileWithRequest(FileTestBase): async def test_error_get_empty_file_id(self, bot): with pytest.raises(TelegramError): await bot.get_file(file_id="") diff --git a/tests/_files/test_inputmedia.py b/tests/_files/test_inputmedia.py index d25a679ffc4..ff398113a48 100644 --- a/tests/_files/test_inputmedia.py +++ b/tests/_files/test_inputmedia.py @@ -68,94 +68,94 @@ @pytest.fixture(scope="module") def input_media_video(class_thumb_file): return InputMediaVideo( - 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, + media=InputMediaVideoTestBase.media, + caption=InputMediaVideoTestBase.caption, + width=InputMediaVideoTestBase.width, + height=InputMediaVideoTestBase.height, + duration=InputMediaVideoTestBase.duration, + parse_mode=InputMediaVideoTestBase.parse_mode, + caption_entities=InputMediaVideoTestBase.caption_entities, thumbnail=class_thumb_file, - supports_streaming=TestInputMediaVideoBase.supports_streaming, - has_spoiler=TestInputMediaVideoBase.has_spoiler, - show_caption_above_media=TestInputMediaVideoBase.show_caption_above_media, + supports_streaming=InputMediaVideoTestBase.supports_streaming, + has_spoiler=InputMediaVideoTestBase.has_spoiler, + show_caption_above_media=InputMediaVideoTestBase.show_caption_above_media, ) @pytest.fixture(scope="module") def input_media_photo(): return InputMediaPhoto( - media=TestInputMediaPhotoBase.media, - caption=TestInputMediaPhotoBase.caption, - parse_mode=TestInputMediaPhotoBase.parse_mode, - caption_entities=TestInputMediaPhotoBase.caption_entities, - has_spoiler=TestInputMediaPhotoBase.has_spoiler, - show_caption_above_media=TestInputMediaPhotoBase.show_caption_above_media, + media=InputMediaPhotoTestBase.media, + caption=InputMediaPhotoTestBase.caption, + parse_mode=InputMediaPhotoTestBase.parse_mode, + caption_entities=InputMediaPhotoTestBase.caption_entities, + has_spoiler=InputMediaPhotoTestBase.has_spoiler, + show_caption_above_media=InputMediaPhotoTestBase.show_caption_above_media, ) @pytest.fixture(scope="module") def input_media_animation(class_thumb_file): return InputMediaAnimation( - media=TestInputMediaAnimationBase.media, - caption=TestInputMediaAnimationBase.caption, - parse_mode=TestInputMediaAnimationBase.parse_mode, - caption_entities=TestInputMediaAnimationBase.caption_entities, - width=TestInputMediaAnimationBase.width, - height=TestInputMediaAnimationBase.height, + media=InputMediaAnimationTestBase.media, + caption=InputMediaAnimationTestBase.caption, + parse_mode=InputMediaAnimationTestBase.parse_mode, + caption_entities=InputMediaAnimationTestBase.caption_entities, + width=InputMediaAnimationTestBase.width, + height=InputMediaAnimationTestBase.height, thumbnail=class_thumb_file, - duration=TestInputMediaAnimationBase.duration, - has_spoiler=TestInputMediaAnimationBase.has_spoiler, - show_caption_above_media=TestInputMediaAnimationBase.show_caption_above_media, + duration=InputMediaAnimationTestBase.duration, + has_spoiler=InputMediaAnimationTestBase.has_spoiler, + show_caption_above_media=InputMediaAnimationTestBase.show_caption_above_media, ) @pytest.fixture(scope="module") def input_media_audio(class_thumb_file): return InputMediaAudio( - media=TestInputMediaAudioBase.media, - caption=TestInputMediaAudioBase.caption, - duration=TestInputMediaAudioBase.duration, - performer=TestInputMediaAudioBase.performer, - title=TestInputMediaAudioBase.title, + media=InputMediaAudioTestBase.media, + caption=InputMediaAudioTestBase.caption, + duration=InputMediaAudioTestBase.duration, + performer=InputMediaAudioTestBase.performer, + title=InputMediaAudioTestBase.title, thumbnail=class_thumb_file, - parse_mode=TestInputMediaAudioBase.parse_mode, - caption_entities=TestInputMediaAudioBase.caption_entities, + parse_mode=InputMediaAudioTestBase.parse_mode, + caption_entities=InputMediaAudioTestBase.caption_entities, ) @pytest.fixture(scope="module") def input_media_document(class_thumb_file): return InputMediaDocument( - media=TestInputMediaDocumentBase.media, - caption=TestInputMediaDocumentBase.caption, + media=InputMediaDocumentTestBase.media, + caption=InputMediaDocumentTestBase.caption, thumbnail=class_thumb_file, - parse_mode=TestInputMediaDocumentBase.parse_mode, - caption_entities=TestInputMediaDocumentBase.caption_entities, - disable_content_type_detection=TestInputMediaDocumentBase.disable_content_type_detection, + parse_mode=InputMediaDocumentTestBase.parse_mode, + caption_entities=InputMediaDocumentTestBase.caption_entities, + disable_content_type_detection=InputMediaDocumentTestBase.disable_content_type_detection, ) @pytest.fixture(scope="module") def input_paid_media_photo(): return InputPaidMediaPhoto( - media=TestInputMediaPhotoBase.media, + media=InputMediaPhotoTestBase.media, ) @pytest.fixture(scope="module") def input_paid_media_video(class_thumb_file): return InputPaidMediaVideo( - media=TestInputMediaVideoBase.media, + media=InputMediaVideoTestBase.media, thumbnail=class_thumb_file, - width=TestInputMediaVideoBase.width, - height=TestInputMediaVideoBase.height, - duration=TestInputMediaVideoBase.duration, - supports_streaming=TestInputMediaVideoBase.supports_streaming, + width=InputMediaVideoTestBase.width, + height=InputMediaVideoTestBase.height, + duration=InputMediaVideoTestBase.duration, + supports_streaming=InputMediaVideoTestBase.supports_streaming, ) -class TestInputMediaVideoBase: +class InputMediaVideoTestBase: type_ = "video" media = "NOTAREALFILEID" caption = "My Caption" @@ -169,7 +169,7 @@ class TestInputMediaVideoBase: show_caption_above_media = True -class TestInputMediaVideoWithoutRequest(TestInputMediaVideoBase): +class TestInputMediaVideoWithoutRequest(InputMediaVideoTestBase): def test_slot_behaviour(self, input_media_video): inst = input_media_video for attr in inst.__slots__: @@ -258,7 +258,7 @@ def test_type_enum_conversion(self): ) -class TestInputMediaPhotoBase: +class InputMediaPhotoTestBase: type_ = "photo" media = "NOTAREALFILEID" caption = "My Caption" @@ -268,7 +268,7 @@ class TestInputMediaPhotoBase: show_caption_above_media = True -class TestInputMediaPhotoWithoutRequest(TestInputMediaPhotoBase): +class TestInputMediaPhotoWithoutRequest(InputMediaPhotoTestBase): def test_slot_behaviour(self, input_media_photo): inst = input_media_photo for attr in inst.__slots__: @@ -322,7 +322,7 @@ def test_with_local_files(self): assert input_media_photo.media == data_file("telegram.mp4").as_uri() -class TestInputMediaAnimationBase: +class InputMediaAnimationTestBase: type_ = "animation" media = "NOTAREALFILEID" caption = "My Caption" @@ -335,7 +335,7 @@ class TestInputMediaAnimationBase: show_caption_above_media = True -class TestInputMediaAnimationWithoutRequest(TestInputMediaAnimationBase): +class TestInputMediaAnimationWithoutRequest(InputMediaAnimationTestBase): def test_slot_behaviour(self, input_media_animation): inst = input_media_animation for attr in inst.__slots__: @@ -396,7 +396,7 @@ def test_with_local_files(self): assert input_media_animation.thumbnail == data_file("telegram.jpg").as_uri() -class TestInputMediaAudioBase: +class InputMediaAudioTestBase: type_ = "audio" media = "NOTAREALFILEID" caption = "My Caption" @@ -407,7 +407,7 @@ class TestInputMediaAudioBase: caption_entities = [MessageEntity(MessageEntity.BOLD, 0, 2)] -class TestInputMediaAudioWithoutRequest(TestInputMediaAudioBase): +class TestInputMediaAudioWithoutRequest(InputMediaAudioTestBase): def test_slot_behaviour(self, input_media_audio): inst = input_media_audio for attr in inst.__slots__: @@ -467,7 +467,7 @@ def test_with_local_files(self): assert input_media_audio.thumbnail == data_file("telegram.jpg").as_uri() -class TestInputMediaDocumentBase: +class InputMediaDocumentTestBase: type_ = "document" media = "NOTAREALFILEID" caption = "My Caption" @@ -476,7 +476,7 @@ class TestInputMediaDocumentBase: disable_content_type_detection = True -class TestInputMediaDocumentWithoutRequest(TestInputMediaDocumentBase): +class TestInputMediaDocumentWithoutRequest(InputMediaDocumentTestBase): def test_slot_behaviour(self, input_media_document): inst = input_media_document for attr in inst.__slots__: @@ -535,7 +535,7 @@ def test_with_local_files(self): assert input_media_document.thumbnail == data_file("telegram.jpg").as_uri() -class TestInputPaidMediaPhotoWithoutRequest(TestInputMediaPhotoBase): +class TestInputPaidMediaPhotoWithoutRequest(InputMediaPhotoTestBase): def test_slot_behaviour(self, input_paid_media_photo): inst = input_paid_media_photo for attr in inst.__slots__: @@ -568,7 +568,7 @@ def test_with_local_files(self): assert input_paid_media_photo.media == data_file("telegram.jpg").as_uri() -class TestInputPaidMediaVideoWithoutRequest(TestInputMediaVideoBase): +class TestInputPaidMediaVideoWithoutRequest(InputMediaVideoTestBase): def test_slot_behaviour(self, input_paid_media_video): inst = input_paid_media_video for attr in inst.__slots__: diff --git a/tests/_files/test_inputsticker.py b/tests/_files/test_inputsticker.py index 680a0167099..bd45bbdea59 100644 --- a/tests/_files/test_inputsticker.py +++ b/tests/_files/test_inputsticker.py @@ -29,15 +29,15 @@ @pytest.fixture(scope="module") def input_sticker(): return InputSticker( - sticker=TestInputStickerBase.sticker, - emoji_list=TestInputStickerBase.emoji_list, - mask_position=TestInputStickerBase.mask_position, - keywords=TestInputStickerBase.keywords, - format=TestInputStickerBase.format, + sticker=InputStickerTestBase.sticker, + emoji_list=InputStickerTestBase.emoji_list, + mask_position=InputStickerTestBase.mask_position, + keywords=InputStickerTestBase.keywords, + format=InputStickerTestBase.format, ) -class TestInputStickerBase: +class InputStickerTestBase: sticker = "fake_file_id" emoji_list = ("👍", "👎") mask_position = MaskPosition("forehead", 0.5, 0.5, 0.5) @@ -45,7 +45,7 @@ class TestInputStickerBase: format = "static" -class TestInputStickerWithoutRequest(TestInputStickerBase): +class TestInputStickerWithoutRequest(InputStickerTestBase): def test_slot_behaviour(self, input_sticker): inst = input_sticker for attr in inst.__slots__: diff --git a/tests/_files/test_location.py b/tests/_files/test_location.py index f9a7e4c6ac6..72c6f720066 100644 --- a/tests/_files/test_location.py +++ b/tests/_files/test_location.py @@ -31,16 +31,16 @@ @pytest.fixture(scope="module") def location(): return Location( - 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, + latitude=LocationTestBase.latitude, + longitude=LocationTestBase.longitude, + horizontal_accuracy=LocationTestBase.horizontal_accuracy, + live_period=LocationTestBase.live_period, + heading=LocationTestBase.live_period, + proximity_alert_radius=LocationTestBase.proximity_alert_radius, ) -class TestLocationBase: +class LocationTestBase: latitude = -23.691288 longitude = -46.788279 horizontal_accuracy = 999 @@ -49,7 +49,7 @@ class TestLocationBase: proximity_alert_radius = 50 -class TestLocationWithoutRequest(TestLocationBase): +class TestLocationWithoutRequest(LocationTestBase): def test_slot_behaviour(self, location): for attr in location.__slots__: assert getattr(location, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_files/test_photo.py b/tests/_files/test_photo.py index 1d48bba868b..6ba9e46acc4 100644 --- a/tests/_files/test_photo.py +++ b/tests/_files/test_photo.py @@ -65,7 +65,7 @@ def photo(photolist): return photolist[-1] -class TestPhotoBase: +class PhotoTestBase: width = 800 height = 800 caption = "PhotoTest - *Caption*" @@ -75,7 +75,7 @@ class TestPhotoBase: file_size = [29176, 27662] -class TestPhotoWithoutRequest(TestPhotoBase): +class TestPhotoWithoutRequest(PhotoTestBase): def test_slot_behaviour(self, photo): for attr in photo.__slots__: assert getattr(photo, attr, "err") != "err", f"got extra slot '{attr}'" @@ -237,7 +237,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): await default_bot.send_photo(chat_id, photo, reply_parameters=ReplyParameters(**kwargs)) -class TestPhotoWithRequest(TestPhotoBase): +class TestPhotoWithRequest(PhotoTestBase): async def test_send_photo_all_args(self, bot, chat_id, photo_file): message = await bot.send_photo( chat_id, diff --git a/tests/_files/test_sticker.py b/tests/_files/test_sticker.py index a994325e1e9..3f374cc2ea0 100644 --- a/tests/_files/test_sticker.py +++ b/tests/_files/test_sticker.py @@ -61,7 +61,7 @@ async def sticker(bot, chat_id): sticker = (await bot.send_sticker(chat_id, sticker=f, read_timeout=50)).sticker # necessary to properly test needs_repainting with sticker._unfrozen(): - sticker.needs_repainting = TestStickerBase.needs_repainting + sticker.needs_repainting = StickerTestBase.needs_repainting return sticker @@ -89,7 +89,7 @@ def video_sticker(bot, chat_id): return bot.send_sticker(chat_id, sticker=f, timeout=50).sticker -class TestStickerBase: +class StickerTestBase: # 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 = ( @@ -116,7 +116,7 @@ class TestStickerBase: premium_animation = File("this_is_an_id", "this_is_an_unique_id") -class TestStickerWithoutRequest(TestStickerBase): +class TestStickerWithoutRequest(StickerTestBase): def test_slot_behaviour(self, sticker): for attr in sticker.__slots__: assert getattr(sticker, attr, "err") != "err", f"got extra slot '{attr}'" @@ -345,7 +345,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) -class TestStickerWithRequest(TestStickerBase): +class TestStickerWithRequest(StickerTestBase): 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 @@ -572,7 +572,7 @@ def sticker_set_thumb_file(): yield file -class TestStickerSetBase: +class StickerSetTestBase: title = "Test stickers" stickers = [Sticker("file_id", "file_un_id", 512, 512, True, True, Sticker.REGULAR)] name = "NOTAREALNAME" @@ -580,7 +580,7 @@ class TestStickerSetBase: contains_masks = True -class TestStickerSetWithoutRequest(TestStickerSetBase): +class TestStickerSetWithoutRequest(StickerSetTestBase): def test_slot_behaviour(self): inst = StickerSet("this", "is", self.stickers, "not") for attr in inst.__slots__: @@ -1064,21 +1064,21 @@ async def test_bot_methods_8_png(self, bot, sticker_set, sticker_file): @pytest.fixture(scope="module") def mask_position(): return MaskPosition( - TestMaskPositionBase.point, - TestMaskPositionBase.x_shift, - TestMaskPositionBase.y_shift, - TestMaskPositionBase.scale, + MaskPositionTestBase.point, + MaskPositionTestBase.x_shift, + MaskPositionTestBase.y_shift, + MaskPositionTestBase.scale, ) -class TestMaskPositionBase: +class MaskPositionTestBase: point = MaskPosition.EYES x_shift = -1 y_shift = 1 scale = 2 -class TestMaskPositionWithoutRequest(TestMaskPositionBase): +class TestMaskPositionWithoutRequest(MaskPositionTestBase): def test_slot_behaviour(self, mask_position): inst = mask_position for attr in inst.__slots__: @@ -1130,7 +1130,7 @@ def test_equality(self): assert hash(a) != hash(e) -class TestMaskPositionWithRequest(TestMaskPositionBase): +class TestMaskPositionWithRequest(MaskPositionTestBase): async def test_create_new_mask_sticker_set(self, bot, chat_id, sticker_file, mask_position): name = f"masks_by_{bot.username}" try: diff --git a/tests/_files/test_venue.py b/tests/_files/test_venue.py index 0cb8f500b50..b78223bbf5d 100644 --- a/tests/_files/test_venue.py +++ b/tests/_files/test_venue.py @@ -31,17 +31,17 @@ @pytest.fixture(scope="module") def venue(): return Venue( - 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, + VenueTestBase.location, + VenueTestBase.title, + VenueTestBase.address, + foursquare_id=VenueTestBase.foursquare_id, + foursquare_type=VenueTestBase.foursquare_type, + google_place_id=VenueTestBase.google_place_id, + google_place_type=VenueTestBase.google_place_type, ) -class TestVenueBase: +class VenueTestBase: location = Location(longitude=-46.788279, latitude=-23.691288) title = "title" address = "address" @@ -51,7 +51,7 @@ class TestVenueBase: google_place_type = "google place type" -class TestVenueWithoutRequest(TestVenueBase): +class TestVenueWithoutRequest(VenueTestBase): def test_slot_behaviour(self, venue): for attr in venue.__slots__: assert getattr(venue, attr, "err") != "err", f"got extra slot '{attr}'" @@ -171,7 +171,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) -class TestVenueWithRequest(TestVenueBase): +class TestVenueWithRequest(VenueTestBase): @pytest.mark.parametrize( ("default_bot", "custom"), [ diff --git a/tests/_files/test_video.py b/tests/_files/test_video.py index 29a80930fda..06666ea16b6 100644 --- a/tests/_files/test_video.py +++ b/tests/_files/test_video.py @@ -49,7 +49,7 @@ async def video(bot, chat_id): return (await bot.send_video(chat_id, video=f, read_timeout=50)).video -class TestVideoBase: +class VideoTestBase: width = 360 height = 640 duration = 5 @@ -66,7 +66,7 @@ class TestVideoBase: video_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoWithoutRequest(TestVideoBase): +class TestVideoWithoutRequest(VideoTestBase): def test_slot_behaviour(self, video): for attr in video.__slots__: assert getattr(video, attr, "err") != "err", f"got extra slot '{attr}'" @@ -229,7 +229,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): await default_bot.send_video(chat_id, video, reply_parameters=ReplyParameters(**kwargs)) -class TestVideoWithRequest(TestVideoBase): +class TestVideoWithRequest(VideoTestBase): 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/_files/test_videonote.py b/tests/_files/test_videonote.py index 5f07936ca50..b86355e446d 100644 --- a/tests/_files/test_videonote.py +++ b/tests/_files/test_videonote.py @@ -48,7 +48,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 TestVideoNoteBase: +class VideoNoteTestBase: length = 240 duration = 3 file_size = 132084 @@ -60,7 +60,7 @@ class TestVideoNoteBase: videonote_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVideoNoteWithoutRequest(TestVideoNoteBase): +class TestVideoNoteWithoutRequest(VideoNoteTestBase): def test_slot_behaviour(self, video_note): for attr in video_note.__slots__: assert getattr(video_note, attr, "err") != "err", f"got extra slot '{attr}'" @@ -218,7 +218,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) -class TestVideoNoteWithRequest(TestVideoNoteBase): +class TestVideoNoteWithRequest(VideoNoteTestBase): 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/_files/test_voice.py b/tests/_files/test_voice.py index 0c92b53902b..454db0aaef4 100644 --- a/tests/_files/test_voice.py +++ b/tests/_files/test_voice.py @@ -49,7 +49,7 @@ async def voice(bot, chat_id): return (await bot.send_voice(chat_id, voice=f, read_timeout=50)).voice -class TestVoiceBase: +class VoiceTestBase: duration = 3 mime_type = "audio/ogg" file_size = 9199 @@ -59,7 +59,7 @@ class TestVoiceBase: voice_file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" -class TestVoiceWithoutRequest(TestVoiceBase): +class TestVoiceWithoutRequest(VoiceTestBase): def test_slot_behaviour(self, voice): for attr in voice.__slots__: assert getattr(voice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -203,7 +203,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): await default_bot.send_voice(chat_id, voice, reply_parameters=ReplyParameters(**kwargs)) -class TestVoiceWithRequest(TestVoiceBase): +class TestVoiceWithRequest(VoiceTestBase): async def test_send_all_args(self, bot, chat_id, voice_file, voice): message = await bot.send_voice( chat_id, diff --git a/tests/_games/test_game.py b/tests/_games/test_game.py index 49067a8009a..23e0d5e9cea 100644 --- a/tests/_games/test_game.py +++ b/tests/_games/test_game.py @@ -26,18 +26,18 @@ @pytest.fixture(scope="module") def game(): game = Game( - TestGameBase.title, - TestGameBase.description, - TestGameBase.photo, - text=TestGameBase.text, - text_entities=TestGameBase.text_entities, - animation=TestGameBase.animation, + GameTestBase.title, + GameTestBase.description, + GameTestBase.photo, + text=GameTestBase.text, + text_entities=GameTestBase.text_entities, + animation=GameTestBase.animation, ) game._unfreeze() return game -class TestGameBase: +class GameTestBase: title = "Python-telegram-bot Test Game" description = "description" photo = [PhotoSize("Blah", "ElseBlah", 640, 360, file_size=0)] @@ -49,7 +49,7 @@ class TestGameBase: animation = Animation("blah", "unique_id", 320, 180, 1) -class TestGameWithoutRequest(TestGameBase): +class TestGameWithoutRequest(GameTestBase): def test_slot_behaviour(self, game): for attr in game.__slots__: assert getattr(game, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_games/test_gamehighscore.py b/tests/_games/test_gamehighscore.py index 02738be2123..fc76867b499 100644 --- a/tests/_games/test_gamehighscore.py +++ b/tests/_games/test_gamehighscore.py @@ -26,17 +26,17 @@ @pytest.fixture(scope="module") def game_highscore(): return GameHighScore( - TestGameHighScoreBase.position, TestGameHighScoreBase.user, TestGameHighScoreBase.score + GameHighScoreTestBase.position, GameHighScoreTestBase.user, GameHighScoreTestBase.score ) -class TestGameHighScoreBase: +class GameHighScoreTestBase: position = 12 user = User(2, "test user", False) score = 42 -class TestGameHighScoreWithoutRequest(TestGameHighScoreBase): +class TestGameHighScoreWithoutRequest(GameHighScoreTestBase): def test_slot_behaviour(self, game_highscore): for attr in game_highscore.__slots__: assert getattr(game_highscore, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_inline/test_inlinekeyboardbutton.py b/tests/_inline/test_inlinekeyboardbutton.py index 9eb1eff49cf..2569a8902ea 100644 --- a/tests/_inline/test_inlinekeyboardbutton.py +++ b/tests/_inline/test_inlinekeyboardbutton.py @@ -32,24 +32,24 @@ @pytest.fixture(scope="module") def inline_keyboard_button(): return InlineKeyboardButton( - TestInlineKeyboardButtonBase.text, - url=TestInlineKeyboardButtonBase.url, - callback_data=TestInlineKeyboardButtonBase.callback_data, - switch_inline_query=TestInlineKeyboardButtonBase.switch_inline_query, + InlineKeyboardButtonTestBase.text, + url=InlineKeyboardButtonTestBase.url, + callback_data=InlineKeyboardButtonTestBase.callback_data, + switch_inline_query=InlineKeyboardButtonTestBase.switch_inline_query, switch_inline_query_current_chat=( - TestInlineKeyboardButtonBase.switch_inline_query_current_chat + InlineKeyboardButtonTestBase.switch_inline_query_current_chat ), - callback_game=TestInlineKeyboardButtonBase.callback_game, - pay=TestInlineKeyboardButtonBase.pay, - login_url=TestInlineKeyboardButtonBase.login_url, - web_app=TestInlineKeyboardButtonBase.web_app, + callback_game=InlineKeyboardButtonTestBase.callback_game, + pay=InlineKeyboardButtonTestBase.pay, + login_url=InlineKeyboardButtonTestBase.login_url, + web_app=InlineKeyboardButtonTestBase.web_app, switch_inline_query_chosen_chat=( - TestInlineKeyboardButtonBase.switch_inline_query_chosen_chat + InlineKeyboardButtonTestBase.switch_inline_query_chosen_chat ), ) -class TestInlineKeyboardButtonBase: +class InlineKeyboardButtonTestBase: text = "text" url = "url" callback_data = "callback data" @@ -62,7 +62,7 @@ class TestInlineKeyboardButtonBase: switch_inline_query_chosen_chat = SwitchInlineQueryChosenChat("a_bot", True, False, True, True) -class TestInlineKeyboardButtonWithoutRequest(TestInlineKeyboardButtonBase): +class TestInlineKeyboardButtonWithoutRequest(InlineKeyboardButtonTestBase): def test_slot_behaviour(self, inline_keyboard_button): inst = inline_keyboard_button for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinekeyboardmarkup.py b/tests/_inline/test_inlinekeyboardmarkup.py index d7e8700dd6d..2f5bd2a5adf 100644 --- a/tests/_inline/test_inlinekeyboardmarkup.py +++ b/tests/_inline/test_inlinekeyboardmarkup.py @@ -31,10 +31,10 @@ @pytest.fixture(scope="module") def inline_keyboard_markup(): - return InlineKeyboardMarkup(TestInlineKeyboardMarkupBase.inline_keyboard) + return InlineKeyboardMarkup(InlineKeyboardMarkupTestBase.inline_keyboard) -class TestInlineKeyboardMarkupBase: +class InlineKeyboardMarkupTestBase: inline_keyboard = [ [ InlineKeyboardButton(text="button1", callback_data="data1"), @@ -43,7 +43,7 @@ class TestInlineKeyboardMarkupBase: ] -class TestInlineKeyboardMarkupWithoutRequest(TestInlineKeyboardMarkupBase): +class TestInlineKeyboardMarkupWithoutRequest(InlineKeyboardMarkupTestBase): def test_slot_behaviour(self, inline_keyboard_markup): inst = inline_keyboard_markup for attr in inst.__slots__: @@ -228,7 +228,7 @@ async def make_assertion( await bot.send_message(123, "test", reply_markup=inline_keyboard_markup) -class TestInlineKeyborardMarkupWithRequest(TestInlineKeyboardMarkupBase): +class TestInlineKeyborardMarkupWithRequest(InlineKeyboardMarkupTestBase): async def test_send_message_with_inline_keyboard_markup( self, bot, chat_id, inline_keyboard_markup ): diff --git a/tests/_inline/test_inlinequery.py b/tests/_inline/test_inlinequery.py index e5c8562c528..4d2e73ffb87 100644 --- a/tests/_inline/test_inlinequery.py +++ b/tests/_inline/test_inlinequery.py @@ -31,17 +31,17 @@ @pytest.fixture(scope="module") def inline_query(bot): ilq = InlineQuery( - TestInlineQueryBase.id_, - TestInlineQueryBase.from_user, - TestInlineQueryBase.query, - TestInlineQueryBase.offset, - location=TestInlineQueryBase.location, + InlineQueryTestBase.id_, + InlineQueryTestBase.from_user, + InlineQueryTestBase.query, + InlineQueryTestBase.offset, + location=InlineQueryTestBase.location, ) ilq.set_bot(bot) return ilq -class TestInlineQueryBase: +class InlineQueryTestBase: id_ = 1234 from_user = User(1, "First name", False) query = "query text" @@ -49,7 +49,7 @@ class TestInlineQueryBase: location = Location(8.8, 53.1) -class TestInlineQueryWithoutRequest(TestInlineQueryBase): +class TestInlineQueryWithoutRequest(InlineQueryTestBase): def test_slot_behaviour(self, inline_query): for attr in inline_query.__slots__: assert getattr(inline_query, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_inline/test_inlinequeryresultarticle.py b/tests/_inline/test_inlinequeryresultarticle.py index 4bc56c92d80..0692c425d0a 100644 --- a/tests/_inline/test_inlinequeryresultarticle.py +++ b/tests/_inline/test_inlinequeryresultarticle.py @@ -34,20 +34,20 @@ @pytest.fixture(scope="module") def inline_query_result_article(): return InlineQueryResultArticle( - 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, - thumbnail_url=TestInlineQueryResultArticleBase.thumbnail_url, - thumbnail_height=TestInlineQueryResultArticleBase.thumbnail_height, - thumbnail_width=TestInlineQueryResultArticleBase.thumbnail_width, + InlineQueryResultArticleTestBase.id_, + InlineQueryResultArticleTestBase.title, + input_message_content=InlineQueryResultArticleTestBase.input_message_content, + reply_markup=InlineQueryResultArticleTestBase.reply_markup, + url=InlineQueryResultArticleTestBase.url, + hide_url=InlineQueryResultArticleTestBase.hide_url, + description=InlineQueryResultArticleTestBase.description, + thumbnail_url=InlineQueryResultArticleTestBase.thumbnail_url, + thumbnail_height=InlineQueryResultArticleTestBase.thumbnail_height, + thumbnail_width=InlineQueryResultArticleTestBase.thumbnail_width, ) -class TestInlineQueryResultArticleBase: +class InlineQueryResultArticleTestBase: id_ = "id" type_ = "article" title = "title" @@ -61,7 +61,7 @@ class TestInlineQueryResultArticleBase: thumbnail_width = 15 -class TestInlineQueryResultArticleWithoutRequest(TestInlineQueryResultArticleBase): +class TestInlineQueryResultArticleWithoutRequest(InlineQueryResultArticleTestBase): def test_slot_behaviour(self, inline_query_result_article): inst = inline_query_result_article for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultaudio.py b/tests/_inline/test_inlinequeryresultaudio.py index 33542787ed8..251b3f6a41e 100644 --- a/tests/_inline/test_inlinequeryresultaudio.py +++ b/tests/_inline/test_inlinequeryresultaudio.py @@ -33,20 +33,20 @@ @pytest.fixture(scope="module") def inline_query_result_audio(): return InlineQueryResultAudio( - 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, + InlineQueryResultAudioTestBase.id_, + InlineQueryResultAudioTestBase.audio_url, + InlineQueryResultAudioTestBase.title, + performer=InlineQueryResultAudioTestBase.performer, + audio_duration=InlineQueryResultAudioTestBase.audio_duration, + caption=InlineQueryResultAudioTestBase.caption, + parse_mode=InlineQueryResultAudioTestBase.parse_mode, + caption_entities=InlineQueryResultAudioTestBase.caption_entities, + input_message_content=InlineQueryResultAudioTestBase.input_message_content, + reply_markup=InlineQueryResultAudioTestBase.reply_markup, ) -class TestInlineQueryResultAudioBase: +class InlineQueryResultAudioTestBase: id_ = "id" type_ = "audio" audio_url = "audio url" @@ -60,7 +60,7 @@ class TestInlineQueryResultAudioBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultAudioWithoutRequest(TestInlineQueryResultAudioBase): +class TestInlineQueryResultAudioWithoutRequest(InlineQueryResultAudioTestBase): def test_slot_behaviour(self, inline_query_result_audio): inst = inline_query_result_audio for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedaudio.py b/tests/_inline/test_inlinequeryresultcachedaudio.py index efa0cb06e27..363580bd615 100644 --- a/tests/_inline/test_inlinequeryresultcachedaudio.py +++ b/tests/_inline/test_inlinequeryresultcachedaudio.py @@ -33,17 +33,17 @@ @pytest.fixture(scope="module") def inline_query_result_cached_audio(): return InlineQueryResultCachedAudio( - 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, + InlineQueryResultCachedAudioTestBase.id_, + InlineQueryResultCachedAudioTestBase.audio_file_id, + caption=InlineQueryResultCachedAudioTestBase.caption, + parse_mode=InlineQueryResultCachedAudioTestBase.parse_mode, + caption_entities=InlineQueryResultCachedAudioTestBase.caption_entities, + input_message_content=InlineQueryResultCachedAudioTestBase.input_message_content, + reply_markup=InlineQueryResultCachedAudioTestBase.reply_markup, ) -class TestInlineQueryResultCachedAudioBase: +class InlineQueryResultCachedAudioTestBase: id_ = "id" type_ = "audio" audio_file_id = "audio file id" @@ -54,7 +54,7 @@ class TestInlineQueryResultCachedAudioBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedAudioWithoutRequest(TestInlineQueryResultCachedAudioBase): +class TestInlineQueryResultCachedAudioWithoutRequest(InlineQueryResultCachedAudioTestBase): def test_slot_behaviour(self, inline_query_result_cached_audio): inst = inline_query_result_cached_audio for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcacheddocument.py b/tests/_inline/test_inlinequeryresultcacheddocument.py index 48c9eef252b..c3d6a19ac3f 100644 --- a/tests/_inline/test_inlinequeryresultcacheddocument.py +++ b/tests/_inline/test_inlinequeryresultcacheddocument.py @@ -33,19 +33,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_document(): return InlineQueryResultCachedDocument( - 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, + InlineQueryResultCachedDocumentTestBase.id_, + InlineQueryResultCachedDocumentTestBase.title, + InlineQueryResultCachedDocumentTestBase.document_file_id, + caption=InlineQueryResultCachedDocumentTestBase.caption, + parse_mode=InlineQueryResultCachedDocumentTestBase.parse_mode, + caption_entities=InlineQueryResultCachedDocumentTestBase.caption_entities, + description=InlineQueryResultCachedDocumentTestBase.description, + input_message_content=InlineQueryResultCachedDocumentTestBase.input_message_content, + reply_markup=InlineQueryResultCachedDocumentTestBase.reply_markup, ) -class TestInlineQueryResultCachedDocumentBase: +class InlineQueryResultCachedDocumentTestBase: id_ = "id" type_ = "document" document_file_id = "document file id" @@ -58,7 +58,7 @@ class TestInlineQueryResultCachedDocumentBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedDocumentWithoutRequest(TestInlineQueryResultCachedDocumentBase): +class TestInlineQueryResultCachedDocumentWithoutRequest(InlineQueryResultCachedDocumentTestBase): def test_slot_behaviour(self, inline_query_result_cached_document): inst = inline_query_result_cached_document for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedgif.py b/tests/_inline/test_inlinequeryresultcachedgif.py index 62b908a631f..8128dc7b6b0 100644 --- a/tests/_inline/test_inlinequeryresultcachedgif.py +++ b/tests/_inline/test_inlinequeryresultcachedgif.py @@ -32,19 +32,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_gif(): return InlineQueryResultCachedGif( - 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, - show_caption_above_media=TestInlineQueryResultCachedGifBase.show_caption_above_media, + InlineQueryResultCachedGifTestBase.id_, + InlineQueryResultCachedGifTestBase.gif_file_id, + title=InlineQueryResultCachedGifTestBase.title, + caption=InlineQueryResultCachedGifTestBase.caption, + parse_mode=InlineQueryResultCachedGifTestBase.parse_mode, + caption_entities=InlineQueryResultCachedGifTestBase.caption_entities, + input_message_content=InlineQueryResultCachedGifTestBase.input_message_content, + reply_markup=InlineQueryResultCachedGifTestBase.reply_markup, + show_caption_above_media=InlineQueryResultCachedGifTestBase.show_caption_above_media, ) -class TestInlineQueryResultCachedGifBase: +class InlineQueryResultCachedGifTestBase: id_ = "id" type_ = "gif" gif_file_id = "gif file id" @@ -57,7 +57,7 @@ class TestInlineQueryResultCachedGifBase: show_caption_above_media = True -class TestInlineQueryResultCachedGifWithoutRequest(TestInlineQueryResultCachedGifBase): +class TestInlineQueryResultCachedGifWithoutRequest(InlineQueryResultCachedGifTestBase): def test_slot_behaviour(self, inline_query_result_cached_gif): inst = inline_query_result_cached_gif for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedmpeg4gif.py b/tests/_inline/test_inlinequeryresultcachedmpeg4gif.py index 3d4b5d3ca5b..fb1db70ceae 100644 --- a/tests/_inline/test_inlinequeryresultcachedmpeg4gif.py +++ b/tests/_inline/test_inlinequeryresultcachedmpeg4gif.py @@ -32,19 +32,19 @@ @pytest.fixture(scope="module") def inline_query_result_cached_mpeg4_gif(): return InlineQueryResultCachedMpeg4Gif( - 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, - show_caption_above_media=TestInlineQueryResultCachedMpeg4GifBase.show_caption_above_media, + InlineQueryResultCachedMpeg4GifTestBase.id_, + InlineQueryResultCachedMpeg4GifTestBase.mpeg4_file_id, + title=InlineQueryResultCachedMpeg4GifTestBase.title, + caption=InlineQueryResultCachedMpeg4GifTestBase.caption, + parse_mode=InlineQueryResultCachedMpeg4GifTestBase.parse_mode, + caption_entities=InlineQueryResultCachedMpeg4GifTestBase.caption_entities, + input_message_content=InlineQueryResultCachedMpeg4GifTestBase.input_message_content, + reply_markup=InlineQueryResultCachedMpeg4GifTestBase.reply_markup, + show_caption_above_media=InlineQueryResultCachedMpeg4GifTestBase.show_caption_above_media, ) -class TestInlineQueryResultCachedMpeg4GifBase: +class InlineQueryResultCachedMpeg4GifTestBase: id_ = "id" type_ = "mpeg4_gif" mpeg4_file_id = "mpeg4 file id" @@ -57,7 +57,7 @@ class TestInlineQueryResultCachedMpeg4GifBase: show_caption_above_media = True -class TestInlineQueryResultCachedMpeg4GifWithoutRequest(TestInlineQueryResultCachedMpeg4GifBase): +class TestInlineQueryResultCachedMpeg4GifWithoutRequest(InlineQueryResultCachedMpeg4GifTestBase): def test_slot_behaviour(self, inline_query_result_cached_mpeg4_gif): inst = inline_query_result_cached_mpeg4_gif for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedphoto.py b/tests/_inline/test_inlinequeryresultcachedphoto.py index b5ed6153b91..e3159acf3aa 100644 --- a/tests/_inline/test_inlinequeryresultcachedphoto.py +++ b/tests/_inline/test_inlinequeryresultcachedphoto.py @@ -32,20 +32,20 @@ @pytest.fixture(scope="module") def inline_query_result_cached_photo(): return InlineQueryResultCachedPhoto( - 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, - show_caption_above_media=TestInlineQueryResultCachedPhotoBase.show_caption_above_media, + InlineQueryResultCachedPhotoTestBase.id_, + InlineQueryResultCachedPhotoTestBase.photo_file_id, + title=InlineQueryResultCachedPhotoTestBase.title, + description=InlineQueryResultCachedPhotoTestBase.description, + caption=InlineQueryResultCachedPhotoTestBase.caption, + parse_mode=InlineQueryResultCachedPhotoTestBase.parse_mode, + caption_entities=InlineQueryResultCachedPhotoTestBase.caption_entities, + input_message_content=InlineQueryResultCachedPhotoTestBase.input_message_content, + reply_markup=InlineQueryResultCachedPhotoTestBase.reply_markup, + show_caption_above_media=InlineQueryResultCachedPhotoTestBase.show_caption_above_media, ) -class TestInlineQueryResultCachedPhotoBase: +class InlineQueryResultCachedPhotoTestBase: id_ = "id" type_ = "photo" photo_file_id = "photo file id" @@ -59,7 +59,7 @@ class TestInlineQueryResultCachedPhotoBase: show_caption_above_media = True -class TestInlineQueryResultCachedPhotoWithoutRequest(TestInlineQueryResultCachedPhotoBase): +class TestInlineQueryResultCachedPhotoWithoutRequest(InlineQueryResultCachedPhotoTestBase): def test_slot_behaviour(self, inline_query_result_cached_photo): inst = inline_query_result_cached_photo for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedsticker.py b/tests/_inline/test_inlinequeryresultcachedsticker.py index 63b7f2425fd..ee4d5e3e8d1 100644 --- a/tests/_inline/test_inlinequeryresultcachedsticker.py +++ b/tests/_inline/test_inlinequeryresultcachedsticker.py @@ -31,14 +31,14 @@ @pytest.fixture(scope="module") def inline_query_result_cached_sticker(): return InlineQueryResultCachedSticker( - TestInlineQueryResultCachedStickerBase.id_, - TestInlineQueryResultCachedStickerBase.sticker_file_id, - input_message_content=TestInlineQueryResultCachedStickerBase.input_message_content, - reply_markup=TestInlineQueryResultCachedStickerBase.reply_markup, + InlineQueryResultCachedStickerTestBase.id_, + InlineQueryResultCachedStickerTestBase.sticker_file_id, + input_message_content=InlineQueryResultCachedStickerTestBase.input_message_content, + reply_markup=InlineQueryResultCachedStickerTestBase.reply_markup, ) -class TestInlineQueryResultCachedStickerBase: +class InlineQueryResultCachedStickerTestBase: id_ = "id" type_ = "sticker" sticker_file_id = "sticker file id" @@ -46,7 +46,7 @@ class TestInlineQueryResultCachedStickerBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedStickerWithoutRequest(TestInlineQueryResultCachedStickerBase): +class TestInlineQueryResultCachedStickerWithoutRequest(InlineQueryResultCachedStickerTestBase): def test_slot_behaviour(self, inline_query_result_cached_sticker): inst = inline_query_result_cached_sticker for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedvideo.py b/tests/_inline/test_inlinequeryresultcachedvideo.py index d520b3c7c10..efd0f624de3 100644 --- a/tests/_inline/test_inlinequeryresultcachedvideo.py +++ b/tests/_inline/test_inlinequeryresultcachedvideo.py @@ -32,20 +32,20 @@ @pytest.fixture(scope="module") def inline_query_result_cached_video(): return InlineQueryResultCachedVideo( - 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, - show_caption_above_media=TestInlineQueryResultCachedVideoBase.show_caption_above_media, + InlineQueryResultCachedVideoTestBase.id_, + InlineQueryResultCachedVideoTestBase.video_file_id, + InlineQueryResultCachedVideoTestBase.title, + caption=InlineQueryResultCachedVideoTestBase.caption, + parse_mode=InlineQueryResultCachedVideoTestBase.parse_mode, + caption_entities=InlineQueryResultCachedVideoTestBase.caption_entities, + description=InlineQueryResultCachedVideoTestBase.description, + input_message_content=InlineQueryResultCachedVideoTestBase.input_message_content, + reply_markup=InlineQueryResultCachedVideoTestBase.reply_markup, + show_caption_above_media=InlineQueryResultCachedVideoTestBase.show_caption_above_media, ) -class TestInlineQueryResultCachedVideoBase: +class InlineQueryResultCachedVideoTestBase: id_ = "id" type_ = "video" video_file_id = "video file id" @@ -59,7 +59,7 @@ class TestInlineQueryResultCachedVideoBase: show_caption_above_media = True -class TestInlineQueryResultCachedVideoWithoutRequest(TestInlineQueryResultCachedVideoBase): +class TestInlineQueryResultCachedVideoWithoutRequest(InlineQueryResultCachedVideoTestBase): def test_slot_behaviour(self, inline_query_result_cached_video): inst = inline_query_result_cached_video for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcachedvoice.py b/tests/_inline/test_inlinequeryresultcachedvoice.py index de6810b2b58..916364ab987 100644 --- a/tests/_inline/test_inlinequeryresultcachedvoice.py +++ b/tests/_inline/test_inlinequeryresultcachedvoice.py @@ -32,18 +32,18 @@ @pytest.fixture(scope="module") def inline_query_result_cached_voice(): return InlineQueryResultCachedVoice( - 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, + InlineQueryResultCachedVoiceTestBase.id_, + InlineQueryResultCachedVoiceTestBase.voice_file_id, + InlineQueryResultCachedVoiceTestBase.title, + caption=InlineQueryResultCachedVoiceTestBase.caption, + parse_mode=InlineQueryResultCachedVoiceTestBase.parse_mode, + caption_entities=InlineQueryResultCachedVoiceTestBase.caption_entities, + input_message_content=InlineQueryResultCachedVoiceTestBase.input_message_content, + reply_markup=InlineQueryResultCachedVoiceTestBase.reply_markup, ) -class TestInlineQueryResultCachedVoiceBase: +class InlineQueryResultCachedVoiceTestBase: id_ = "id" type_ = "voice" voice_file_id = "voice file id" @@ -55,7 +55,7 @@ class TestInlineQueryResultCachedVoiceBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultCachedVoiceWithoutRequest(TestInlineQueryResultCachedVoiceBase): +class TestInlineQueryResultCachedVoiceWithoutRequest(InlineQueryResultCachedVoiceTestBase): def test_slot_behaviour(self, inline_query_result_cached_voice): inst = inline_query_result_cached_voice for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultcontact.py b/tests/_inline/test_inlinequeryresultcontact.py index 4b691f3801b..bb8c8c18147 100644 --- a/tests/_inline/test_inlinequeryresultcontact.py +++ b/tests/_inline/test_inlinequeryresultcontact.py @@ -31,19 +31,19 @@ @pytest.fixture(scope="module") def inline_query_result_contact(): return InlineQueryResultContact( - TestInlineQueryResultContactBase.id_, - TestInlineQueryResultContactBase.phone_number, - TestInlineQueryResultContactBase.first_name, - last_name=TestInlineQueryResultContactBase.last_name, - thumbnail_url=TestInlineQueryResultContactBase.thumbnail_url, - thumbnail_width=TestInlineQueryResultContactBase.thumbnail_width, - thumbnail_height=TestInlineQueryResultContactBase.thumbnail_height, - input_message_content=TestInlineQueryResultContactBase.input_message_content, - reply_markup=TestInlineQueryResultContactBase.reply_markup, + InlineQueryResultContactTestBase.id_, + InlineQueryResultContactTestBase.phone_number, + InlineQueryResultContactTestBase.first_name, + last_name=InlineQueryResultContactTestBase.last_name, + thumbnail_url=InlineQueryResultContactTestBase.thumbnail_url, + thumbnail_width=InlineQueryResultContactTestBase.thumbnail_width, + thumbnail_height=InlineQueryResultContactTestBase.thumbnail_height, + input_message_content=InlineQueryResultContactTestBase.input_message_content, + reply_markup=InlineQueryResultContactTestBase.reply_markup, ) -class TestInlineQueryResultContactBase: +class InlineQueryResultContactTestBase: id_ = "id" type_ = "contact" phone_number = "phone_number" @@ -56,7 +56,7 @@ class TestInlineQueryResultContactBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultContactWithoutRequest(TestInlineQueryResultContactBase): +class TestInlineQueryResultContactWithoutRequest(InlineQueryResultContactTestBase): def test_slot_behaviour(self, inline_query_result_contact): inst = inline_query_result_contact for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultdocument.py b/tests/_inline/test_inlinequeryresultdocument.py index aacf9d85860..024d714c7a1 100644 --- a/tests/_inline/test_inlinequeryresultdocument.py +++ b/tests/_inline/test_inlinequeryresultdocument.py @@ -32,23 +32,23 @@ @pytest.fixture(scope="module") def inline_query_result_document(): return InlineQueryResultDocument( - 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, - thumbnail_url=TestInlineQueryResultDocumentBase.thumbnail_url, - thumbnail_width=TestInlineQueryResultDocumentBase.thumbnail_width, - thumbnail_height=TestInlineQueryResultDocumentBase.thumbnail_height, - input_message_content=TestInlineQueryResultDocumentBase.input_message_content, - reply_markup=TestInlineQueryResultDocumentBase.reply_markup, + InlineQueryResultDocumentTestBase.id_, + InlineQueryResultDocumentTestBase.document_url, + InlineQueryResultDocumentTestBase.title, + InlineQueryResultDocumentTestBase.mime_type, + caption=InlineQueryResultDocumentTestBase.caption, + parse_mode=InlineQueryResultDocumentTestBase.parse_mode, + caption_entities=InlineQueryResultDocumentTestBase.caption_entities, + description=InlineQueryResultDocumentTestBase.description, + thumbnail_url=InlineQueryResultDocumentTestBase.thumbnail_url, + thumbnail_width=InlineQueryResultDocumentTestBase.thumbnail_width, + thumbnail_height=InlineQueryResultDocumentTestBase.thumbnail_height, + input_message_content=InlineQueryResultDocumentTestBase.input_message_content, + reply_markup=InlineQueryResultDocumentTestBase.reply_markup, ) -class TestInlineQueryResultDocumentBase: +class InlineQueryResultDocumentTestBase: id_ = "id" type_ = "document" document_url = "document url" @@ -65,7 +65,7 @@ class TestInlineQueryResultDocumentBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultDocumentWithoutRequest(TestInlineQueryResultDocumentBase): +class TestInlineQueryResultDocumentWithoutRequest(InlineQueryResultDocumentTestBase): def test_slot_behaviour(self, inline_query_result_document): inst = inline_query_result_document for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultgame.py b/tests/_inline/test_inlinequeryresultgame.py index 8a72ae401e5..2efb7ead89f 100644 --- a/tests/_inline/test_inlinequeryresultgame.py +++ b/tests/_inline/test_inlinequeryresultgame.py @@ -30,20 +30,20 @@ @pytest.fixture(scope="module") def inline_query_result_game(): return InlineQueryResultGame( - TestInlineQueryResultGameBase.id_, - TestInlineQueryResultGameBase.game_short_name, - reply_markup=TestInlineQueryResultGameBase.reply_markup, + InlineQueryResultGameTestBase.id_, + InlineQueryResultGameTestBase.game_short_name, + reply_markup=InlineQueryResultGameTestBase.reply_markup, ) -class TestInlineQueryResultGameBase: +class InlineQueryResultGameTestBase: id_ = "id" type_ = "game" game_short_name = "game short name" reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultGameWithoutRequest(TestInlineQueryResultGameBase): +class TestInlineQueryResultGameWithoutRequest(InlineQueryResultGameTestBase): def test_slot_behaviour(self, inline_query_result_game): inst = inline_query_result_game for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultgif.py b/tests/_inline/test_inlinequeryresultgif.py index 86ac8574a8e..efd995ac335 100644 --- a/tests/_inline/test_inlinequeryresultgif.py +++ b/tests/_inline/test_inlinequeryresultgif.py @@ -32,24 +32,24 @@ @pytest.fixture(scope="module") def inline_query_result_gif(): return InlineQueryResultGif( - TestInlineQueryResultGifBase.id_, - TestInlineQueryResultGifBase.gif_url, - TestInlineQueryResultGifBase.thumbnail_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, - thumbnail_mime_type=TestInlineQueryResultGifBase.thumbnail_mime_type, - show_caption_above_media=TestInlineQueryResultGifBase.show_caption_above_media, + InlineQueryResultGifTestBase.id_, + InlineQueryResultGifTestBase.gif_url, + InlineQueryResultGifTestBase.thumbnail_url, + gif_width=InlineQueryResultGifTestBase.gif_width, + gif_height=InlineQueryResultGifTestBase.gif_height, + gif_duration=InlineQueryResultGifTestBase.gif_duration, + title=InlineQueryResultGifTestBase.title, + caption=InlineQueryResultGifTestBase.caption, + parse_mode=InlineQueryResultGifTestBase.parse_mode, + caption_entities=InlineQueryResultGifTestBase.caption_entities, + input_message_content=InlineQueryResultGifTestBase.input_message_content, + reply_markup=InlineQueryResultGifTestBase.reply_markup, + thumbnail_mime_type=InlineQueryResultGifTestBase.thumbnail_mime_type, + show_caption_above_media=InlineQueryResultGifTestBase.show_caption_above_media, ) -class TestInlineQueryResultGifBase: +class InlineQueryResultGifTestBase: id_ = "id" type_ = "gif" gif_url = "gif url" @@ -67,7 +67,7 @@ class TestInlineQueryResultGifBase: show_caption_above_media = True -class TestInlineQueryResultGifWithoutRequest(TestInlineQueryResultGifBase): +class TestInlineQueryResultGifWithoutRequest(InlineQueryResultGifTestBase): def test_slot_behaviour(self, inline_query_result_gif): inst = inline_query_result_gif for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultlocation.py b/tests/_inline/test_inlinequeryresultlocation.py index 2f5023d5144..76320dddaee 100644 --- a/tests/_inline/test_inlinequeryresultlocation.py +++ b/tests/_inline/test_inlinequeryresultlocation.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="module") def inline_query_result_location(): return InlineQueryResultLocation( - TestInlineQueryResultLocationBase.id_, - TestInlineQueryResultLocationBase.latitude, - TestInlineQueryResultLocationBase.longitude, - TestInlineQueryResultLocationBase.title, - live_period=TestInlineQueryResultLocationBase.live_period, - thumbnail_url=TestInlineQueryResultLocationBase.thumbnail_url, - thumbnail_width=TestInlineQueryResultLocationBase.thumbnail_width, - thumbnail_height=TestInlineQueryResultLocationBase.thumbnail_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, + InlineQueryResultLocationTestBase.id_, + InlineQueryResultLocationTestBase.latitude, + InlineQueryResultLocationTestBase.longitude, + InlineQueryResultLocationTestBase.title, + live_period=InlineQueryResultLocationTestBase.live_period, + thumbnail_url=InlineQueryResultLocationTestBase.thumbnail_url, + thumbnail_width=InlineQueryResultLocationTestBase.thumbnail_width, + thumbnail_height=InlineQueryResultLocationTestBase.thumbnail_height, + input_message_content=InlineQueryResultLocationTestBase.input_message_content, + reply_markup=InlineQueryResultLocationTestBase.reply_markup, + horizontal_accuracy=InlineQueryResultLocationTestBase.horizontal_accuracy, + heading=InlineQueryResultLocationTestBase.heading, + proximity_alert_radius=InlineQueryResultLocationTestBase.proximity_alert_radius, ) -class TestInlineQueryResultLocationBase: +class InlineQueryResultLocationTestBase: id_ = "id" type_ = "location" latitude = 0.0 @@ -64,7 +64,7 @@ class TestInlineQueryResultLocationBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultLocationWithoutRequest(TestInlineQueryResultLocationBase): +class TestInlineQueryResultLocationWithoutRequest(InlineQueryResultLocationTestBase): def test_slot_behaviour(self, inline_query_result_location): inst = inline_query_result_location for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultmpeg4gif.py b/tests/_inline/test_inlinequeryresultmpeg4gif.py index 2a1bfc2cf93..4c0f0f1d3d3 100644 --- a/tests/_inline/test_inlinequeryresultmpeg4gif.py +++ b/tests/_inline/test_inlinequeryresultmpeg4gif.py @@ -32,24 +32,24 @@ @pytest.fixture(scope="module") def inline_query_result_mpeg4_gif(): return InlineQueryResultMpeg4Gif( - TestInlineQueryResultMpeg4GifBase.id_, - TestInlineQueryResultMpeg4GifBase.mpeg4_url, - TestInlineQueryResultMpeg4GifBase.thumbnail_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, - thumbnail_mime_type=TestInlineQueryResultMpeg4GifBase.thumbnail_mime_type, - show_caption_above_media=TestInlineQueryResultMpeg4GifBase.show_caption_above_media, + InlineQueryResultMpeg4GifTestBase.id_, + InlineQueryResultMpeg4GifTestBase.mpeg4_url, + InlineQueryResultMpeg4GifTestBase.thumbnail_url, + mpeg4_width=InlineQueryResultMpeg4GifTestBase.mpeg4_width, + mpeg4_height=InlineQueryResultMpeg4GifTestBase.mpeg4_height, + mpeg4_duration=InlineQueryResultMpeg4GifTestBase.mpeg4_duration, + title=InlineQueryResultMpeg4GifTestBase.title, + caption=InlineQueryResultMpeg4GifTestBase.caption, + parse_mode=InlineQueryResultMpeg4GifTestBase.parse_mode, + caption_entities=InlineQueryResultMpeg4GifTestBase.caption_entities, + input_message_content=InlineQueryResultMpeg4GifTestBase.input_message_content, + reply_markup=InlineQueryResultMpeg4GifTestBase.reply_markup, + thumbnail_mime_type=InlineQueryResultMpeg4GifTestBase.thumbnail_mime_type, + show_caption_above_media=InlineQueryResultMpeg4GifTestBase.show_caption_above_media, ) -class TestInlineQueryResultMpeg4GifBase: +class InlineQueryResultMpeg4GifTestBase: id_ = "id" type_ = "mpeg4_gif" mpeg4_url = "mpeg4 url" @@ -67,7 +67,7 @@ class TestInlineQueryResultMpeg4GifBase: show_caption_above_media = True -class TestInlineQueryResultMpeg4GifWithoutRequest(TestInlineQueryResultMpeg4GifBase): +class TestInlineQueryResultMpeg4GifWithoutRequest(InlineQueryResultMpeg4GifTestBase): def test_slot_behaviour(self, inline_query_result_mpeg4_gif): inst = inline_query_result_mpeg4_gif for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultphoto.py b/tests/_inline/test_inlinequeryresultphoto.py index 323cf7b71ed..2abec4a3b7e 100644 --- a/tests/_inline/test_inlinequeryresultphoto.py +++ b/tests/_inline/test_inlinequeryresultphoto.py @@ -32,23 +32,23 @@ @pytest.fixture(scope="module") def inline_query_result_photo(): return InlineQueryResultPhoto( - TestInlineQueryResultPhotoBase.id_, - TestInlineQueryResultPhotoBase.photo_url, - TestInlineQueryResultPhotoBase.thumbnail_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, - show_caption_above_media=TestInlineQueryResultPhotoBase.show_caption_above_media, + InlineQueryResultPhotoTestBase.id_, + InlineQueryResultPhotoTestBase.photo_url, + InlineQueryResultPhotoTestBase.thumbnail_url, + photo_width=InlineQueryResultPhotoTestBase.photo_width, + photo_height=InlineQueryResultPhotoTestBase.photo_height, + title=InlineQueryResultPhotoTestBase.title, + description=InlineQueryResultPhotoTestBase.description, + caption=InlineQueryResultPhotoTestBase.caption, + parse_mode=InlineQueryResultPhotoTestBase.parse_mode, + caption_entities=InlineQueryResultPhotoTestBase.caption_entities, + input_message_content=InlineQueryResultPhotoTestBase.input_message_content, + reply_markup=InlineQueryResultPhotoTestBase.reply_markup, + show_caption_above_media=InlineQueryResultPhotoTestBase.show_caption_above_media, ) -class TestInlineQueryResultPhotoBase: +class InlineQueryResultPhotoTestBase: id_ = "id" type_ = "photo" photo_url = "photo url" @@ -66,7 +66,7 @@ class TestInlineQueryResultPhotoBase: show_caption_above_media = True -class TestInlineQueryResultPhotoWithoutRequest(TestInlineQueryResultPhotoBase): +class TestInlineQueryResultPhotoWithoutRequest(InlineQueryResultPhotoTestBase): def test_slot_behaviour(self, inline_query_result_photo): inst = inline_query_result_photo for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultvenue.py b/tests/_inline/test_inlinequeryresultvenue.py index ba09ad7d180..cb5ad760a58 100644 --- a/tests/_inline/test_inlinequeryresultvenue.py +++ b/tests/_inline/test_inlinequeryresultvenue.py @@ -31,24 +31,24 @@ @pytest.fixture(scope="module") def inline_query_result_venue(): return InlineQueryResultVenue( - TestInlineQueryResultVenueBase.id_, - TestInlineQueryResultVenueBase.latitude, - TestInlineQueryResultVenueBase.longitude, - TestInlineQueryResultVenueBase.title, - TestInlineQueryResultVenueBase.address, - foursquare_id=TestInlineQueryResultVenueBase.foursquare_id, - foursquare_type=TestInlineQueryResultVenueBase.foursquare_type, - thumbnail_url=TestInlineQueryResultVenueBase.thumbnail_url, - thumbnail_width=TestInlineQueryResultVenueBase.thumbnail_width, - thumbnail_height=TestInlineQueryResultVenueBase.thumbnail_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, + InlineQueryResultVenueTestBase.id_, + InlineQueryResultVenueTestBase.latitude, + InlineQueryResultVenueTestBase.longitude, + InlineQueryResultVenueTestBase.title, + InlineQueryResultVenueTestBase.address, + foursquare_id=InlineQueryResultVenueTestBase.foursquare_id, + foursquare_type=InlineQueryResultVenueTestBase.foursquare_type, + thumbnail_url=InlineQueryResultVenueTestBase.thumbnail_url, + thumbnail_width=InlineQueryResultVenueTestBase.thumbnail_width, + thumbnail_height=InlineQueryResultVenueTestBase.thumbnail_height, + input_message_content=InlineQueryResultVenueTestBase.input_message_content, + reply_markup=InlineQueryResultVenueTestBase.reply_markup, + google_place_id=InlineQueryResultVenueTestBase.google_place_id, + google_place_type=InlineQueryResultVenueTestBase.google_place_type, ) -class TestInlineQueryResultVenueBase: +class InlineQueryResultVenueTestBase: id_ = "id" type_ = "venue" latitude = "latitude" @@ -66,7 +66,7 @@ class TestInlineQueryResultVenueBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVenueWithoutRequest(TestInlineQueryResultVenueBase): +class TestInlineQueryResultVenueWithoutRequest(InlineQueryResultVenueTestBase): def test_slot_behaviour(self, inline_query_result_venue): inst = inline_query_result_venue for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultvideo.py b/tests/_inline/test_inlinequeryresultvideo.py index 68709e396e3..7534ad0433d 100644 --- a/tests/_inline/test_inlinequeryresultvideo.py +++ b/tests/_inline/test_inlinequeryresultvideo.py @@ -32,25 +32,25 @@ @pytest.fixture(scope="module") def inline_query_result_video(): return InlineQueryResultVideo( - TestInlineQueryResultVideoBase.id_, - TestInlineQueryResultVideoBase.video_url, - TestInlineQueryResultVideoBase.mime_type, - TestInlineQueryResultVideoBase.thumbnail_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, - show_caption_above_media=TestInlineQueryResultVideoBase.show_caption_above_media, + InlineQueryResultVideoTestBase.id_, + InlineQueryResultVideoTestBase.video_url, + InlineQueryResultVideoTestBase.mime_type, + InlineQueryResultVideoTestBase.thumbnail_url, + InlineQueryResultVideoTestBase.title, + video_width=InlineQueryResultVideoTestBase.video_width, + video_height=InlineQueryResultVideoTestBase.video_height, + video_duration=InlineQueryResultVideoTestBase.video_duration, + caption=InlineQueryResultVideoTestBase.caption, + parse_mode=InlineQueryResultVideoTestBase.parse_mode, + caption_entities=InlineQueryResultVideoTestBase.caption_entities, + description=InlineQueryResultVideoTestBase.description, + input_message_content=InlineQueryResultVideoTestBase.input_message_content, + reply_markup=InlineQueryResultVideoTestBase.reply_markup, + show_caption_above_media=InlineQueryResultVideoTestBase.show_caption_above_media, ) -class TestInlineQueryResultVideoBase: +class InlineQueryResultVideoTestBase: id_ = "id" type_ = "video" video_url = "video url" @@ -69,7 +69,7 @@ class TestInlineQueryResultVideoBase: show_caption_above_media = True -class TestInlineQueryResultVideoWithoutRequest(TestInlineQueryResultVideoBase): +class TestInlineQueryResultVideoWithoutRequest(InlineQueryResultVideoTestBase): def test_slot_behaviour(self, inline_query_result_video): inst = inline_query_result_video for attr in inst.__slots__: diff --git a/tests/_inline/test_inlinequeryresultvoice.py b/tests/_inline/test_inlinequeryresultvoice.py index 34ea013cb60..cddbc9d7efa 100644 --- a/tests/_inline/test_inlinequeryresultvoice.py +++ b/tests/_inline/test_inlinequeryresultvoice.py @@ -32,19 +32,19 @@ @pytest.fixture(scope="module") def inline_query_result_voice(): return InlineQueryResultVoice( - 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, + id=InlineQueryResultVoiceTestBase.id_, + voice_url=InlineQueryResultVoiceTestBase.voice_url, + title=InlineQueryResultVoiceTestBase.title, + voice_duration=InlineQueryResultVoiceTestBase.voice_duration, + caption=InlineQueryResultVoiceTestBase.caption, + parse_mode=InlineQueryResultVoiceTestBase.parse_mode, + caption_entities=InlineQueryResultVoiceTestBase.caption_entities, + input_message_content=InlineQueryResultVoiceTestBase.input_message_content, + reply_markup=InlineQueryResultVoiceTestBase.reply_markup, ) -class TestInlineQueryResultVoiceBase: +class InlineQueryResultVoiceTestBase: id_ = "id" type_ = "voice" voice_url = "voice url" @@ -57,7 +57,7 @@ class TestInlineQueryResultVoiceBase: reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton("reply_markup")]]) -class TestInlineQueryResultVoiceWithoutRequest(TestInlineQueryResultVoiceBase): +class TestInlineQueryResultVoiceWithoutRequest(InlineQueryResultVoiceTestBase): def test_slot_behaviour(self, inline_query_result_voice): inst = inline_query_result_voice for attr in inst.__slots__: diff --git a/tests/_inline/test_inputcontactmessagecontent.py b/tests/_inline/test_inputcontactmessagecontent.py index 5a48f7dc5cc..afd1b15f035 100644 --- a/tests/_inline/test_inputcontactmessagecontent.py +++ b/tests/_inline/test_inputcontactmessagecontent.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="module") def input_contact_message_content(): return InputContactMessageContent( - TestInputContactMessageContentBase.phone_number, - TestInputContactMessageContentBase.first_name, - TestInputContactMessageContentBase.last_name, + InputContactMessageContentTestBase.phone_number, + InputContactMessageContentTestBase.first_name, + InputContactMessageContentTestBase.last_name, ) -class TestInputContactMessageContentBase: +class InputContactMessageContentTestBase: phone_number = "phone number" first_name = "first name" last_name = "last name" -class TestInputContactMessageContentWithoutRequest(TestInputContactMessageContentBase): +class TestInputContactMessageContentWithoutRequest(InputContactMessageContentTestBase): def test_slot_behaviour(self, input_contact_message_content): inst = input_contact_message_content for attr in inst.__slots__: diff --git a/tests/_inline/test_inputinvoicemessagecontent.py b/tests/_inline/test_inputinvoicemessagecontent.py index 577ba677599..17bfad01359 100644 --- a/tests/_inline/test_inputinvoicemessagecontent.py +++ b/tests/_inline/test_inputinvoicemessagecontent.py @@ -26,32 +26,32 @@ @pytest.fixture(scope="module") def input_invoice_message_content(): return InputInvoiceMessageContent( - 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, + title=InputInvoiceMessageContentTestBase.title, + description=InputInvoiceMessageContentTestBase.description, + payload=InputInvoiceMessageContentTestBase.payload, + provider_token=InputInvoiceMessageContentTestBase.provider_token, + currency=InputInvoiceMessageContentTestBase.currency, + prices=InputInvoiceMessageContentTestBase.prices, + max_tip_amount=InputInvoiceMessageContentTestBase.max_tip_amount, + suggested_tip_amounts=InputInvoiceMessageContentTestBase.suggested_tip_amounts, + provider_data=InputInvoiceMessageContentTestBase.provider_data, + photo_url=InputInvoiceMessageContentTestBase.photo_url, + photo_size=InputInvoiceMessageContentTestBase.photo_size, + photo_width=InputInvoiceMessageContentTestBase.photo_width, + photo_height=InputInvoiceMessageContentTestBase.photo_height, + need_name=InputInvoiceMessageContentTestBase.need_name, + need_phone_number=InputInvoiceMessageContentTestBase.need_phone_number, + need_email=InputInvoiceMessageContentTestBase.need_email, + need_shipping_address=InputInvoiceMessageContentTestBase.need_shipping_address, send_phone_number_to_provider=( - TestInputInvoiceMessageContentBase.send_phone_number_to_provider + InputInvoiceMessageContentTestBase.send_phone_number_to_provider ), - send_email_to_provider=TestInputInvoiceMessageContentBase.send_email_to_provider, - is_flexible=TestInputInvoiceMessageContentBase.is_flexible, + send_email_to_provider=InputInvoiceMessageContentTestBase.send_email_to_provider, + is_flexible=InputInvoiceMessageContentTestBase.is_flexible, ) -class TestInputInvoiceMessageContentBase: +class InputInvoiceMessageContentTestBase: title = "invoice title" description = "invoice description" payload = "invoice payload" @@ -74,7 +74,7 @@ class TestInputInvoiceMessageContentBase: is_flexible = True -class TestInputInvoiceMessageContentWithoutRequest(TestInputInvoiceMessageContentBase): +class TestInputInvoiceMessageContentWithoutRequest(InputInvoiceMessageContentTestBase): def test_slot_behaviour(self, input_invoice_message_content): inst = input_invoice_message_content for attr in inst.__slots__: diff --git a/tests/_inline/test_inputlocationmessagecontent.py b/tests/_inline/test_inputlocationmessagecontent.py index 61d311cae38..f2101fca27b 100644 --- a/tests/_inline/test_inputlocationmessagecontent.py +++ b/tests/_inline/test_inputlocationmessagecontent.py @@ -25,16 +25,16 @@ @pytest.fixture(scope="module") def input_location_message_content(): return InputLocationMessageContent( - TestInputLocationMessageContentBase.latitude, - TestInputLocationMessageContentBase.longitude, - live_period=TestInputLocationMessageContentBase.live_period, - horizontal_accuracy=TestInputLocationMessageContentBase.horizontal_accuracy, - heading=TestInputLocationMessageContentBase.heading, - proximity_alert_radius=TestInputLocationMessageContentBase.proximity_alert_radius, + InputLocationMessageContentTestBase.latitude, + InputLocationMessageContentTestBase.longitude, + live_period=InputLocationMessageContentTestBase.live_period, + horizontal_accuracy=InputLocationMessageContentTestBase.horizontal_accuracy, + heading=InputLocationMessageContentTestBase.heading, + proximity_alert_radius=InputLocationMessageContentTestBase.proximity_alert_radius, ) -class TestInputLocationMessageContentBase: +class InputLocationMessageContentTestBase: latitude = -23.691288 longitude = -46.788279 live_period = 80 @@ -43,7 +43,7 @@ class TestInputLocationMessageContentBase: proximity_alert_radius = 999 -class TestInputLocationMessageContentWithoutRequest(TestInputLocationMessageContentBase): +class TestInputLocationMessageContentWithoutRequest(InputLocationMessageContentTestBase): def test_slot_behaviour(self, input_location_message_content): inst = input_location_message_content for attr in inst.__slots__: diff --git a/tests/_inline/test_inputtextmessagecontent.py b/tests/_inline/test_inputtextmessagecontent.py index 632a29db189..227e0737dce 100644 --- a/tests/_inline/test_inputtextmessagecontent.py +++ b/tests/_inline/test_inputtextmessagecontent.py @@ -26,14 +26,14 @@ @pytest.fixture(scope="module") def input_text_message_content(): return InputTextMessageContent( - TestInputTextMessageContentBase.message_text, - parse_mode=TestInputTextMessageContentBase.parse_mode, - entities=TestInputTextMessageContentBase.entities, - link_preview_options=TestInputTextMessageContentBase.link_preview_options, + InputTextMessageContentTestBase.message_text, + parse_mode=InputTextMessageContentTestBase.parse_mode, + entities=InputTextMessageContentTestBase.entities, + link_preview_options=InputTextMessageContentTestBase.link_preview_options, ) -class TestInputTextMessageContentBase: +class InputTextMessageContentTestBase: message_text = "*message text*" parse_mode = ParseMode.MARKDOWN entities = [MessageEntity(MessageEntity.ITALIC, 0, 7)] @@ -41,7 +41,7 @@ class TestInputTextMessageContentBase: link_preview_options = LinkPreviewOptions(False, url="https://python-telegram-bot.org") -class TestInputTextMessageContentWithoutRequest(TestInputTextMessageContentBase): +class TestInputTextMessageContentWithoutRequest(InputTextMessageContentTestBase): def test_slot_behaviour(self, input_text_message_content): inst = input_text_message_content for attr in inst.__slots__: diff --git a/tests/_inline/test_inputvenuemessagecontent.py b/tests/_inline/test_inputvenuemessagecontent.py index 8c9d4c62d10..d88f9714ff9 100644 --- a/tests/_inline/test_inputvenuemessagecontent.py +++ b/tests/_inline/test_inputvenuemessagecontent.py @@ -25,18 +25,18 @@ @pytest.fixture(scope="module") def input_venue_message_content(): return InputVenueMessageContent( - 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, + InputVenueMessageContentTestBase.latitude, + InputVenueMessageContentTestBase.longitude, + InputVenueMessageContentTestBase.title, + InputVenueMessageContentTestBase.address, + foursquare_id=InputVenueMessageContentTestBase.foursquare_id, + foursquare_type=InputVenueMessageContentTestBase.foursquare_type, + google_place_id=InputVenueMessageContentTestBase.google_place_id, + google_place_type=InputVenueMessageContentTestBase.google_place_type, ) -class TestInputVenueMessageContentBase: +class InputVenueMessageContentTestBase: latitude = 1.0 longitude = 2.0 title = "title" @@ -47,7 +47,7 @@ class TestInputVenueMessageContentBase: google_place_type = "google place type" -class TestInputVenueMessageContentWithoutRequest(TestInputVenueMessageContentBase): +class TestInputVenueMessageContentWithoutRequest(InputVenueMessageContentTestBase): def test_slot_behaviour(self, input_venue_message_content): inst = input_venue_message_content for attr in inst.__slots__: diff --git a/tests/_passport/test_encryptedcredentials.py b/tests/_passport/test_encryptedcredentials.py index 3b45ee157c3..8af9c2cff92 100644 --- a/tests/_passport/test_encryptedcredentials.py +++ b/tests/_passport/test_encryptedcredentials.py @@ -26,19 +26,19 @@ @pytest.fixture(scope="module") def encrypted_credentials(): return EncryptedCredentials( - TestEncryptedCredentialsBase.data, - TestEncryptedCredentialsBase.hash, - TestEncryptedCredentialsBase.secret, + EncryptedCredentialsTestBase.data, + EncryptedCredentialsTestBase.hash, + EncryptedCredentialsTestBase.secret, ) -class TestEncryptedCredentialsBase: +class EncryptedCredentialsTestBase: data = "data" hash = "hash" secret = "secret" -class TestEncryptedCredentialsWithoutRequest(TestEncryptedCredentialsBase): +class TestEncryptedCredentialsWithoutRequest(EncryptedCredentialsTestBase): def test_slot_behaviour(self, encrypted_credentials): inst = encrypted_credentials for attr in inst.__slots__: diff --git a/tests/_passport/test_encryptedpassportelement.py b/tests/_passport/test_encryptedpassportelement.py index f1299029017..fa79846b6e6 100644 --- a/tests/_passport/test_encryptedpassportelement.py +++ b/tests/_passport/test_encryptedpassportelement.py @@ -26,19 +26,19 @@ @pytest.fixture(scope="module") def encrypted_passport_element(): return EncryptedPassportElement( - TestEncryptedPassportElementBase.type_, + EncryptedPassportElementTestBase.type_, "this is a hash", - 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, + data=EncryptedPassportElementTestBase.data, + phone_number=EncryptedPassportElementTestBase.phone_number, + email=EncryptedPassportElementTestBase.email, + files=EncryptedPassportElementTestBase.files, + front_side=EncryptedPassportElementTestBase.front_side, + reverse_side=EncryptedPassportElementTestBase.reverse_side, + selfie=EncryptedPassportElementTestBase.selfie, ) -class TestEncryptedPassportElementBase: +class EncryptedPassportElementTestBase: type_ = "type" hash = "this is a hash" data = "data" @@ -50,7 +50,7 @@ class TestEncryptedPassportElementBase: selfie = PassportFile("file_id", 50, 0, 25) -class TestEncryptedPassportElementWithoutRequest(TestEncryptedPassportElementBase): +class TestEncryptedPassportElementWithoutRequest(EncryptedPassportElementTestBase): def test_slot_behaviour(self, encrypted_passport_element): inst = encrypted_passport_element for attr in inst.__slots__: diff --git a/tests/_passport/test_passport.py b/tests/_passport/test_passport.py index c35eeaf1761..9303ae7eb13 100644 --- a/tests/_passport/test_passport.py +++ b/tests/_passport/test_passport.py @@ -220,7 +220,7 @@ def passport_data(bot): return PassportData.de_json(RAW_PASSPORT_DATA, bot=bot) -class TestPassportBase: +class PassportTestBase: driver_license_selfie_file_id = "DgADBAADEQQAAkopgFNr6oi-wISRtAI" driver_license_selfie_file_unique_id = "d4e390cca57b4da5a65322b304762a12" driver_license_front_side_file_id = "DgADBAADxwMAApnQgVPK2-ckL2eXVAI" @@ -243,7 +243,7 @@ class TestPassportBase: driver_license_selfie_credentials_secret = "tivdId6RNYNsvXYPppdzrbxOBuBOr9wXRPDcCvnXU7E=" -class TestPassportWithoutRequest(TestPassportBase): +class TestPassportWithoutRequest(PassportTestBase): def test_slot_behaviour(self, passport_data): inst = passport_data for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrordatafield.py b/tests/_passport/test_passportelementerrordatafield.py index 0d49359a3fa..5bbf1e7a4fd 100644 --- a/tests/_passport/test_passportelementerrordatafield.py +++ b/tests/_passport/test_passportelementerrordatafield.py @@ -25,14 +25,14 @@ @pytest.fixture(scope="module") def passport_element_error_data_field(): return PassportElementErrorDataField( - TestPassportElementErrorDataFieldBase.type_, - TestPassportElementErrorDataFieldBase.field_name, - TestPassportElementErrorDataFieldBase.data_hash, - TestPassportElementErrorDataFieldBase.message, + PassportElementErrorDataFieldTestBase.type_, + PassportElementErrorDataFieldTestBase.field_name, + PassportElementErrorDataFieldTestBase.data_hash, + PassportElementErrorDataFieldTestBase.message, ) -class TestPassportElementErrorDataFieldBase: +class PassportElementErrorDataFieldTestBase: source = "data" type_ = "test_type" field_name = "test_field" @@ -40,7 +40,7 @@ class TestPassportElementErrorDataFieldBase: message = "Error message" -class TestPassportElementErrorDataFieldWithoutRequest(TestPassportElementErrorDataFieldBase): +class TestPassportElementErrorDataFieldWithoutRequest(PassportElementErrorDataFieldTestBase): def test_slot_behaviour(self, passport_element_error_data_field): inst = passport_element_error_data_field for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrorfile.py b/tests/_passport/test_passportelementerrorfile.py index ef892b183ff..39d4b044975 100644 --- a/tests/_passport/test_passportelementerrorfile.py +++ b/tests/_passport/test_passportelementerrorfile.py @@ -25,20 +25,20 @@ @pytest.fixture(scope="module") def passport_element_error_file(): return PassportElementErrorFile( - TestPassportElementErrorFileBase.type_, - TestPassportElementErrorFileBase.file_hash, - TestPassportElementErrorFileBase.message, + PassportElementErrorFileTestBase.type_, + PassportElementErrorFileTestBase.file_hash, + PassportElementErrorFileTestBase.message, ) -class TestPassportElementErrorFileBase: +class PassportElementErrorFileTestBase: source = "file" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorFileWithoutRequest(TestPassportElementErrorFileBase): +class TestPassportElementErrorFileWithoutRequest(PassportElementErrorFileTestBase): def test_slot_behaviour(self, passport_element_error_file): inst = passport_element_error_file for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrorfiles.py b/tests/_passport/test_passportelementerrorfiles.py index 43ee7cb5da8..97bb059cad8 100644 --- a/tests/_passport/test_passportelementerrorfiles.py +++ b/tests/_passport/test_passportelementerrorfiles.py @@ -26,20 +26,20 @@ @pytest.fixture(scope="module") def passport_element_error_files(): return PassportElementErrorFiles( - TestPassportElementErrorFilesBase.type_, - TestPassportElementErrorFilesBase.file_hashes, - TestPassportElementErrorFilesBase.message, + PassportElementErrorFilesTestBase.type_, + PassportElementErrorFilesTestBase.file_hashes, + PassportElementErrorFilesTestBase.message, ) -class TestPassportElementErrorFilesBase: +class PassportElementErrorFilesTestBase: source = "files" type_ = "test_type" file_hashes = ["hash1", "hash2"] message = "Error message" -class TestPassportElementErrorFilesWithoutRequest(TestPassportElementErrorFilesBase): +class TestPassportElementErrorFilesWithoutRequest(PassportElementErrorFilesTestBase): def test_slot_behaviour(self, passport_element_error_files): inst = passport_element_error_files for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrorfrontside.py b/tests/_passport/test_passportelementerrorfrontside.py index 6a29052d319..3a5694fc847 100644 --- a/tests/_passport/test_passportelementerrorfrontside.py +++ b/tests/_passport/test_passportelementerrorfrontside.py @@ -25,20 +25,20 @@ @pytest.fixture(scope="module") def passport_element_error_front_side(): return PassportElementErrorFrontSide( - TestPassportElementErrorFrontSideBase.type_, - TestPassportElementErrorFrontSideBase.file_hash, - TestPassportElementErrorFrontSideBase.message, + PassportElementErrorFrontSideTestBase.type_, + PassportElementErrorFrontSideTestBase.file_hash, + PassportElementErrorFrontSideTestBase.message, ) -class TestPassportElementErrorFrontSideBase: +class PassportElementErrorFrontSideTestBase: source = "front_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorFrontSideWithoutRequest(TestPassportElementErrorFrontSideBase): +class TestPassportElementErrorFrontSideWithoutRequest(PassportElementErrorFrontSideTestBase): def test_slot_behaviour(self, passport_element_error_front_side): inst = passport_element_error_front_side for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrorreverseside.py b/tests/_passport/test_passportelementerrorreverseside.py index bda4cd73167..e6b1bae9e45 100644 --- a/tests/_passport/test_passportelementerrorreverseside.py +++ b/tests/_passport/test_passportelementerrorreverseside.py @@ -25,20 +25,20 @@ @pytest.fixture(scope="module") def passport_element_error_reverse_side(): return PassportElementErrorReverseSide( - TestPassportElementErrorReverseSideBase.type_, - TestPassportElementErrorReverseSideBase.file_hash, - TestPassportElementErrorReverseSideBase.message, + PassportElementErrorReverseSideTestBase.type_, + PassportElementErrorReverseSideTestBase.file_hash, + PassportElementErrorReverseSideTestBase.message, ) -class TestPassportElementErrorReverseSideBase: +class PassportElementErrorReverseSideTestBase: source = "reverse_side" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorReverseSideWithoutRequest(TestPassportElementErrorReverseSideBase): +class TestPassportElementErrorReverseSideWithoutRequest(PassportElementErrorReverseSideTestBase): def test_slot_behaviour(self, passport_element_error_reverse_side): inst = passport_element_error_reverse_side for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrorselfie.py b/tests/_passport/test_passportelementerrorselfie.py index 9580e24ae74..a7af4ecdc7c 100644 --- a/tests/_passport/test_passportelementerrorselfie.py +++ b/tests/_passport/test_passportelementerrorselfie.py @@ -25,20 +25,20 @@ @pytest.fixture(scope="module") def passport_element_error_selfie(): return PassportElementErrorSelfie( - TestPassportElementErrorSelfieBase.type_, - TestPassportElementErrorSelfieBase.file_hash, - TestPassportElementErrorSelfieBase.message, + PassportElementErrorSelfieTestBase.type_, + PassportElementErrorSelfieTestBase.file_hash, + PassportElementErrorSelfieTestBase.message, ) -class TestPassportElementErrorSelfieBase: +class PassportElementErrorSelfieTestBase: source = "selfie" type_ = "test_type" file_hash = "file_hash" message = "Error message" -class TestPassportElementErrorSelfieWithoutRequest(TestPassportElementErrorSelfieBase): +class TestPassportElementErrorSelfieWithoutRequest(PassportElementErrorSelfieTestBase): def test_slot_behaviour(self, passport_element_error_selfie): inst = passport_element_error_selfie for attr in inst.__slots__: diff --git a/tests/_passport/test_passportelementerrortranslationfile.py b/tests/_passport/test_passportelementerrortranslationfile.py index f55a8ad7017..0493f7e3fb3 100644 --- a/tests/_passport/test_passportelementerrortranslationfile.py +++ b/tests/_passport/test_passportelementerrortranslationfile.py @@ -25,13 +25,13 @@ @pytest.fixture(scope="module") def passport_element_error_translation_file(): return PassportElementErrorTranslationFile( - TestPassportElementErrorTranslationFileBase.type_, - TestPassportElementErrorTranslationFileBase.file_hash, - TestPassportElementErrorTranslationFileBase.message, + PassportElementErrorTranslationFileTestBase.type_, + PassportElementErrorTranslationFileTestBase.file_hash, + PassportElementErrorTranslationFileTestBase.message, ) -class TestPassportElementErrorTranslationFileBase: +class PassportElementErrorTranslationFileTestBase: source = "translation_file" type_ = "test_type" file_hash = "file_hash" @@ -39,7 +39,7 @@ class TestPassportElementErrorTranslationFileBase: class TestPassportElementErrorTranslationFileWithoutRequest( - TestPassportElementErrorTranslationFileBase + PassportElementErrorTranslationFileTestBase ): def test_slot_behaviour(self, passport_element_error_translation_file): inst = passport_element_error_translation_file diff --git a/tests/_passport/test_passportelementerrortranslationfiles.py b/tests/_passport/test_passportelementerrortranslationfiles.py index eb62aa5d1d7..8412ef30050 100644 --- a/tests/_passport/test_passportelementerrortranslationfiles.py +++ b/tests/_passport/test_passportelementerrortranslationfiles.py @@ -26,13 +26,13 @@ @pytest.fixture(scope="module") def passport_element_error_translation_files(): return PassportElementErrorTranslationFiles( - TestPassportElementErrorTranslationFilesBase.type_, - TestPassportElementErrorTranslationFilesBase.file_hashes, - TestPassportElementErrorTranslationFilesBase.message, + PassportElementErrorTranslationFilesTestBase.type_, + PassportElementErrorTranslationFilesTestBase.file_hashes, + PassportElementErrorTranslationFilesTestBase.message, ) -class TestPassportElementErrorTranslationFilesBase: +class PassportElementErrorTranslationFilesTestBase: source = "translation_files" type_ = "test_type" file_hashes = ["hash1", "hash2"] @@ -40,7 +40,7 @@ class TestPassportElementErrorTranslationFilesBase: class TestPassportElementErrorTranslationFilesWithoutRequest( - TestPassportElementErrorTranslationFilesBase + PassportElementErrorTranslationFilesTestBase ): def test_slot_behaviour(self, passport_element_error_translation_files): inst = passport_element_error_translation_files diff --git a/tests/_passport/test_passportelementerrorunspecified.py b/tests/_passport/test_passportelementerrorunspecified.py index 260192e18c6..d3b6105b2de 100644 --- a/tests/_passport/test_passportelementerrorunspecified.py +++ b/tests/_passport/test_passportelementerrorunspecified.py @@ -25,20 +25,20 @@ @pytest.fixture(scope="module") def passport_element_error_unspecified(): return PassportElementErrorUnspecified( - TestPassportElementErrorUnspecifiedBase.type_, - TestPassportElementErrorUnspecifiedBase.element_hash, - TestPassportElementErrorUnspecifiedBase.message, + PassportElementErrorUnspecifiedTestBase.type_, + PassportElementErrorUnspecifiedTestBase.element_hash, + PassportElementErrorUnspecifiedTestBase.message, ) -class TestPassportElementErrorUnspecifiedBase: +class PassportElementErrorUnspecifiedTestBase: source = "unspecified" type_ = "test_type" element_hash = "element_hash" message = "Error message" -class TestPassportElementErrorUnspecifiedWithoutRequest(TestPassportElementErrorUnspecifiedBase): +class TestPassportElementErrorUnspecifiedWithoutRequest(PassportElementErrorUnspecifiedTestBase): def test_slot_behaviour(self, passport_element_error_unspecified): inst = passport_element_error_unspecified for attr in inst.__slots__: diff --git a/tests/_passport/test_passportfile.py b/tests/_passport/test_passportfile.py index d12e0ce9f11..8fef970be71 100644 --- a/tests/_passport/test_passportfile.py +++ b/tests/_passport/test_passportfile.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="class") def passport_file(bot): pf = PassportFile( - file_id=TestPassportFileBase.file_id, - file_unique_id=TestPassportFileBase.file_unique_id, - file_size=TestPassportFileBase.file_size, - file_date=TestPassportFileBase.file_date, + file_id=PassportFileTestBase.file_id, + file_unique_id=PassportFileTestBase.file_unique_id, + file_size=PassportFileTestBase.file_size, + file_date=PassportFileTestBase.file_date, ) pf.set_bot(bot) return pf -class TestPassportFileBase: +class PassportFileTestBase: file_id = "data" file_unique_id = "adc3145fd2e84d95b64d68eaa22aa33e" file_size = 50 file_date = 1532879128 -class TestPassportFileWithoutRequest(TestPassportFileBase): +class TestPassportFileWithoutRequest(PassportFileTestBase): def test_slot_behaviour(self, passport_file): inst = passport_file for attr in inst.__slots__: diff --git a/tests/_payment/test_invoice.py b/tests/_payment/test_invoice.py index 65a39aeb3f7..2293fe58745 100644 --- a/tests/_payment/test_invoice.py +++ b/tests/_payment/test_invoice.py @@ -31,15 +31,15 @@ @pytest.fixture(scope="module") def invoice(): return Invoice( - TestInvoiceBase.title, - TestInvoiceBase.description, - TestInvoiceBase.start_parameter, - TestInvoiceBase.currency, - TestInvoiceBase.total_amount, + InvoiceTestBase.title, + InvoiceTestBase.description, + InvoiceTestBase.start_parameter, + InvoiceTestBase.currency, + InvoiceTestBase.total_amount, ) -class TestInvoiceBase: +class InvoiceTestBase: payload = "payload" prices = [LabeledPrice("Fish", 100), LabeledPrice("Fish Tax", 1000)] provider_data = """{"test":"test"}""" @@ -52,7 +52,7 @@ class TestInvoiceBase: suggested_tip_amounts = [13, 42] -class TestInvoiceWithoutRequest(TestInvoiceBase): +class TestInvoiceWithoutRequest(InvoiceTestBase): def test_slot_behaviour(self, invoice): for attr in invoice.__slots__: assert getattr(invoice, attr, "err") != "err", f"got extra slot '{attr}'" @@ -219,7 +219,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestInvoiceWithRequest(TestInvoiceBase): +class TestInvoiceWithRequest(InvoiceTestBase): async def test_send_required_args_only(self, bot, chat_id, provider_token): message = await bot.send_invoice( chat_id=chat_id, diff --git a/tests/_payment/test_labeledprice.py b/tests/_payment/test_labeledprice.py index c05672de3c5..7647a704c75 100644 --- a/tests/_payment/test_labeledprice.py +++ b/tests/_payment/test_labeledprice.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def labeled_price(): - return LabeledPrice(TestLabeledPriceBase.label, TestLabeledPriceBase.amount) + return LabeledPrice(LabeledPriceTestBase.label, LabeledPriceTestBase.amount) -class TestLabeledPriceBase: +class LabeledPriceTestBase: label = "label" amount = 100 -class TestLabeledPriceWithoutRequest(TestLabeledPriceBase): +class TestLabeledPriceWithoutRequest(LabeledPriceTestBase): def test_slot_behaviour(self, labeled_price): inst = labeled_price for attr in inst.__slots__: diff --git a/tests/_payment/test_orderinfo.py b/tests/_payment/test_orderinfo.py index a8a01fb5e27..8e27ed34390 100644 --- a/tests/_payment/test_orderinfo.py +++ b/tests/_payment/test_orderinfo.py @@ -25,21 +25,21 @@ @pytest.fixture(scope="module") def order_info(): return OrderInfo( - TestOrderInfoBase.name, - TestOrderInfoBase.phone_number, - TestOrderInfoBase.email, - TestOrderInfoBase.shipping_address, + OrderInfoTestBase.name, + OrderInfoTestBase.phone_number, + OrderInfoTestBase.email, + OrderInfoTestBase.shipping_address, ) -class TestOrderInfoBase: +class OrderInfoTestBase: name = "name" phone_number = "phone_number" email = "email" shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestOrderInfoWithoutRequest(TestOrderInfoBase): +class TestOrderInfoWithoutRequest(OrderInfoTestBase): def test_slot_behaviour(self, order_info): for attr in order_info.__slots__: assert getattr(order_info, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/_payment/test_precheckoutquery.py b/tests/_payment/test_precheckoutquery.py index 57637187df5..aaca70407a4 100644 --- a/tests/_payment/test_precheckoutquery.py +++ b/tests/_payment/test_precheckoutquery.py @@ -31,19 +31,19 @@ @pytest.fixture(scope="module") def pre_checkout_query(bot): pcq = PreCheckoutQuery( - 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, + PreCheckoutQueryTestBase.id_, + PreCheckoutQueryTestBase.from_user, + PreCheckoutQueryTestBase.currency, + PreCheckoutQueryTestBase.total_amount, + PreCheckoutQueryTestBase.invoice_payload, + shipping_option_id=PreCheckoutQueryTestBase.shipping_option_id, + order_info=PreCheckoutQueryTestBase.order_info, ) pcq.set_bot(bot) return pcq -class TestPreCheckoutQueryBase: +class PreCheckoutQueryTestBase: id_ = 5 invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" @@ -53,7 +53,7 @@ class TestPreCheckoutQueryBase: order_info = OrderInfo() -class TestPreCheckoutQueryWithoutRequest(TestPreCheckoutQueryBase): +class TestPreCheckoutQueryWithoutRequest(PreCheckoutQueryTestBase): def test_slot_behaviour(self, pre_checkout_query): inst = pre_checkout_query for attr in inst.__slots__: diff --git a/tests/_payment/test_refundedpayment.py b/tests/_payment/test_refundedpayment.py index 75e252660da..8ea4d1a5001 100644 --- a/tests/_payment/test_refundedpayment.py +++ b/tests/_payment/test_refundedpayment.py @@ -25,15 +25,15 @@ @pytest.fixture(scope="module") def refunded_payment(): return RefundedPayment( - TestRefundedPaymentBase.currency, - TestRefundedPaymentBase.total_amount, - TestRefundedPaymentBase.invoice_payload, - TestRefundedPaymentBase.telegram_payment_charge_id, - TestRefundedPaymentBase.provider_payment_charge_id, + RefundedPaymentTestBase.currency, + RefundedPaymentTestBase.total_amount, + RefundedPaymentTestBase.invoice_payload, + RefundedPaymentTestBase.telegram_payment_charge_id, + RefundedPaymentTestBase.provider_payment_charge_id, ) -class TestRefundedPaymentBase: +class RefundedPaymentTestBase: invoice_payload = "invoice_payload" currency = "EUR" total_amount = 100 @@ -41,7 +41,7 @@ class TestRefundedPaymentBase: provider_payment_charge_id = "provider_payment_charge_id" -class TestRefundedPaymentWithoutRequest(TestRefundedPaymentBase): +class TestRefundedPaymentWithoutRequest(RefundedPaymentTestBase): def test_slot_behaviour(self, refunded_payment): inst = refunded_payment for attr in inst.__slots__: diff --git a/tests/_payment/test_shippingaddress.py b/tests/_payment/test_shippingaddress.py index ee69fded956..41fbeba5a16 100644 --- a/tests/_payment/test_shippingaddress.py +++ b/tests/_payment/test_shippingaddress.py @@ -25,16 +25,16 @@ @pytest.fixture(scope="module") def shipping_address(): return ShippingAddress( - TestShippingAddressBase.country_code, - TestShippingAddressBase.state, - TestShippingAddressBase.city, - TestShippingAddressBase.street_line1, - TestShippingAddressBase.street_line2, - TestShippingAddressBase.post_code, + ShippingAddressTestBase.country_code, + ShippingAddressTestBase.state, + ShippingAddressTestBase.city, + ShippingAddressTestBase.street_line1, + ShippingAddressTestBase.street_line2, + ShippingAddressTestBase.post_code, ) -class TestShippingAddressBase: +class ShippingAddressTestBase: country_code = "GB" state = "state" city = "London" @@ -43,7 +43,7 @@ class TestShippingAddressBase: post_code = "WC1" -class TestShippingAddressWithoutRequest(TestShippingAddressBase): +class TestShippingAddressWithoutRequest(ShippingAddressTestBase): def test_slot_behaviour(self, shipping_address): inst = shipping_address for attr in inst.__slots__: diff --git a/tests/_payment/test_shippingoption.py b/tests/_payment/test_shippingoption.py index cc969879056..5ce619488e7 100644 --- a/tests/_payment/test_shippingoption.py +++ b/tests/_payment/test_shippingoption.py @@ -25,17 +25,17 @@ @pytest.fixture(scope="module") def shipping_option(): return ShippingOption( - TestShippingOptionBase.id_, TestShippingOptionBase.title, TestShippingOptionBase.prices + ShippingOptionTestBase.id_, ShippingOptionTestBase.title, ShippingOptionTestBase.prices ) -class TestShippingOptionBase: +class ShippingOptionTestBase: id_ = "id" title = "title" prices = [LabeledPrice("Fish Container", 100), LabeledPrice("Premium Fish Container", 1000)] -class TestShippingOptionWithoutRequest(TestShippingOptionBase): +class TestShippingOptionWithoutRequest(ShippingOptionTestBase): def test_slot_behaviour(self, shipping_option): inst = shipping_option for attr in inst.__slots__: diff --git a/tests/_payment/test_shippingquery.py b/tests/_payment/test_shippingquery.py index bf8fc820d17..4821cbae9c9 100644 --- a/tests/_payment/test_shippingquery.py +++ b/tests/_payment/test_shippingquery.py @@ -31,23 +31,23 @@ @pytest.fixture(scope="module") def shipping_query(bot): sq = ShippingQuery( - TestShippingQueryBase.id_, - TestShippingQueryBase.from_user, - TestShippingQueryBase.invoice_payload, - TestShippingQueryBase.shipping_address, + ShippingQueryTestBase.id_, + ShippingQueryTestBase.from_user, + ShippingQueryTestBase.invoice_payload, + ShippingQueryTestBase.shipping_address, ) sq.set_bot(bot) return sq -class TestShippingQueryBase: +class ShippingQueryTestBase: id_ = "5" invoice_payload = "invoice_payload" from_user = User(0, "", False) shipping_address = ShippingAddress("GB", "", "London", "12 Grimmauld Place", "", "WC1") -class TestShippingQueryWithoutRequest(TestShippingQueryBase): +class TestShippingQueryWithoutRequest(ShippingQueryTestBase): def test_slot_behaviour(self, shipping_query): inst = shipping_query for attr in inst.__slots__: diff --git a/tests/_payment/test_successfulpayment.py b/tests/_payment/test_successfulpayment.py index a93238c537a..c4562d0a87d 100644 --- a/tests/_payment/test_successfulpayment.py +++ b/tests/_payment/test_successfulpayment.py @@ -25,17 +25,17 @@ @pytest.fixture(scope="module") def successful_payment(): return SuccessfulPayment( - 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, + SuccessfulPaymentTestBase.currency, + SuccessfulPaymentTestBase.total_amount, + SuccessfulPaymentTestBase.invoice_payload, + SuccessfulPaymentTestBase.telegram_payment_charge_id, + SuccessfulPaymentTestBase.provider_payment_charge_id, + shipping_option_id=SuccessfulPaymentTestBase.shipping_option_id, + order_info=SuccessfulPaymentTestBase.order_info, ) -class TestSuccessfulPaymentBase: +class SuccessfulPaymentTestBase: invoice_payload = "invoice_payload" shipping_option_id = "shipping_option_id" currency = "EUR" @@ -45,7 +45,7 @@ class TestSuccessfulPaymentBase: provider_payment_charge_id = "provider_payment_charge_id" -class TestSuccessfulPaymentWithoutRequest(TestSuccessfulPaymentBase): +class TestSuccessfulPaymentWithoutRequest(SuccessfulPaymentTestBase): def test_slot_behaviour(self, successful_payment): inst = successful_payment for attr in inst.__slots__: diff --git a/tests/test_birthdate.py b/tests/test_birthdate.py index a5e90d413f8..c22ebd9affd 100644 --- a/tests/test_birthdate.py +++ b/tests/test_birthdate.py @@ -24,7 +24,7 @@ from tests.auxil.slots import mro_slots -class TestBirthdateBase: +class BirthdateTestBase: day = 1 month = 1 year = 2022 @@ -32,10 +32,10 @@ class TestBirthdateBase: @pytest.fixture(scope="module") def birthdate(): - return Birthdate(TestBirthdateBase.day, TestBirthdateBase.month, TestBirthdateBase.year) + return Birthdate(BirthdateTestBase.day, BirthdateTestBase.month, BirthdateTestBase.year) -class TestBirthdateWithoutRequest(TestBirthdateBase): +class TestBirthdateWithoutRequest(BirthdateTestBase): def test_slot_behaviour(self, birthdate): for attr in birthdate.__slots__: assert getattr(birthdate, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_botdescription.py b/tests/test_botdescription.py index 4e84eb558c3..a75a88cb1a7 100644 --- a/tests/test_botdescription.py +++ b/tests/test_botdescription.py @@ -24,20 +24,20 @@ @pytest.fixture(scope="module") def bot_description(bot): - return BotDescription(TestBotDescriptionBase.description) + return BotDescription(BotDescriptionTestBase.description) @pytest.fixture(scope="module") def bot_short_description(bot): - return BotShortDescription(TestBotDescriptionBase.short_description) + return BotShortDescription(BotDescriptionTestBase.short_description) -class TestBotDescriptionBase: +class BotDescriptionTestBase: description = "This is a test description" short_description = "This is a test short description" -class TestBotDescriptionWithoutRequest(TestBotDescriptionBase): +class TestBotDescriptionWithoutRequest(BotDescriptionTestBase): def test_slot_behaviour(self, bot_description): for attr in bot_description.__slots__: assert getattr(bot_description, attr, "err") != "err", f"got extra slot '{attr}'" @@ -64,7 +64,7 @@ def test_equality(self): assert hash(a) != hash(c) -class TestBotShortDescriptionWithoutRequest(TestBotDescriptionBase): +class TestBotShortDescriptionWithoutRequest(BotDescriptionTestBase): def test_slot_behaviour(self, bot_short_description): for attr in bot_short_description.__slots__: assert getattr(bot_short_description, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_botname.py b/tests/test_botname.py index 3fadfa76b4b..4edefae3943 100644 --- a/tests/test_botname.py +++ b/tests/test_botname.py @@ -24,14 +24,14 @@ @pytest.fixture(scope="module") def bot_name(bot): - return BotName(TestBotNameBase.name) + return BotName(BotNameTestBase.name) -class TestBotNameBase: +class BotNameTestBase: name = "This is a test name" -class TestBotNameWithoutRequest(TestBotNameBase): +class TestBotNameWithoutRequest(BotNameTestBase): def test_slot_behaviour(self, bot_name): for attr in bot_name.__slots__: assert getattr(bot_name, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_business.py b/tests/test_business.py index da6838d6d47..735f2e7177a 100644 --- a/tests/test_business.py +++ b/tests/test_business.py @@ -36,7 +36,7 @@ from tests.auxil.slots import mro_slots -class TestBusinessBase: +class BusinessTestBase: id_ = "123" user = User(123, "test_user", False) user_chat_id = 123 @@ -62,58 +62,58 @@ class TestBusinessBase: @pytest.fixture(scope="module") def business_connection(): return BusinessConnection( - TestBusinessBase.id_, - TestBusinessBase.user, - TestBusinessBase.user_chat_id, - TestBusinessBase.date, - TestBusinessBase.can_reply, - TestBusinessBase.is_enabled, + BusinessTestBase.id_, + BusinessTestBase.user, + BusinessTestBase.user_chat_id, + BusinessTestBase.date, + BusinessTestBase.can_reply, + BusinessTestBase.is_enabled, ) @pytest.fixture(scope="module") def business_messages_deleted(): return BusinessMessagesDeleted( - TestBusinessBase.business_connection_id, - TestBusinessBase.chat, - TestBusinessBase.message_ids, + BusinessTestBase.business_connection_id, + BusinessTestBase.chat, + BusinessTestBase.message_ids, ) @pytest.fixture(scope="module") def business_intro(): return BusinessIntro( - TestBusinessBase.title, - TestBusinessBase.message, - TestBusinessBase.sticker, + BusinessTestBase.title, + BusinessTestBase.message, + BusinessTestBase.sticker, ) @pytest.fixture(scope="module") def business_location(): return BusinessLocation( - TestBusinessBase.address, - TestBusinessBase.location, + BusinessTestBase.address, + BusinessTestBase.location, ) @pytest.fixture(scope="module") def business_opening_hours_interval(): return BusinessOpeningHoursInterval( - TestBusinessBase.opening_minute, - TestBusinessBase.closing_minute, + BusinessTestBase.opening_minute, + BusinessTestBase.closing_minute, ) @pytest.fixture(scope="module") def business_opening_hours(): return BusinessOpeningHours( - TestBusinessBase.time_zone_name, - TestBusinessBase.opening_hours, + BusinessTestBase.time_zone_name, + BusinessTestBase.opening_hours, ) -class TestBusinessConnectionWithoutRequest(TestBusinessBase): +class TestBusinessConnectionWithoutRequest(BusinessTestBase): def test_slots(self, business_connection): bc = business_connection for attr in bc.__slots__: @@ -188,7 +188,7 @@ def test_equality(self): assert hash(bc1) != hash(bc3) -class TestBusinessMessagesDeleted(TestBusinessBase): +class TestBusinessMessagesDeleted(BusinessTestBase): def test_slots(self, business_messages_deleted): bmd = business_messages_deleted for attr in bmd.__slots__: @@ -227,7 +227,7 @@ def test_equality(self): assert hash(bmd1) != hash(bmd3) -class TestBusinessIntroWithoutRequest(TestBusinessBase): +class TestBusinessIntroWithoutRequest(BusinessTestBase): def test_slot_behaviour(self, business_intro): intro = business_intro for attr in intro.__slots__: @@ -267,7 +267,7 @@ def test_equality(self): assert hash(intro1) != hash(intro3) -class TestBusinessLocationWithoutRequest(TestBusinessBase): +class TestBusinessLocationWithoutRequest(BusinessTestBase): def test_slot_behaviour(self, business_location): inst = business_location for attr in inst.__slots__: @@ -304,7 +304,7 @@ def test_equality(self): assert hash(blc1) != hash(blc3) -class TestBusinessOpeningHoursIntervalWithoutRequest(TestBusinessBase): +class TestBusinessOpeningHoursIntervalWithoutRequest(BusinessTestBase): def test_slot_behaviour(self, business_opening_hours_interval): inst = business_opening_hours_interval for attr in inst.__slots__: @@ -375,7 +375,7 @@ def test_closing_time(self, closing_minute, expected): assert cached is closing_time -class TestBusinessOpeningHoursWithoutRequest(TestBusinessBase): +class TestBusinessOpeningHoursWithoutRequest(BusinessTestBase): def test_slot_behaviour(self, business_opening_hours): inst = business_opening_hours for attr in inst.__slots__: diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 75c7fc63a33..3131b34f249 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -33,28 +33,28 @@ @pytest.fixture(params=["message", "inline", "inaccessible_message"]) def callback_query(bot, request): cbq = CallbackQuery( - TestCallbackQueryBase.id_, - TestCallbackQueryBase.from_user, - TestCallbackQueryBase.chat_instance, - data=TestCallbackQueryBase.data, - game_short_name=TestCallbackQueryBase.game_short_name, + CallbackQueryTestBase.id_, + CallbackQueryTestBase.from_user, + CallbackQueryTestBase.chat_instance, + data=CallbackQueryTestBase.data, + game_short_name=CallbackQueryTestBase.game_short_name, ) cbq.set_bot(bot) cbq._unfreeze() if request.param == "message": - cbq.message = TestCallbackQueryBase.message + cbq.message = CallbackQueryTestBase.message cbq.message.set_bot(bot) elif request.param == "inline": - cbq.inline_message_id = TestCallbackQueryBase.inline_message_id + cbq.inline_message_id = CallbackQueryTestBase.inline_message_id elif request.param == "inaccessible_message": cbq.message = InaccessibleMessage( - chat=TestCallbackQueryBase.message.chat, - message_id=TestCallbackQueryBase.message.message_id, + chat=CallbackQueryTestBase.message.chat, + message_id=CallbackQueryTestBase.message.message_id, ) return cbq -class TestCallbackQueryBase: +class CallbackQueryTestBase: id_ = "id" from_user = User(1, "test_user", False) chat_instance = "chat_instance" @@ -64,7 +64,7 @@ class TestCallbackQueryBase: game_short_name = "the_game" -class TestCallbackQueryWithoutRequest(TestCallbackQueryBase): +class TestCallbackQueryWithoutRequest(CallbackQueryTestBase): @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 28905934c3c..a3dcd6aa17f 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -34,20 +34,20 @@ @pytest.fixture(scope="module") def chat(bot): chat = Chat( - TestChatBase.id_, - title=TestChatBase.title, - type=TestChatBase.type_, - username=TestChatBase.username, + ChatTestBase.id_, + title=ChatTestBase.title, + type=ChatTestBase.type_, + username=ChatTestBase.username, is_forum=True, - first_name=TestChatBase.first_name, - last_name=TestChatBase.last_name, + first_name=ChatTestBase.first_name, + last_name=ChatTestBase.last_name, ) chat.set_bot(bot) chat._unfreeze() return chat -class TestChatBase: +class ChatTestBase: id_ = -28767330 title = "ToledosPalaceBot - Group" type_ = "group" @@ -57,7 +57,7 @@ class TestChatBase: last_name = "last" -class TestChatWithoutRequest(TestChatBase): +class TestChatWithoutRequest(ChatTestBase): def test_slot_behaviour(self, chat): for attr in chat.__slots__: assert getattr(chat, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_chatfullinfo.py b/tests/test_chatfullinfo.py index ee9d697ca71..7e5bc90baae 100644 --- a/tests/test_chatfullinfo.py +++ b/tests/test_chatfullinfo.py @@ -42,47 +42,47 @@ @pytest.fixture(scope="module") def chat_full_info(bot): chat = ChatFullInfo( - TestChatFullInfoBase.id_, - type=TestChatFullInfoBase.type_, - accent_color_id=TestChatFullInfoBase.accent_color_id, - max_reaction_count=TestChatFullInfoBase.max_reaction_count, - title=TestChatFullInfoBase.title, - username=TestChatFullInfoBase.username, - sticker_set_name=TestChatFullInfoBase.sticker_set_name, - can_set_sticker_set=TestChatFullInfoBase.can_set_sticker_set, - permissions=TestChatFullInfoBase.permissions, - slow_mode_delay=TestChatFullInfoBase.slow_mode_delay, - bio=TestChatFullInfoBase.bio, - linked_chat_id=TestChatFullInfoBase.linked_chat_id, - location=TestChatFullInfoBase.location, - has_private_forwards=TestChatFullInfoBase.has_private_forwards, - has_protected_content=TestChatFullInfoBase.has_protected_content, - has_visible_history=TestChatFullInfoBase.has_visible_history, - join_to_send_messages=TestChatFullInfoBase.join_to_send_messages, - join_by_request=TestChatFullInfoBase.join_by_request, + ChatFullInfoTestBase.id_, + type=ChatFullInfoTestBase.type_, + accent_color_id=ChatFullInfoTestBase.accent_color_id, + max_reaction_count=ChatFullInfoTestBase.max_reaction_count, + title=ChatFullInfoTestBase.title, + username=ChatFullInfoTestBase.username, + sticker_set_name=ChatFullInfoTestBase.sticker_set_name, + can_set_sticker_set=ChatFullInfoTestBase.can_set_sticker_set, + permissions=ChatFullInfoTestBase.permissions, + slow_mode_delay=ChatFullInfoTestBase.slow_mode_delay, + bio=ChatFullInfoTestBase.bio, + linked_chat_id=ChatFullInfoTestBase.linked_chat_id, + location=ChatFullInfoTestBase.location, + has_private_forwards=ChatFullInfoTestBase.has_private_forwards, + has_protected_content=ChatFullInfoTestBase.has_protected_content, + has_visible_history=ChatFullInfoTestBase.has_visible_history, + join_to_send_messages=ChatFullInfoTestBase.join_to_send_messages, + join_by_request=ChatFullInfoTestBase.join_by_request, has_restricted_voice_and_video_messages=( - TestChatFullInfoBase.has_restricted_voice_and_video_messages + ChatFullInfoTestBase.has_restricted_voice_and_video_messages ), - is_forum=TestChatFullInfoBase.is_forum, - active_usernames=TestChatFullInfoBase.active_usernames, - emoji_status_custom_emoji_id=TestChatFullInfoBase.emoji_status_custom_emoji_id, - emoji_status_expiration_date=TestChatFullInfoBase.emoji_status_expiration_date, - has_aggressive_anti_spam_enabled=TestChatFullInfoBase.has_aggressive_anti_spam_enabled, - has_hidden_members=TestChatFullInfoBase.has_hidden_members, - available_reactions=TestChatFullInfoBase.available_reactions, - background_custom_emoji_id=TestChatFullInfoBase.background_custom_emoji_id, - profile_accent_color_id=TestChatFullInfoBase.profile_accent_color_id, - profile_background_custom_emoji_id=TestChatFullInfoBase.profile_background_custom_emoji_id, - unrestrict_boost_count=TestChatFullInfoBase.unrestrict_boost_count, - custom_emoji_sticker_set_name=TestChatFullInfoBase.custom_emoji_sticker_set_name, - business_intro=TestChatFullInfoBase.business_intro, - business_location=TestChatFullInfoBase.business_location, - business_opening_hours=TestChatFullInfoBase.business_opening_hours, - birthdate=TestChatFullInfoBase.birthdate, - personal_chat=TestChatFullInfoBase.personal_chat, - first_name=TestChatFullInfoBase.first_name, - last_name=TestChatFullInfoBase.last_name, - can_send_paid_media=TestChatFullInfoBase.can_send_paid_media, + is_forum=ChatFullInfoTestBase.is_forum, + active_usernames=ChatFullInfoTestBase.active_usernames, + emoji_status_custom_emoji_id=ChatFullInfoTestBase.emoji_status_custom_emoji_id, + emoji_status_expiration_date=ChatFullInfoTestBase.emoji_status_expiration_date, + has_aggressive_anti_spam_enabled=ChatFullInfoTestBase.has_aggressive_anti_spam_enabled, + has_hidden_members=ChatFullInfoTestBase.has_hidden_members, + available_reactions=ChatFullInfoTestBase.available_reactions, + background_custom_emoji_id=ChatFullInfoTestBase.background_custom_emoji_id, + profile_accent_color_id=ChatFullInfoTestBase.profile_accent_color_id, + profile_background_custom_emoji_id=ChatFullInfoTestBase.profile_background_custom_emoji_id, + unrestrict_boost_count=ChatFullInfoTestBase.unrestrict_boost_count, + custom_emoji_sticker_set_name=ChatFullInfoTestBase.custom_emoji_sticker_set_name, + business_intro=ChatFullInfoTestBase.business_intro, + business_location=ChatFullInfoTestBase.business_location, + business_opening_hours=ChatFullInfoTestBase.business_opening_hours, + birthdate=ChatFullInfoTestBase.birthdate, + personal_chat=ChatFullInfoTestBase.personal_chat, + first_name=ChatFullInfoTestBase.first_name, + last_name=ChatFullInfoTestBase.last_name, + can_send_paid_media=ChatFullInfoTestBase.can_send_paid_media, ) chat.set_bot(bot) chat._unfreeze() @@ -90,7 +90,7 @@ def chat_full_info(bot): # Shortcut methods are tested in test_chat.py. -class TestChatFullInfoBase: +class ChatFullInfoTestBase: id_ = -28767330 max_reaction_count = 2 title = "ToledosPalaceBot - Group" @@ -142,7 +142,7 @@ class TestChatFullInfoBase: can_send_paid_media = True -class TestChatFullInfoWithoutRequest(TestChatFullInfoBase): +class TestChatFullInfoWithoutRequest(ChatFullInfoTestBase): def test_slot_behaviour(self, chat_full_info): cfi = chat_full_info for attr in cfi.__slots__: diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 2a4007986b3..9331166b466 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -33,21 +33,21 @@ def creator(): @pytest.fixture(scope="module") def invite_link(creator): return ChatInviteLink( - TestChatInviteLinkBase.link, + ChatInviteLinkTestBase.link, creator, - 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, - subscription_period=TestChatInviteLinkBase.subscription_period, - subscription_price=TestChatInviteLinkBase.subscription_price, + ChatInviteLinkTestBase.creates_join_request, + ChatInviteLinkTestBase.primary, + ChatInviteLinkTestBase.revoked, + expire_date=ChatInviteLinkTestBase.expire_date, + member_limit=ChatInviteLinkTestBase.member_limit, + name=ChatInviteLinkTestBase.name, + pending_join_request_count=ChatInviteLinkTestBase.pending_join_request_count, + subscription_period=ChatInviteLinkTestBase.subscription_period, + subscription_price=ChatInviteLinkTestBase.subscription_price, ) -class TestChatInviteLinkBase: +class ChatInviteLinkTestBase: link = "thisialink" creates_join_request = False primary = True @@ -60,7 +60,7 @@ class TestChatInviteLinkBase: subscription_price = 44 -class TestChatInviteLinkWithoutRequest(TestChatInviteLinkBase): +class TestChatInviteLinkWithoutRequest(ChatInviteLinkTestBase): def test_slot_behaviour(self, 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 3d8b19386de..cdf2787e8ea 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -38,18 +38,18 @@ def time(): @pytest.fixture(scope="module") def chat_join_request(bot, time): cjr = ChatJoinRequest( - chat=TestChatJoinRequestBase.chat, - from_user=TestChatJoinRequestBase.from_user, + chat=ChatJoinRequestTestBase.chat, + from_user=ChatJoinRequestTestBase.from_user, date=time, - bio=TestChatJoinRequestBase.bio, - invite_link=TestChatJoinRequestBase.invite_link, - user_chat_id=TestChatJoinRequestBase.from_user.id, + bio=ChatJoinRequestTestBase.bio, + invite_link=ChatJoinRequestTestBase.invite_link, + user_chat_id=ChatJoinRequestTestBase.from_user.id, ) cjr.set_bot(bot) return cjr -class TestChatJoinRequestBase: +class ChatJoinRequestTestBase: chat = Chat(1, Chat.SUPERGROUP) from_user = User(2, "first_name", False) bio = "bio" @@ -63,7 +63,7 @@ class TestChatJoinRequestBase: ) -class TestChatJoinRequestWithoutRequest(TestChatJoinRequestBase): +class TestChatJoinRequestWithoutRequest(ChatJoinRequestTestBase): def test_slot_behaviour(self, chat_join_request): inst = chat_join_request for attr in inst.__slots__: diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index a57d157cce1..00481d644d5 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -25,15 +25,15 @@ @pytest.fixture(scope="module") def chat_location(): - return ChatLocation(TestChatLocationBase.location, TestChatLocationBase.address) + return ChatLocation(ChatLocationTestBase.location, ChatLocationTestBase.address) -class TestChatLocationBase: +class ChatLocationTestBase: location = Location(123, 456) address = "The Shire" -class TestChatLocationWithoutRequest(TestChatLocationBase): +class TestChatLocationWithoutRequest(ChatLocationTestBase): def test_slot_behaviour(self, chat_location): inst = chat_location for attr in inst.__slots__: diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index 0efbcd8d0ab..33b07863a5a 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -47,7 +47,7 @@ def chat(): @pytest.fixture(scope="module") def old_chat_member(user): - return ChatMember(user, TestChatMemberUpdatedBase.old_status) + return ChatMember(user, ChatMemberUpdatedTestBase.old_status) @pytest.fixture(scope="module") @@ -66,7 +66,7 @@ def new_chat_member(user): True, True, True, - custom_title=TestChatMemberUpdatedBase.new_status, + custom_title=ChatMemberUpdatedTestBase.new_status, ) @@ -87,12 +87,12 @@ def chat_member_updated(user, chat, old_chat_member, new_chat_member, invite_lin ) -class TestChatMemberUpdatedBase: +class ChatMemberUpdatedTestBase: old_status = ChatMember.MEMBER new_status = ChatMember.ADMINISTRATOR -class TestChatMemberUpdatedWithoutRequest(TestChatMemberUpdatedBase): +class TestChatMemberUpdatedWithoutRequest(ChatMemberUpdatedTestBase): def test_slot_behaviour(self, 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 9317de22769..79b6bab8081 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -43,7 +43,7 @@ def chat_permissions(): ) -class TestChatPermissionsBase: +class ChatPermissionsTestBase: can_send_messages = True can_send_polls = True can_send_other_messages = False @@ -60,7 +60,7 @@ class TestChatPermissionsBase: can_send_voice_notes = None -class TestChatPermissionsWithoutRequest(TestChatPermissionsBase): +class TestChatPermissionsWithoutRequest(ChatPermissionsTestBase): def test_slot_behaviour(self, chat_permissions): inst = chat_permissions for attr in inst.__slots__: diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index d1cb3622649..2b53b684770 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -33,16 +33,16 @@ def user(): @pytest.fixture(scope="module") def chosen_inline_result(user): return ChosenInlineResult( - TestChosenInlineResultBase.result_id, user, TestChosenInlineResultBase.query + ChosenInlineResultTestBase.result_id, user, ChosenInlineResultTestBase.query ) -class TestChosenInlineResultBase: +class ChosenInlineResultTestBase: result_id = "result id" query = "query text" -class TestChosenInlineResultWithoutRequest(TestChosenInlineResultBase): +class TestChosenInlineResultWithoutRequest(ChosenInlineResultTestBase): def test_slot_behaviour(self, chosen_inline_result): inst = chosen_inline_result for attr in inst.__slots__: diff --git a/tests/test_dice.py b/tests/test_dice.py index 53242efa770..df3c349d4d7 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -28,11 +28,11 @@ def dice(request): return Dice(value=5, emoji=request.param) -class TestDiceBase: +class DiceTestBase: value = 4 -class TestDiceWithoutRequest(TestDiceBase): +class TestDiceWithoutRequest(DiceTestBase): def test_slot_behaviour(self, dice): for attr in dice.__slots__: assert getattr(dice, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_forcereply.py b/tests/test_forcereply.py index ca9d7cae5ed..e4e2b5b5dda 100644 --- a/tests/test_forcereply.py +++ b/tests/test_forcereply.py @@ -25,16 +25,16 @@ @pytest.fixture(scope="module") def force_reply(): - return ForceReply(TestForceReplyBase.selective, TestForceReplyBase.input_field_placeholder) + return ForceReply(ForceReplyTestBase.selective, ForceReplyTestBase.input_field_placeholder) -class TestForceReplyBase: +class ForceReplyTestBase: force_reply = True selective = True input_field_placeholder = "force replies can be annoying if not used properly" -class TestForceReplyWithoutRequest(TestForceReplyBase): +class TestForceReplyWithoutRequest(ForceReplyTestBase): def test_slot_behaviour(self, force_reply): for attr in force_reply.__slots__: assert getattr(force_reply, attr, "err") != "err", f"got extra slot '{attr}'" @@ -69,7 +69,7 @@ def test_equality(self): assert hash(a) != hash(d) -class TestForceReplyWithRequest(TestForceReplyBase): +class TestForceReplyWithRequest(ForceReplyTestBase): 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_inlinequeryresultsbutton.py b/tests/test_inlinequeryresultsbutton.py index 2c6ad4336c2..90ce2c235ac 100644 --- a/tests/test_inlinequeryresultsbutton.py +++ b/tests/test_inlinequeryresultsbutton.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="module") def inline_query_results_button(): return InlineQueryResultsButton( - text=TestInlineQueryResultsButtonBase.text, - start_parameter=TestInlineQueryResultsButtonBase.start_parameter, - web_app=TestInlineQueryResultsButtonBase.web_app, + text=InlineQueryResultsButtonTestBase.text, + start_parameter=InlineQueryResultsButtonTestBase.start_parameter, + web_app=InlineQueryResultsButtonTestBase.web_app, ) -class TestInlineQueryResultsButtonBase: +class InlineQueryResultsButtonTestBase: text = "text" start_parameter = "start_parameter" web_app = WebAppInfo(url="https://python-telegram-bot.org") -class TestInlineQueryResultsButtonWithoutRequest(TestInlineQueryResultsButtonBase): +class TestInlineQueryResultsButtonWithoutRequest(InlineQueryResultsButtonTestBase): def test_slot_behaviour(self, inline_query_results_button): inst = inline_query_results_button for attr in inst.__slots__: diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index edd45cc9a8b..4493ed22320 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -32,17 +32,17 @@ @pytest.fixture(scope="module") def keyboard_button(): return KeyboardButton( - TestKeyboardButtonBase.text, - request_location=TestKeyboardButtonBase.request_location, - request_contact=TestKeyboardButtonBase.request_contact, - request_poll=TestKeyboardButtonBase.request_poll, - web_app=TestKeyboardButtonBase.web_app, - request_chat=TestKeyboardButtonBase.request_chat, - request_users=TestKeyboardButtonBase.request_users, + KeyboardButtonTestBase.text, + request_location=KeyboardButtonTestBase.request_location, + request_contact=KeyboardButtonTestBase.request_contact, + request_poll=KeyboardButtonTestBase.request_poll, + web_app=KeyboardButtonTestBase.web_app, + request_chat=KeyboardButtonTestBase.request_chat, + request_users=KeyboardButtonTestBase.request_users, ) -class TestKeyboardButtonBase: +class KeyboardButtonTestBase: text = "text" request_location = True request_contact = True @@ -52,7 +52,7 @@ class TestKeyboardButtonBase: request_users = KeyboardButtonRequestUsers(2) -class TestKeyboardButtonWithoutRequest(TestKeyboardButtonBase): +class TestKeyboardButtonWithoutRequest(KeyboardButtonTestBase): def test_slot_behaviour(self, keyboard_button): inst = keyboard_button for attr in inst.__slots__: diff --git a/tests/test_keyboardbuttonpolltype.py b/tests/test_keyboardbuttonpolltype.py index 2d4f0dd5b17..6c4e92bf2ca 100644 --- a/tests/test_keyboardbuttonpolltype.py +++ b/tests/test_keyboardbuttonpolltype.py @@ -25,14 +25,14 @@ @pytest.fixture(scope="module") def keyboard_button_poll_type(): - return KeyboardButtonPollType(TestKeyboardButtonPollTypeBase.type) + return KeyboardButtonPollType(KeyboardButtonPollTypeTestBase.type) -class TestKeyboardButtonPollTypeBase: +class KeyboardButtonPollTypeTestBase: type = Poll.QUIZ -class TestKeyboardButtonPollTypeWithoutRequest(TestKeyboardButtonPollTypeBase): +class TestKeyboardButtonPollTypeWithoutRequest(KeyboardButtonPollTypeTestBase): def test_slot_behaviour(self, keyboard_button_poll_type): inst = keyboard_button_poll_type for attr in inst.__slots__: diff --git a/tests/test_keyboardbuttonrequest.py b/tests/test_keyboardbuttonrequest.py index 8678fd08d8e..8e42b1cd374 100644 --- a/tests/test_keyboardbuttonrequest.py +++ b/tests/test_keyboardbuttonrequest.py @@ -26,21 +26,21 @@ @pytest.fixture(scope="class") def request_users(): return KeyboardButtonRequestUsers( - TestKeyboardButtonRequestUsersBase.request_id, - TestKeyboardButtonRequestUsersBase.user_is_bot, - TestKeyboardButtonRequestUsersBase.user_is_premium, - TestKeyboardButtonRequestUsersBase.max_quantity, + KeyboardButtonRequestUsersTestBase.request_id, + KeyboardButtonRequestUsersTestBase.user_is_bot, + KeyboardButtonRequestUsersTestBase.user_is_premium, + KeyboardButtonRequestUsersTestBase.max_quantity, ) -class TestKeyboardButtonRequestUsersBase: +class KeyboardButtonRequestUsersTestBase: request_id = 123 user_is_bot = True user_is_premium = False max_quantity = 10 -class TestKeyboardButtonRequestUsersWithoutRequest(TestKeyboardButtonRequestUsersBase): +class TestKeyboardButtonRequestUsersWithoutRequest(KeyboardButtonRequestUsersTestBase): def test_slot_behaviour(self, request_users): for attr in request_users.__slots__: assert getattr(request_users, attr, "err") != "err", f"got extra slot '{attr}'" @@ -88,18 +88,18 @@ def test_equality(self): @pytest.fixture(scope="class") def request_chat(): return KeyboardButtonRequestChat( - TestKeyboardButtonRequestChatBase.request_id, - TestKeyboardButtonRequestChatBase.chat_is_channel, - TestKeyboardButtonRequestChatBase.chat_is_forum, - TestKeyboardButtonRequestChatBase.chat_has_username, - TestKeyboardButtonRequestChatBase.chat_is_created, - TestKeyboardButtonRequestChatBase.user_administrator_rights, - TestKeyboardButtonRequestChatBase.bot_administrator_rights, - TestKeyboardButtonRequestChatBase.bot_is_member, + KeyboardButtonRequestChatTestBase.request_id, + KeyboardButtonRequestChatTestBase.chat_is_channel, + KeyboardButtonRequestChatTestBase.chat_is_forum, + KeyboardButtonRequestChatTestBase.chat_has_username, + KeyboardButtonRequestChatTestBase.chat_is_created, + KeyboardButtonRequestChatTestBase.user_administrator_rights, + KeyboardButtonRequestChatTestBase.bot_administrator_rights, + KeyboardButtonRequestChatTestBase.bot_is_member, ) -class TestKeyboardButtonRequestChatBase: +class KeyboardButtonRequestChatTestBase: request_id = 456 chat_is_channel = True chat_is_forum = False @@ -134,7 +134,7 @@ class TestKeyboardButtonRequestChatBase: bot_is_member = True -class TestKeyboardButtonRequestChatWithoutRequest(TestKeyboardButtonRequestChatBase): +class TestKeyboardButtonRequestChatWithoutRequest(KeyboardButtonRequestChatTestBase): def test_slot_behaviour(self, request_chat): for attr in request_chat.__slots__: assert getattr(request_chat, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_linkpreviewoptions.py b/tests/test_linkpreviewoptions.py index 7b5bc7beb8b..a4fa5aea455 100644 --- a/tests/test_linkpreviewoptions.py +++ b/tests/test_linkpreviewoptions.py @@ -25,15 +25,15 @@ @pytest.fixture(scope="module") def link_preview_options(): return LinkPreviewOptions( - is_disabled=TestLinkPreviewOptionsBase.is_disabled, - url=TestLinkPreviewOptionsBase.url, - prefer_small_media=TestLinkPreviewOptionsBase.prefer_small_media, - prefer_large_media=TestLinkPreviewOptionsBase.prefer_large_media, - show_above_text=TestLinkPreviewOptionsBase.show_above_text, + is_disabled=LinkPreviewOptionsTestBase.is_disabled, + url=LinkPreviewOptionsTestBase.url, + prefer_small_media=LinkPreviewOptionsTestBase.prefer_small_media, + prefer_large_media=LinkPreviewOptionsTestBase.prefer_large_media, + show_above_text=LinkPreviewOptionsTestBase.show_above_text, ) -class TestLinkPreviewOptionsBase: +class LinkPreviewOptionsTestBase: is_disabled = True url = "https://www.example.com" prefer_small_media = True @@ -41,7 +41,7 @@ class TestLinkPreviewOptionsBase: show_above_text = True -class TestLinkPreviewOptionsWithoutRequest(TestLinkPreviewOptionsBase): +class TestLinkPreviewOptionsWithoutRequest(LinkPreviewOptionsTestBase): def test_slot_behaviour(self, link_preview_options): a = link_preview_options for attr in a.__slots__: diff --git a/tests/test_loginurl.py b/tests/test_loginurl.py index a9f69699b5f..2fd84e97e23 100644 --- a/tests/test_loginurl.py +++ b/tests/test_loginurl.py @@ -25,21 +25,21 @@ @pytest.fixture(scope="module") def login_url(): return LoginUrl( - url=TestLoginUrlBase.url, - forward_text=TestLoginUrlBase.forward_text, - bot_username=TestLoginUrlBase.bot_username, - request_write_access=TestLoginUrlBase.request_write_access, + url=LoginUrlTestBase.url, + forward_text=LoginUrlTestBase.forward_text, + bot_username=LoginUrlTestBase.bot_username, + request_write_access=LoginUrlTestBase.request_write_access, ) -class TestLoginUrlBase: +class LoginUrlTestBase: url = "http://www.google.com" forward_text = "Send me forward!" bot_username = "botname" request_write_access = True -class TestLoginUrlWithoutRequest(TestLoginUrlBase): +class TestLoginUrlWithoutRequest(LoginUrlTestBase): def test_slot_behaviour(self, login_url): for attr in login_url.__slots__: assert getattr(login_url, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_maybeinaccessiblemessage.py b/tests/test_maybeinaccessiblemessage.py index 2c6617af8f4..da7db43ce0e 100644 --- a/tests/test_maybeinaccessiblemessage.py +++ b/tests/test_maybeinaccessiblemessage.py @@ -29,19 +29,19 @@ @pytest.fixture(scope="class") def maybe_inaccessible_message(): return MaybeInaccessibleMessage( - TestMaybeInaccessibleMessageBase.chat, - TestMaybeInaccessibleMessageBase.message_id, - TestMaybeInaccessibleMessageBase.date, + MaybeInaccessibleMessageTestBase.chat, + MaybeInaccessibleMessageTestBase.message_id, + MaybeInaccessibleMessageTestBase.date, ) -class TestMaybeInaccessibleMessageBase: +class MaybeInaccessibleMessageTestBase: chat = Chat(1, "title") message_id = 123 date = dtm.datetime.now(dtm.timezone.utc).replace(microsecond=0) -class TestMaybeInaccessibleMessageWithoutRequest(TestMaybeInaccessibleMessageBase): +class TestMaybeInaccessibleMessageWithoutRequest(MaybeInaccessibleMessageTestBase): def test_slot_behaviour(self, maybe_inaccessible_message): for attr in maybe_inaccessible_message.__slots__: assert ( diff --git a/tests/test_menubutton.py b/tests/test_menubutton.py index 48c9c30c9f2..d5930f805c2 100644 --- a/tests/test_menubutton.py +++ b/tests/test_menubutton.py @@ -84,20 +84,20 @@ def menu_button(scope_class_and_type): return scope_class_and_type[0].de_json( { "type": scope_class_and_type[1], - "text": TestMenuButtonselfBase.text, - "web_app": TestMenuButtonselfBase.web_app.to_dict(), + "text": MenuButtonTestBase.text, + "web_app": MenuButtonTestBase.web_app.to_dict(), }, bot=None, ) -class TestMenuButtonselfBase: +class MenuButtonTestBase: 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(TestMenuButtonselfBase): +class TestMenuButtonWithoutRequest(MenuButtonTestBase): def test_slot_behaviour(self, menu_button): 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 3cf237a5537..84b2b7c3929 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -93,10 +93,10 @@ @pytest.fixture def message(bot): message = PytestMessage( - message_id=TestMessageBase.id_, - date=TestMessageBase.date, - chat=copy(TestMessageBase.chat), - from_user=copy(TestMessageBase.from_user), + message_id=MessageTestBase.id_, + date=MessageTestBase.date, + chat=copy(MessageTestBase.chat), + from_user=copy(MessageTestBase.from_user), business_connection_id="123456789", ) message.set_bot(bot) @@ -357,17 +357,17 @@ def message(bot): ) def message_params(bot, request): message = Message( - message_id=TestMessageBase.id_, - from_user=TestMessageBase.from_user, - date=TestMessageBase.date, - chat=TestMessageBase.chat, + message_id=MessageTestBase.id_, + from_user=MessageTestBase.from_user, + date=MessageTestBase.date, + chat=MessageTestBase.chat, **request.param, ) message.set_bot(bot) return message -class TestMessageBase: +class MessageTestBase: id_ = 1 from_user = User(2, "testuser", False) date = datetime.utcnow() @@ -439,7 +439,7 @@ class TestMessageBase: ) -class TestMessageWithoutRequest(TestMessageBase): +class TestMessageWithoutRequest(MessageTestBase): @staticmethod async def check_quote_parsing( message: Message, method, bot_method_name: str, args, monkeypatch @@ -559,10 +559,10 @@ async def extract_message_thread_id(*args, **kwargs): def test_slot_behaviour(self): message = Message( - message_id=TestMessageBase.id_, - date=TestMessageBase.date, - chat=copy(TestMessageBase.chat), - from_user=copy(TestMessageBase.from_user), + message_id=MessageTestBase.id_, + date=MessageTestBase.date, + chat=copy(MessageTestBase.chat), + from_user=copy(MessageTestBase.from_user), ) for attr in message.__slots__: assert getattr(message, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 2fc21ea493c..3598454d8eb 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -41,14 +41,14 @@ def message_entity(request): return MessageEntity(type_, 1, 3, url=url, user=user, language=language) -class TestMessageEntityBase: +class MessageEntityTestBase: type_ = "url" offset = 1 length = 2 url = "url" -class TestMessageEntityWithoutRequest(TestMessageEntityBase): +class TestMessageEntityWithoutRequest(MessageEntityTestBase): def test_slot_behaviour(self, message_entity): inst = message_entity for attr in inst.__slots__: diff --git a/tests/test_paidmedia.py b/tests/test_paidmedia.py index f76bcf6310f..be9ac14905b 100644 --- a/tests/test_paidmedia.py +++ b/tests/test_paidmedia.py @@ -96,33 +96,33 @@ def paid_media(pm_scope_class_and_type): return pm_scope_class_and_type[0].de_json( { "type": pm_scope_class_and_type[1], - "width": TestPaidMediaBase.width, - "height": TestPaidMediaBase.height, - "duration": TestPaidMediaBase.duration, - "video": TestPaidMediaBase.video.to_dict(), - "photo": [p.to_dict() for p in TestPaidMediaBase.photo], + "width": PaidMediaTestBase.width, + "height": PaidMediaTestBase.height, + "duration": PaidMediaTestBase.duration, + "video": PaidMediaTestBase.video.to_dict(), + "photo": [p.to_dict() for p in PaidMediaTestBase.photo], }, bot=None, ) def paid_media_video(): - return PaidMediaVideo(video=TestPaidMediaBase.video) + return PaidMediaVideo(video=PaidMediaTestBase.video) def paid_media_photo(): - return PaidMediaPhoto(photo=TestPaidMediaBase.photo) + return PaidMediaPhoto(photo=PaidMediaTestBase.photo) @pytest.fixture(scope="module") def paid_media_info(): return PaidMediaInfo( - star_count=TestPaidMediaInfoBase.star_count, + star_count=PaidMediaInfoTestBase.star_count, paid_media=[paid_media_video(), paid_media_photo()], ) -class TestPaidMediaBase: +class PaidMediaTestBase: width = 640 height = 480 duration = 60 @@ -143,7 +143,7 @@ class TestPaidMediaBase: ) -class TestPaidMediaWithoutRequest(TestPaidMediaBase): +class TestPaidMediaWithoutRequest(PaidMediaTestBase): def test_slot_behaviour(self, paid_media): inst = paid_media for attr in inst.__slots__: @@ -280,12 +280,12 @@ def test_equality(self, paid_media, bot): assert hash(c) != hash(f) -class TestPaidMediaInfoBase: +class PaidMediaInfoTestBase: star_count = 200 paid_media = [paid_media_video(), paid_media_photo()] -class TestPaidMediaInfoWithoutRequest(TestPaidMediaInfoBase): +class TestPaidMediaInfoWithoutRequest(PaidMediaInfoTestBase): def test_slot_behaviour(self, paid_media_info): inst = paid_media_info for attr in inst.__slots__: diff --git a/tests/test_poll.py b/tests/test_poll.py index 92c58339daf..81619a11299 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -28,15 +28,15 @@ @pytest.fixture(scope="module") def input_poll_option(): out = InputPollOption( - text=TestInputPollOptionBase.text, - text_parse_mode=TestInputPollOptionBase.text_parse_mode, - text_entities=TestInputPollOptionBase.text_entities, + text=InputPollOptionTestBase.text, + text_parse_mode=InputPollOptionTestBase.text_parse_mode, + text_entities=InputPollOptionTestBase.text_entities, ) out._unfreeze() return out -class TestInputPollOptionBase: +class InputPollOptionTestBase: text = "test option" text_parse_mode = "MarkdownV2" text_entities = [ @@ -45,7 +45,7 @@ class TestInputPollOptionBase: ] -class TestInputPollOptionWithoutRequest(TestInputPollOptionBase): +class TestInputPollOptionWithoutRequest(InputPollOptionTestBase): def test_slot_behaviour(self, input_poll_option): for attr in input_poll_option.__slots__: assert getattr(input_poll_option, attr, "err") != "err", f"got extra slot '{attr}'" @@ -106,15 +106,15 @@ def test_equality(self): @pytest.fixture(scope="module") def poll_option(): out = PollOption( - text=TestPollOptionBase.text, - voter_count=TestPollOptionBase.voter_count, - text_entities=TestPollOptionBase.text_entities, + text=PollOptionTestBase.text, + voter_count=PollOptionTestBase.voter_count, + text_entities=PollOptionTestBase.text_entities, ) out._unfreeze() return out -class TestPollOptionBase: +class PollOptionTestBase: text = "test option" voter_count = 3 text_entities = [ @@ -123,7 +123,7 @@ class TestPollOptionBase: ] -class TestPollOptionWithoutRequest(TestPollOptionBase): +class TestPollOptionWithoutRequest(PollOptionTestBase): def test_slot_behaviour(self, poll_option): for attr in poll_option.__slots__: assert getattr(poll_option, attr, "err") != "err", f"got extra slot '{attr}'" @@ -198,21 +198,21 @@ def test_equality(self): @pytest.fixture(scope="module") def poll_answer(): return PollAnswer( - TestPollAnswerBase.poll_id, - TestPollAnswerBase.option_ids, - TestPollAnswerBase.user, - TestPollAnswerBase.voter_chat, + PollAnswerTestBase.poll_id, + PollAnswerTestBase.option_ids, + PollAnswerTestBase.user, + PollAnswerTestBase.voter_chat, ) -class TestPollAnswerBase: +class PollAnswerTestBase: poll_id = "id" option_ids = [2] user = User(1, "", False) voter_chat = Chat(1, "") -class TestPollAnswerWithoutRequest(TestPollAnswerBase): +class TestPollAnswerWithoutRequest(PollAnswerTestBase): def test_de_json(self): json_dict = { "poll_id": self.poll_id, @@ -264,25 +264,25 @@ def test_equality(self): @pytest.fixture(scope="module") def poll(): poll = Poll( - 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, - question_entities=TestPollBase.question_entities, + PollTestBase.id_, + PollTestBase.question, + PollTestBase.options, + PollTestBase.total_voter_count, + PollTestBase.is_closed, + PollTestBase.is_anonymous, + PollTestBase.type, + PollTestBase.allows_multiple_answers, + explanation=PollTestBase.explanation, + explanation_entities=PollTestBase.explanation_entities, + open_period=PollTestBase.open_period, + close_date=PollTestBase.close_date, + question_entities=PollTestBase.question_entities, ) poll._unfreeze() return poll -class TestPollBase: +class PollTestBase: id_ = "id" question = "Test Question?" options = [PollOption("test", 10), PollOption("test2", 11)] @@ -304,7 +304,7 @@ class TestPollBase: ] -class TestPollWithoutRequest(TestPollBase): +class TestPollWithoutRequest(PollTestBase): def test_de_json(self, bot): json_dict = { "id": self.id_, diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index 3db91ffbe0b..de49b699fea 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -25,19 +25,19 @@ @pytest.fixture(scope="module") def proximity_alert_triggered(): return ProximityAlertTriggered( - TestProximityAlertTriggeredBase.traveler, - TestProximityAlertTriggeredBase.watcher, - TestProximityAlertTriggeredBase.distance, + ProximityAlertTriggeredTestBase.traveler, + ProximityAlertTriggeredTestBase.watcher, + ProximityAlertTriggeredTestBase.distance, ) -class TestProximityAlertTriggeredBase: +class ProximityAlertTriggeredTestBase: traveler = User(1, "foo", False) watcher = User(2, "bar", False) distance = 42 -class TestProximityAlertTriggeredWithoutRequest(TestProximityAlertTriggeredBase): +class TestProximityAlertTriggeredWithoutRequest(ProximityAlertTriggeredTestBase): def test_slot_behaviour(self, proximity_alert_triggered): inst = proximity_alert_triggered for attr in inst.__slots__: diff --git a/tests/test_reply.py b/tests/test_reply.py index f41ed01eb59..5cacb7b6b5c 100644 --- a/tests/test_reply.py +++ b/tests/test_reply.py @@ -41,16 +41,16 @@ @pytest.fixture(scope="module") def external_reply_info(): return ExternalReplyInfo( - origin=TestExternalReplyInfoBase.origin, - chat=TestExternalReplyInfoBase.chat, - message_id=TestExternalReplyInfoBase.message_id, - link_preview_options=TestExternalReplyInfoBase.link_preview_options, - giveaway=TestExternalReplyInfoBase.giveaway, - paid_media=TestExternalReplyInfoBase.paid_media, + origin=ExternalReplyInfoTestBase.origin, + chat=ExternalReplyInfoTestBase.chat, + message_id=ExternalReplyInfoTestBase.message_id, + link_preview_options=ExternalReplyInfoTestBase.link_preview_options, + giveaway=ExternalReplyInfoTestBase.giveaway, + paid_media=ExternalReplyInfoTestBase.paid_media, ) -class TestExternalReplyInfoBase: +class ExternalReplyInfoTestBase: origin = MessageOriginUser( dtm.datetime.now(dtm.timezone.utc).replace(microsecond=0), User(1, "user", False) ) @@ -65,7 +65,7 @@ class TestExternalReplyInfoBase: paid_media = PaidMediaInfo(5, [PaidMediaPreview(10, 10, 10)]) -class TestExternalReplyInfoWithoutRequest(TestExternalReplyInfoBase): +class TestExternalReplyInfoWithoutRequest(ExternalReplyInfoTestBase): def test_slot_behaviour(self, external_reply_info): for attr in external_reply_info.__slots__: assert getattr(external_reply_info, attr, "err") != "err", f"got extra slot '{attr}'" @@ -128,14 +128,14 @@ def test_equality(self, external_reply_info): @pytest.fixture(scope="module") def text_quote(): return TextQuote( - text=TestTextQuoteBase.text, - position=TestTextQuoteBase.position, - entities=TestTextQuoteBase.entities, - is_manual=TestTextQuoteBase.is_manual, + text=TextQuoteTestBase.text, + position=TextQuoteTestBase.position, + entities=TextQuoteTestBase.entities, + is_manual=TextQuoteTestBase.is_manual, ) -class TestTextQuoteBase: +class TextQuoteTestBase: text = "text" position = 1 entities = [ @@ -145,7 +145,7 @@ class TestTextQuoteBase: is_manual = True -class TestTextQuoteWithoutRequest(TestTextQuoteBase): +class TestTextQuoteWithoutRequest(TextQuoteTestBase): def test_slot_behaviour(self, text_quote): for attr in text_quote.__slots__: assert getattr(text_quote, attr, "err") != "err", f"got extra slot '{attr}'" @@ -202,17 +202,17 @@ def test_equality(self, text_quote): @pytest.fixture(scope="module") def reply_parameters(): return ReplyParameters( - message_id=TestReplyParametersBase.message_id, - chat_id=TestReplyParametersBase.chat_id, - allow_sending_without_reply=TestReplyParametersBase.allow_sending_without_reply, - quote=TestReplyParametersBase.quote, - quote_parse_mode=TestReplyParametersBase.quote_parse_mode, - quote_entities=TestReplyParametersBase.quote_entities, - quote_position=TestReplyParametersBase.quote_position, + message_id=ReplyParametersTestBase.message_id, + chat_id=ReplyParametersTestBase.chat_id, + allow_sending_without_reply=ReplyParametersTestBase.allow_sending_without_reply, + quote=ReplyParametersTestBase.quote, + quote_parse_mode=ReplyParametersTestBase.quote_parse_mode, + quote_entities=ReplyParametersTestBase.quote_entities, + quote_position=ReplyParametersTestBase.quote_position, ) -class TestReplyParametersBase: +class ReplyParametersTestBase: message_id = 123 chat_id = 456 allow_sending_without_reply = True @@ -225,7 +225,7 @@ class TestReplyParametersBase: quote_position = 5 -class TestReplyParametersWithoutRequest(TestReplyParametersBase): +class TestReplyParametersWithoutRequest(ReplyParametersTestBase): def test_slot_behaviour(self, reply_parameters): for attr in reply_parameters.__slots__: assert getattr(reply_parameters, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index 15654208d2f..68996a246f5 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -26,15 +26,15 @@ @pytest.fixture(scope="module") def reply_keyboard_markup(): return ReplyKeyboardMarkup( - TestReplyKeyboardMarkupBase.keyboard, - resize_keyboard=TestReplyKeyboardMarkupBase.resize_keyboard, - one_time_keyboard=TestReplyKeyboardMarkupBase.one_time_keyboard, - selective=TestReplyKeyboardMarkupBase.selective, - is_persistent=TestReplyKeyboardMarkupBase.is_persistent, + ReplyKeyboardMarkupTestBase.keyboard, + resize_keyboard=ReplyKeyboardMarkupTestBase.resize_keyboard, + one_time_keyboard=ReplyKeyboardMarkupTestBase.one_time_keyboard, + selective=ReplyKeyboardMarkupTestBase.selective, + is_persistent=ReplyKeyboardMarkupTestBase.is_persistent, ) -class TestReplyKeyboardMarkupBase: +class ReplyKeyboardMarkupTestBase: keyboard = [[KeyboardButton("button1"), KeyboardButton("button2")]] resize_keyboard = True one_time_keyboard = True @@ -42,7 +42,7 @@ class TestReplyKeyboardMarkupBase: is_persistent = True -class TestReplyKeyboardMarkupWithoutRequest(TestReplyKeyboardMarkupBase): +class TestReplyKeyboardMarkupWithoutRequest(ReplyKeyboardMarkupTestBase): def test_slot_behaviour(self, reply_keyboard_markup): inst = reply_keyboard_markup for attr in inst.__slots__: @@ -154,7 +154,7 @@ def test_from_column(self): assert len(reply_keyboard_markup[1]) == 1 -class TestReplyKeyboardMarkupWithRequest(TestReplyKeyboardMarkupBase): +class TestReplyKeyboardMarkupWithRequest(ReplyKeyboardMarkupTestBase): 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 f1a771e7f4c..f0054588168 100644 --- a/tests/test_replykeyboardremove.py +++ b/tests/test_replykeyboardremove.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def reply_keyboard_remove(): - return ReplyKeyboardRemove(selective=TestReplyKeyboardRemoveBase.selective) + return ReplyKeyboardRemove(selective=ReplyKeyboardRemoveTestBase.selective) -class TestReplyKeyboardRemoveBase: +class ReplyKeyboardRemoveTestBase: remove_keyboard = True selective = True -class TestReplyKeyboardRemoveWithoutRequest(TestReplyKeyboardRemoveBase): +class TestReplyKeyboardRemoveWithoutRequest(ReplyKeyboardRemoveTestBase): def test_slot_behaviour(self, reply_keyboard_remove): inst = reply_keyboard_remove for attr in inst.__slots__: @@ -52,7 +52,7 @@ def test_to_dict(self, reply_keyboard_remove): assert reply_keyboard_remove_dict["selective"] == reply_keyboard_remove.selective -class TestReplyKeyboardRemoveWithRequest(TestReplyKeyboardRemoveBase): +class TestReplyKeyboardRemoveWithRequest(ReplyKeyboardRemoveTestBase): 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 c523ea09f75..e4bc116d035 100644 --- a/tests/test_sentwebappmessage.py +++ b/tests/test_sentwebappmessage.py @@ -25,14 +25,14 @@ @pytest.fixture(scope="module") def sent_web_app_message(): - return SentWebAppMessage(inline_message_id=TestSentWebAppMessageBase.inline_message_id) + return SentWebAppMessage(inline_message_id=SentWebAppMessageTestBase.inline_message_id) -class TestSentWebAppMessageBase: +class SentWebAppMessageTestBase: inline_message_id = "123" -class TestSentWebAppMessageWithoutRequest(TestSentWebAppMessageBase): +class TestSentWebAppMessageWithoutRequest(SentWebAppMessageTestBase): def test_slot_behaviour(self, sent_web_app_message): inst = sent_web_app_message for attr in inst.__slots__: diff --git a/tests/test_shared.py b/tests/test_shared.py index 53e5fe4d882..c51bcf5ea91 100644 --- a/tests/test_shared.py +++ b/tests/test_shared.py @@ -25,16 +25,16 @@ @pytest.fixture(scope="class") def users_shared(): - return UsersShared(TestUsersSharedBase.request_id, users=TestUsersSharedBase.users) + return UsersShared(UsersSharedTestBase.request_id, users=UsersSharedTestBase.users) -class TestUsersSharedBase: +class UsersSharedTestBase: request_id = 789 user_ids = (101112, 101113) users = (SharedUser(101112, "user1"), SharedUser(101113, "user2")) -class TestUsersSharedWithoutRequest(TestUsersSharedBase): +class TestUsersSharedWithoutRequest(UsersSharedTestBase): def test_slot_behaviour(self, users_shared): for attr in users_shared.__slots__: assert getattr(users_shared, attr, "err") != "err", f"got extra slot '{attr}'" @@ -85,17 +85,17 @@ def test_equality(self): @pytest.fixture(scope="class") def chat_shared(): return ChatShared( - TestChatSharedBase.request_id, - TestChatSharedBase.chat_id, + ChatSharedTestBase.request_id, + ChatSharedTestBase.chat_id, ) -class TestChatSharedBase: +class ChatSharedTestBase: request_id = 131415 chat_id = 161718 -class TestChatSharedWithoutRequest(TestChatSharedBase): +class TestChatSharedWithoutRequest(ChatSharedTestBase): def test_slot_behaviour(self, chat_shared): for attr in chat_shared.__slots__: assert getattr(chat_shared, attr, "err") != "err", f"got extra slot '{attr}'" @@ -143,15 +143,15 @@ def test_equality(self, users_shared): @pytest.fixture(scope="class") def shared_user(): return SharedUser( - TestSharedUserBase.user_id, - TestSharedUserBase.first_name, - last_name=TestSharedUserBase.last_name, - username=TestSharedUserBase.username, - photo=TestSharedUserBase.photo, + SharedUserTestBase.user_id, + SharedUserTestBase.first_name, + last_name=SharedUserTestBase.last_name, + username=SharedUserTestBase.username, + photo=SharedUserTestBase.photo, ) -class TestSharedUserBase: +class SharedUserTestBase: user_id = 101112 first_name = "first" last_name = "last" @@ -162,7 +162,7 @@ class TestSharedUserBase: ) -class TestSharedUserWithoutRequest(TestSharedUserBase): +class TestSharedUserWithoutRequest(SharedUserTestBase): def test_slot_behaviour(self, shared_user): for attr in shared_user.__slots__: assert getattr(shared_user, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_stars.py b/tests/test_stars.py index 10ed7e63b81..ef700ae392a 100644 --- a/tests/test_stars.py +++ b/tests/test_stars.py @@ -165,9 +165,9 @@ def transaction_partner(tp_scope_class_and_type): return tp_scope_class_and_type[0].de_json( { "type": tp_scope_class_and_type[1], - "invoice_payload": TestTransactionPartnerBase.invoice_payload, - "withdrawal_state": TestTransactionPartnerBase.withdrawal_state.to_dict(), - "user": TestTransactionPartnerBase.user.to_dict(), + "invoice_payload": TransactionPartnerTestBase.invoice_payload, + "withdrawal_state": TransactionPartnerTestBase.withdrawal_state.to_dict(), + "user": TransactionPartnerTestBase.user.to_dict(), }, bot=None, ) @@ -225,14 +225,14 @@ def revenue_withdrawal_state(rws_scope_class_and_type): return rws_scope_class_and_type[0].de_json( { "type": rws_scope_class_and_type[1], - "date": to_timestamp(TestRevenueWithdrawalStateBase.date), - "url": TestRevenueWithdrawalStateBase.url, + "date": to_timestamp(RevenueWithdrawalStateTestBase.date), + "url": RevenueWithdrawalStateTestBase.url, }, bot=None, ) -class TestStarTransactionBase: +class StarTransactionTestBase: id = "2" amount = 2 date = to_timestamp(datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC)) @@ -246,7 +246,7 @@ class TestStarTransactionBase: receiver = TransactionPartnerOther() -class TestStarTransactionWithoutRequest(TestStarTransactionBase): +class TestStarTransactionWithoutRequest(StarTransactionTestBase): def test_slot_behaviour(self): inst = star_transaction() for attr in inst.__slots__: @@ -332,11 +332,11 @@ def test_equality(self): assert hash(a) != hash(c) -class TestStarTransactionsBase: +class StarTransactionsTestBase: transactions = [star_transaction(), star_transaction()] -class TestStarTransactionsWithoutRequest(TestStarTransactionsBase): +class TestStarTransactionsWithoutRequest(StarTransactionsTestBase): def test_slot_behaviour(self, star_transactions): inst = star_transactions for attr in inst.__slots__: @@ -377,13 +377,13 @@ def test_equality(self): assert hash(a) != hash(c) -class TestTransactionPartnerBase: +class TransactionPartnerTestBase: withdrawal_state = withdrawal_state_succeeded() user = transaction_partner_user().user invoice_payload = "payload" -class TestTransactionPartnerWithoutRequest(TestTransactionPartnerBase): +class TestTransactionPartnerWithoutRequest(TransactionPartnerTestBase): def test_slot_behaviour(self, transaction_partner): inst = transaction_partner for attr in inst.__slots__: @@ -494,12 +494,12 @@ def test_equality(self, transaction_partner, bot): assert hash(c) != hash(f) -class TestRevenueWithdrawalStateBase: +class RevenueWithdrawalStateTestBase: date = datetime.datetime(2024, 1, 1, 0, 0, 0, 0, tzinfo=UTC) url = "url" -class TestRevenueWithdrawalStateWithoutRequest(TestRevenueWithdrawalStateBase): +class TestRevenueWithdrawalStateWithoutRequest(RevenueWithdrawalStateTestBase): def test_slot_behaviour(self, revenue_withdrawal_state): inst = revenue_withdrawal_state for attr in inst.__slots__: diff --git a/tests/test_story.py b/tests/test_story.py index b521bebc5c5..1aad292cb45 100644 --- a/tests/test_story.py +++ b/tests/test_story.py @@ -24,15 +24,15 @@ @pytest.fixture(scope="module") def story(): - return Story(TestStoryBase.chat, TestStoryBase.id) + return Story(StoryTestBase.chat, StoryTestBase.id) -class TestStoryBase: +class StoryTestBase: chat = Chat(1, "") id = 0 -class TestStoryWithoutRequest(TestStoryBase): +class TestStoryWithoutRequest(StoryTestBase): def test_slot_behaviour(self, story): for attr in story.__slots__: assert getattr(story, attr, "err") != "err", f"got extra slot '{attr}'" diff --git a/tests/test_switchinlinequerychosenchat.py b/tests/test_switchinlinequerychosenchat.py index 8a55398606f..e522c164418 100644 --- a/tests/test_switchinlinequerychosenchat.py +++ b/tests/test_switchinlinequerychosenchat.py @@ -26,15 +26,15 @@ @pytest.fixture(scope="module") def switch_inline_query_chosen_chat(): return SwitchInlineQueryChosenChat( - query=TestSwitchInlineQueryChosenChatBase.query, - allow_user_chats=TestSwitchInlineQueryChosenChatBase.allow_user_chats, - allow_bot_chats=TestSwitchInlineQueryChosenChatBase.allow_bot_chats, - allow_channel_chats=TestSwitchInlineQueryChosenChatBase.allow_channel_chats, - allow_group_chats=TestSwitchInlineQueryChosenChatBase.allow_group_chats, + query=SwitchInlineQueryChosenChatTestBase.query, + allow_user_chats=SwitchInlineQueryChosenChatTestBase.allow_user_chats, + allow_bot_chats=SwitchInlineQueryChosenChatTestBase.allow_bot_chats, + allow_channel_chats=SwitchInlineQueryChosenChatTestBase.allow_channel_chats, + allow_group_chats=SwitchInlineQueryChosenChatTestBase.allow_group_chats, ) -class TestSwitchInlineQueryChosenChatBase: +class SwitchInlineQueryChosenChatTestBase: query = "query" allow_user_chats = True allow_bot_chats = True @@ -42,7 +42,7 @@ class TestSwitchInlineQueryChosenChatBase: allow_group_chats = True -class TestSwitchInlineQueryChosenChat(TestSwitchInlineQueryChosenChatBase): +class TestSwitchInlineQueryChosenChat(SwitchInlineQueryChosenChatTestBase): def test_slot_behaviour(self, switch_inline_query_chosen_chat): inst = switch_inline_query_chosen_chat for attr in inst.__slots__: diff --git a/tests/test_update.py b/tests/test_update.py index b314c98e819..46619fbfd9d 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -212,14 +212,14 @@ @pytest.fixture(scope="module", params=params, ids=ids) def update(request): - return Update(update_id=TestUpdateBase.update_id, **request.param) + return Update(update_id=UpdateTestBase.update_id, **request.param) -class TestUpdateBase: +class UpdateTestBase: update_id = 868573637 -class TestUpdateWithoutRequest(TestUpdateBase): +class TestUpdateWithoutRequest(UpdateTestBase): def test_slot_behaviour(self): update = Update(self.update_id) for attr in update.__slots__: diff --git a/tests/test_user.py b/tests/test_user.py index 8b0ae5df585..073d0af58e0 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -31,45 +31,45 @@ @pytest.fixture(scope="module") def json_dict(): return { - "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, - "can_connect_to_business": TestUserBase.can_connect_to_business, - "has_main_web_app": TestUserBase.has_main_web_app, + "id": UserTestBase.id_, + "is_bot": UserTestBase.is_bot, + "first_name": UserTestBase.first_name, + "last_name": UserTestBase.last_name, + "username": UserTestBase.username, + "language_code": UserTestBase.language_code, + "can_join_groups": UserTestBase.can_join_groups, + "can_read_all_group_messages": UserTestBase.can_read_all_group_messages, + "supports_inline_queries": UserTestBase.supports_inline_queries, + "is_premium": UserTestBase.is_premium, + "added_to_attachment_menu": UserTestBase.added_to_attachment_menu, + "can_connect_to_business": UserTestBase.can_connect_to_business, + "has_main_web_app": UserTestBase.has_main_web_app, } @pytest.fixture def user(bot): user = User( - 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, - can_connect_to_business=TestUserBase.can_connect_to_business, - has_main_web_app=TestUserBase.has_main_web_app, + id=UserTestBase.id_, + first_name=UserTestBase.first_name, + is_bot=UserTestBase.is_bot, + last_name=UserTestBase.last_name, + username=UserTestBase.username, + language_code=UserTestBase.language_code, + can_join_groups=UserTestBase.can_join_groups, + can_read_all_group_messages=UserTestBase.can_read_all_group_messages, + supports_inline_queries=UserTestBase.supports_inline_queries, + is_premium=UserTestBase.is_premium, + added_to_attachment_menu=UserTestBase.added_to_attachment_menu, + can_connect_to_business=UserTestBase.can_connect_to_business, + has_main_web_app=UserTestBase.has_main_web_app, ) user.set_bot(bot) user._unfreeze() return user -class TestUserBase: +class UserTestBase: id_ = 1 is_bot = True first_name = "first\u2022name" @@ -85,7 +85,7 @@ class TestUserBase: has_main_web_app = False -class TestUserWithoutRequest(TestUserBase): +class TestUserWithoutRequest(UserTestBase): def test_slot_behaviour(self, user): 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 caff6a2a5a8..f0017ce6ca6 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -20,7 +20,7 @@ from tests.auxil.slots import mro_slots -class TestUserProfilePhotosBase: +class UserProfilePhotosTestBase: total_count = 2 photos = [ [ @@ -34,7 +34,7 @@ class TestUserProfilePhotosBase: ] -class TestUserProfilePhotosWithoutRequest(TestUserProfilePhotosBase): +class TestUserProfilePhotosWithoutRequest(UserProfilePhotosTestBase): def test_slot_behaviour(self): inst = UserProfilePhotos(self.total_count, self.photos) for attr in inst.__slots__: diff --git a/tests/test_webappdata.py b/tests/test_webappdata.py index 5a1a5c3fc02..a13043042c2 100644 --- a/tests/test_webappdata.py +++ b/tests/test_webappdata.py @@ -25,15 +25,15 @@ @pytest.fixture(scope="module") def web_app_data(): - return WebAppData(data=TestWebAppDataBase.data, button_text=TestWebAppDataBase.button_text) + return WebAppData(data=WebAppDataTestBase.data, button_text=WebAppDataTestBase.button_text) -class TestWebAppDataBase: +class WebAppDataTestBase: data = "data" button_text = "button_text" -class TestWebAppDataWithoutRequest(TestWebAppDataBase): +class TestWebAppDataWithoutRequest(WebAppDataTestBase): def test_slot_behaviour(self, web_app_data): 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 b0c8db81704..40d65873351 100644 --- a/tests/test_webappinfo.py +++ b/tests/test_webappinfo.py @@ -25,14 +25,14 @@ @pytest.fixture(scope="module") def web_app_info(): - return WebAppInfo(url=TestWebAppInfoBase.url) + return WebAppInfo(url=WebAppInfoTestBase.url) -class TestWebAppInfoBase: +class WebAppInfoTestBase: url = "https://www.example.com" -class TestWebAppInfoWithoutRequest(TestWebAppInfoBase): +class TestWebAppInfoWithoutRequest(WebAppInfoTestBase): def test_slot_behaviour(self, web_app_info): 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 8075095342a..48bb5ee38e6 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -29,18 +29,18 @@ @pytest.fixture(scope="module") def webhook_info(): return WebhookInfo( - 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, + url=WebhookInfoTestBase.url, + has_custom_certificate=WebhookInfoTestBase.has_custom_certificate, + pending_update_count=WebhookInfoTestBase.pending_update_count, + ip_address=WebhookInfoTestBase.ip_address, + last_error_date=WebhookInfoTestBase.last_error_date, + max_connections=WebhookInfoTestBase.max_connections, + allowed_updates=WebhookInfoTestBase.allowed_updates, + last_synchronization_error_date=WebhookInfoTestBase.last_synchronization_error_date, ) -class TestWebhookInfoBase: +class WebhookInfoTestBase: url = "http://www.google.com" has_custom_certificate = False pending_update_count = 5 @@ -51,7 +51,7 @@ class TestWebhookInfoBase: last_synchronization_error_date = time.time() -class TestWebhookInfoWithoutRequest(TestWebhookInfoBase): +class TestWebhookInfoWithoutRequest(WebhookInfoTestBase): def test_slot_behaviour(self, webhook_info): for attr in webhook_info.__slots__: assert getattr(webhook_info, attr, "err") != "err", f"got extra slot '{attr}'" From 0b352b043e9270b799d96df566da30fe76265e76 Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Mon, 9 Sep 2024 07:32:32 +0200 Subject: [PATCH 2/9] Make Tests for `telegram.ext` Independent of Networking (#4454) --- tests/auxil/monkeypatch.py | 29 +++++ tests/auxil/networking.py | 31 ++++- tests/auxil/pytest_classes.py | 11 +- tests/conftest.py | 53 ++------ tests/ext/conftest.py | 102 +++++++++++++++ tests/ext/test_application.py | 121 +++++------------- tests/ext/test_callbackcontext.py | 6 +- .../test_inlinequeryhandler.py | 0 tests/{ => ext}/test_pollhandler.py | 0 tests/ext/test_updater.py | 98 +++++--------- 10 files changed, 243 insertions(+), 208 deletions(-) create mode 100644 tests/auxil/monkeypatch.py create mode 100644 tests/ext/conftest.py rename tests/{_inline => ext}/test_inlinequeryhandler.py (100%) rename tests/{ => ext}/test_pollhandler.py (100%) diff --git a/tests/auxil/monkeypatch.py b/tests/auxil/monkeypatch.py new file mode 100644 index 00000000000..087ea80232d --- /dev/null +++ b/tests/auxil/monkeypatch.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2024 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +import asyncio + + +async def return_true(*args, **kwargs): + return True + + +async def empty_get_updates(*args, **kwargs): + # The `await` gives the event loop a chance to run other tasks + await asyncio.sleep(0) + return [] diff --git a/tests/auxil/networking.py b/tests/auxil/networking.py index 7c20da7ac94..a695eb232f7 100644 --- a/tests/auxil/networking.py +++ b/tests/auxil/networking.py @@ -17,7 +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/]. from pathlib import Path -from typing import Optional +from typing import Optional, Tuple import pytest from httpx import AsyncClient, AsyncHTTPTransport, Response @@ -26,7 +26,7 @@ from telegram._utils.strings import TextEncoding from telegram._utils.types import ODVInput from telegram.error import BadRequest, RetryAfter, TimedOut -from telegram.request import HTTPXRequest, RequestData +from telegram.request import BaseRequest, HTTPXRequest, RequestData class NonchalantHttpxRequest(HTTPXRequest): @@ -60,6 +60,33 @@ async def _request_wrapper( pytest.xfail(f"Ignoring TimedOut error: {e}") +class OfflineRequest(BaseRequest): + """This Request class disallows making requests to Telegram's servers. + Use this in tests that should not depend on the network. + """ + + async def initialize(self) -> None: + pass + + async def shutdown(self) -> None: + pass + + def __init__(self, *args, **kwargs): + pass + + async def do_request( + self, + url: str, + method: str, + request_data: Optional[RequestData] = None, + read_timeout: ODVInput[float] = BaseRequest.DEFAULT_NONE, + write_timeout: ODVInput[float] = BaseRequest.DEFAULT_NONE, + connect_timeout: ODVInput[float] = BaseRequest.DEFAULT_NONE, + pool_timeout: ODVInput[float] = BaseRequest.DEFAULT_NONE, + ) -> Tuple[int, bytes]: + pytest.fail("OfflineRequest: Network access disallowed in this test") + + async def expect_bad_request(func, message, reason): """ Wrapper for testing bot functions expected to result in an :class:`telegram.error.BadRequest`. diff --git a/tests/auxil/pytest_classes.py b/tests/auxil/pytest_classes.py index 1b976b02e6c..b80945b6704 100644 --- a/tests/auxil/pytest_classes.py +++ b/tests/auxil/pytest_classes.py @@ -25,7 +25,7 @@ from tests.auxil.ci_bots import BOT_INFO_PROVIDER from tests.auxil.constants import PRIVATE_KEY from tests.auxil.envvars import TEST_WITH_OPT_DEPS -from tests.auxil.networking import NonchalantHttpxRequest +from tests.auxil.networking import NonchalantHttpxRequest, OfflineRequest def _get_bot_user(token: str) -> User: @@ -93,17 +93,20 @@ class PytestUpdater(Updater): pass -def make_bot(bot_info=None, **kwargs): +def make_bot(bot_info=None, offline: bool = False, **kwargs): """ Tests are executed on tg.ext.ExtBot, as that class only extends the functionality of tg.bot """ token = kwargs.pop("token", (bot_info or {}).get("token")) private_key = kwargs.pop("private_key", PRIVATE_KEY) kwargs.pop("token", None) + + request_class = OfflineRequest if offline else NonchalantHttpxRequest + return PytestExtBot( token=token, private_key=private_key if TEST_WITH_OPT_DEPS else None, - request=NonchalantHttpxRequest(8), - get_updates_request=NonchalantHttpxRequest(1), + request=request_class(8), + get_updates_request=request_class(1), **kwargs, ) diff --git a/tests/conftest.py b/tests/conftest.py index c721605bdb5..e8ef01cabac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -37,15 +37,14 @@ Update, User, ) -from telegram.ext import ApplicationBuilder, Defaults, Updater -from telegram.ext.filters import MessageFilter, UpdateFilter +from telegram.ext import Defaults from tests.auxil.build_messages import DATE from tests.auxil.ci_bots import BOT_INFO_PROVIDER from tests.auxil.constants import PRIVATE_KEY from tests.auxil.envvars import RUN_TEST_OFFICIAL, TEST_WITH_OPT_DEPS from tests.auxil.files import data_file from tests.auxil.networking import NonchalantHttpxRequest -from tests.auxil.pytest_classes import PytestApplication, PytestBot, make_bot +from tests.auxil.pytest_classes import PytestBot, make_bot from tests.auxil.timezones import BasicTimezone if TEST_WITH_OPT_DEPS: @@ -124,6 +123,15 @@ async def bot(bot_info): yield _bot +@pytest.fixture(scope="session") +async def offline_bot(bot_info): + """Makes an offline Bot instance with the given bot_info + Note that in tests/ext we also override the `bot` fixture to return the offline bot instead. + """ + async with make_bot(bot_info, offline=True) as _bot: + yield _bot + + @pytest.fixture def one_time_bot(bot_info): """A function scoped bot since the session bot would shutdown when `async with app` finishes""" @@ -211,28 +219,6 @@ def subscription_channel_id(bot_info): return bot_info["subscription_channel_id"] -@pytest.fixture -async def app(bot_info): - # We build a new bot each time so that we use `app` in a context manager without problems - application = ( - ApplicationBuilder().bot(make_bot(bot_info)).application_class(PytestApplication).build() - ) - yield application - if application.running: - await application.stop() - await application.shutdown() - - -@pytest.fixture -async def updater(bot_info): - # We build a new bot each time so that we use `updater` in a context manager without problems - up = Updater(bot=make_bot(bot_info), update_queue=asyncio.Queue()) - yield up - if up.running: - await up.stop() - await up.shutdown() - - @pytest.fixture def thumb_file(): with data_file("thumb.jpg").open("rb") as f: @@ -245,23 +231,6 @@ def class_thumb_file(): yield f -@pytest.fixture( - scope="class", - params=[{"class": MessageFilter}, {"class": UpdateFilter}], - ids=["MessageFilter", "UpdateFilter"], -) -def mock_filter(request): - class MockFilter(request.param["class"]): - def __init__(self): - super().__init__() - self.tested = False - - def filter(self, _): - self.tested = True - - return MockFilter() - - def _get_false_update_fixture_decorator_params(): message = Message(1, DATE, Chat(1, ""), from_user=User(1, "", False), text="test") params = [ diff --git a/tests/ext/conftest.py b/tests/ext/conftest.py new file mode 100644 index 00000000000..f1a877b6e27 --- /dev/null +++ b/tests/ext/conftest.py @@ -0,0 +1,102 @@ +import asyncio + +import pytest + +from telegram.ext import ApplicationBuilder, Updater +from telegram.ext.filters import MessageFilter, UpdateFilter +from tests.auxil.constants import PRIVATE_KEY +from tests.auxil.envvars import TEST_WITH_OPT_DEPS +from tests.auxil.monkeypatch import return_true +from tests.auxil.networking import OfflineRequest +from tests.auxil.pytest_classes import PytestApplication, PytestBot, make_bot + +# This module overrides the bot fixtures defined in the global conftest.py to use the offline bot. +# We don't want the tests on telegram.ext to depend on the network, so we use the offline bot +# instead. + + +@pytest.fixture(scope="session") +async def bot(bot_info, offline_bot): + return offline_bot + + +@pytest.fixture +async def app(bot_info, monkeypatch): + # We build a new bot each time so that we use `app` in a context manager without problems + application = ( + ApplicationBuilder() + .bot(make_bot(bot_info, offline=True)) + .application_class(PytestApplication) + .build() + ) + monkeypatch.setattr(application.bot, "delete_webhook", return_true) + monkeypatch.setattr(application.bot, "set_webhook", return_true) + yield application + if application.running: + await application.stop() + await application.shutdown() + + +@pytest.fixture +async def updater(bot_info, monkeypatch): + # We build a new bot each time so that we use `updater` in a context manager without problems + up = Updater(bot=make_bot(bot_info, offline=True), update_queue=asyncio.Queue()) + monkeypatch.setattr(up.bot, "delete_webhook", return_true) + monkeypatch.setattr(up.bot, "set_webhook", return_true) + yield up + if up.running: + await up.stop() + await up.shutdown() + + +@pytest.fixture +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, offline=True) + + +@pytest.fixture(scope="session") +async def cdc_bot(bot_info): + """Makes an ExtBot instance with the given bot_info that uses arbitrary callback_data""" + async with make_bot(bot_info, arbitrary_callback_data=True, offline=True) as _bot: + yield _bot + + +@pytest.fixture(scope="session") +async def raw_bot(bot_info): + """Makes an regular Bot instance with the given bot_info""" + async with PytestBot( + bot_info["token"], + private_key=PRIVATE_KEY if TEST_WITH_OPT_DEPS else None, + request=OfflineRequest(), + get_updates_request=OfflineRequest(), + ) as _bot: + yield _bot + + +@pytest.fixture +async def one_time_raw_bot(bot_info): + """Makes an regular Bot instance with the given bot_info""" + return PytestBot( + bot_info["token"], + private_key=PRIVATE_KEY if TEST_WITH_OPT_DEPS else None, + request=OfflineRequest(), + get_updates_request=OfflineRequest(), + ) + + +@pytest.fixture( + scope="class", + params=[{"class": MessageFilter}, {"class": UpdateFilter}], + ids=["MessageFilter", "UpdateFilter"], +) +def mock_filter(request): + class MockFilter(request.param["class"]): + def __init__(self): + super().__init__() + self.tested = False + + def filter(self, _): + self.tested = True + + return MockFilter() diff --git a/tests/ext/test_application.py b/tests/ext/test_application.py index c423c5d5fbf..2826f4cad99 100644 --- a/tests/ext/test_application.py +++ b/tests/ext/test_application.py @@ -60,6 +60,7 @@ from tests.auxil.asyncio_helpers import call_after from tests.auxil.build_messages import make_message_update from tests.auxil.files import PROJECT_ROOT_PATH +from tests.auxil.monkeypatch import empty_get_updates, return_true from tests.auxil.networking import send_webhook_message from tests.auxil.pytest_classes import PytestApplication, PytestUpdater, make_bot from tests.auxil.slots import mro_slots @@ -432,7 +433,7 @@ 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, one_time_bot, job_queue): + async def test_start_stop_processing_updates(self, one_time_bot, job_queue, monkeypatch): # TODO: repeat a similar test for create_task, persistence processing and job queue if job_queue: app = ApplicationBuilder().bot(one_time_bot).build() @@ -442,6 +443,9 @@ async def test_start_stop_processing_updates(self, one_time_bot, job_queue): async def callback(u, c): self.received = u + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) + assert not app.running assert not app.updater.running if job_queue: @@ -1519,11 +1523,6 @@ def thread_target(): def test_run_polling_timeout_deprecation_warnings( self, timeout_name, monkeypatch, recwarn, app ): - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1536,7 +1535,7 @@ def thread_target(): os.kill(os.getpid(), signal.SIGINT) - monkeypatch.setattr(app.bot, "get_updates", get_updates) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) thread = Thread(target=thread_target) thread.start() @@ -1563,11 +1562,6 @@ def thread_target(): def test_run_polling_post_init(self, one_time_bot, monkeypatch): events = [] - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1589,7 +1583,7 @@ async def post_init(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "get_updates", get_updates) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) monkeypatch.setattr( app, "initialize", call_after(app.initialize, lambda _: events.append("init")) ) @@ -1598,6 +1592,7 @@ async def post_init(app: Application) -> None: "start_polling", call_after(app.updater.start_polling, lambda _: events.append("start_polling")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -1612,11 +1607,6 @@ async def post_init(app: Application) -> None: def test_run_polling_post_shutdown(self, one_time_bot, monkeypatch): events = [] - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1638,7 +1628,7 @@ async def post_shutdown(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "get_updates", get_updates) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) monkeypatch.setattr( app, "shutdown", call_after(app.shutdown, lambda _: events.append("shutdown")) ) @@ -1647,6 +1637,7 @@ async def post_shutdown(app: Application) -> None: "shutdown", call_after(app.updater.shutdown, lambda _: events.append("updater.shutdown")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -1665,11 +1656,6 @@ async def post_shutdown(app: Application) -> None: def test_run_polling_post_stop(self, one_time_bot, monkeypatch): events = [] - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1691,7 +1677,7 @@ async def post_stop(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "get_updates", get_updates) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) monkeypatch.setattr(app, "stop", call_after(app.stop, lambda _: events.append("stop"))) monkeypatch.setattr( app.updater, @@ -1703,6 +1689,7 @@ async def post_stop(app: Application) -> None: "shutdown", call_after(app.updater.shutdown, lambda _: events.append("updater.shutdown")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -1784,12 +1771,6 @@ def thread_target(): def test_run_webhook_basic(self, app, monkeypatch, caplog): assertions = {} - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - def thread_target(): waited = 0 while not app.running: @@ -1820,8 +1801,6 @@ def thread_target(): assertions["updater_not_running"] = not app.updater.running assertions["job_queue_not_running"] = not app.job_queue.scheduler.running - monkeypatch.setattr(app.bot, "set_webhook", set_webhook) - monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) app.add_handler(TypeHandler(object, self.callback_set_count(42))) thread = Thread(target=thread_target) @@ -1857,17 +1836,6 @@ def thread_target(): def test_run_webhook_post_init(self, one_time_bot, monkeypatch): events = [] - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1889,8 +1857,7 @@ async def post_init(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "set_webhook", set_webhook) - monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) + monkeypatch.setattr( app, "initialize", call_after(app.initialize, lambda _: events.append("init")) ) @@ -1899,6 +1866,8 @@ async def post_init(app: Application) -> None: "start_webhook", call_after(app.updater.start_webhook, lambda _: events.append("start_webhook")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) + monkeypatch.setattr(app.bot, "set_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -1923,17 +1892,6 @@ async def post_init(app: Application) -> None: def test_run_webhook_post_shutdown(self, one_time_bot, monkeypatch): events = [] - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -1955,8 +1913,7 @@ async def post_shutdown(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "set_webhook", set_webhook) - monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) + monkeypatch.setattr( app, "shutdown", call_after(app.shutdown, lambda _: events.append("shutdown")) ) @@ -1965,6 +1922,8 @@ async def post_shutdown(app: Application) -> None: "shutdown", call_after(app.updater.shutdown, lambda _: events.append("updater.shutdown")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) + monkeypatch.setattr(app.bot, "set_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -1993,17 +1952,6 @@ async def post_shutdown(app: Application) -> None: def test_run_webhook_post_stop(self, one_time_bot, monkeypatch): events = [] - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - - async def get_updates(*args, **kwargs): - # This makes sure that other coroutines have a chance of running as well - await asyncio.sleep(0) - return [] - def thread_target(): waited = 0 while not app.running: @@ -2025,8 +1973,7 @@ async def post_stop(app: Application) -> None: .build() ) app.bot._unfreeze() - monkeypatch.setattr(app.bot, "set_webhook", set_webhook) - monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) + monkeypatch.setattr(app, "stop", call_after(app.stop, lambda _: events.append("stop"))) monkeypatch.setattr( app.updater, @@ -2038,6 +1985,8 @@ async def post_stop(app: Application) -> None: "shutdown", call_after(app.updater.shutdown, lambda _: events.append("updater.shutdown")), ) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) + monkeypatch.setattr(app.bot, "set_webhook", return_true) thread = Thread(target=thread_target) thread.start() @@ -2217,10 +2166,6 @@ async def update_logger_callback(update, context): async def callback(*args, **kwargs): called_callbacks.add(kwargs["name"]) - async def get_updates(*args, **kwargs): - await asyncio.sleep(0) - return [] - for cls, method, entry in [ (Application, "initialize", "app_initialize"), (Application, "start", "app_start"), @@ -2249,7 +2194,8 @@ def after(_, name): .post_shutdown(functools.partial(callback, name="post_shutdown")) .build() ) - monkeypatch.setattr(app.bot, "get_updates", get_updates) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) app.add_handler(TypeHandler(object, update_logger_callback), group=-10) app.add_handler(TypeHandler(object, handler_callback)) @@ -2322,6 +2268,9 @@ def _after_shutdown(*args, **kwargs): Updater, "shutdown", call_after(Updater.shutdown, after_shutdown("updater")) ) app = ApplicationBuilder().bot(one_time_bot).build() + monkeypatch.setattr(app.bot, "delete_webhook", return_true) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) + with pytest.raises(RuntimeError, match="Test Exception"): app.run_polling(close_loop=False) @@ -2418,7 +2367,9 @@ def signal_handler_test(*args, **kwargs): received_signals.append(args[0]) loop = asyncio.get_event_loop() + monkeypatch.setattr(loop, "add_signal_handler", signal_handler_test) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) def abort_app(): raise SystemExit @@ -2496,16 +2447,6 @@ def test_stop_running(self, one_time_bot, monkeypatch, method): called_stop_running = threading.Event() assertions = {} - async def get_updates(*args, **kwargs): - await asyncio.sleep(0) - return [] - - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - async def post_init(app): # Simply calling app.update_queue.put_nowait(method) in the thread_target doesn't work # for some reason (probably threading magic), so we use an event from the thread_target @@ -2523,9 +2464,7 @@ async def task(app): .post_init(post_init) .build() ) - monkeypatch.setattr(app.bot, "get_updates", get_updates) - monkeypatch.setattr(app.bot, "set_webhook", set_webhook) - monkeypatch.setattr(app.bot, "delete_webhook", delete_webhook) + monkeypatch.setattr(app.bot, "get_updates", empty_get_updates) events = [] monkeypatch.setattr( @@ -2543,6 +2482,8 @@ async def task(app): "shutdown", call_after(app.shutdown, lambda _: events.append("app.shutdown")), ) + monkeypatch.setattr(app.bot, "set_webhook", return_true) + monkeypatch.setattr(app.bot, "delete_webhook", return_true) def thread_target(): waited = 0 diff --git a/tests/ext/test_callbackcontext.py b/tests/ext/test_callbackcontext.py index 0a099f64f15..9a5f64e6f21 100644 --- a/tests/ext/test_callbackcontext.py +++ b/tests/ext/test_callbackcontext.py @@ -20,7 +20,6 @@ import pytest from telegram import ( - Bot, CallbackQuery, Chat, InlineKeyboardButton, @@ -194,8 +193,7 @@ def test_application_attribute(self, app): callback_context = CallbackContext(app) assert callback_context.application is app - def test_drop_callback_data_exception(self, bot, app): - non_ext_bot = Bot(bot.token) + def test_drop_callback_data_exception(self, bot, app, raw_bot): update = Update( 0, message=Message(0, None, Chat(1, "chat"), from_user=User(1, "user", False)) ) @@ -206,7 +204,7 @@ def test_drop_callback_data_exception(self, bot, app): callback_context.drop_callback_data(None) try: - app.bot = non_ext_bot + app.bot = raw_bot with pytest.raises(RuntimeError, match="telegram.Bot does not allow for"): callback_context.drop_callback_data(None) finally: diff --git a/tests/_inline/test_inlinequeryhandler.py b/tests/ext/test_inlinequeryhandler.py similarity index 100% rename from tests/_inline/test_inlinequeryhandler.py rename to tests/ext/test_inlinequeryhandler.py diff --git a/tests/test_pollhandler.py b/tests/ext/test_pollhandler.py similarity index 100% rename from tests/test_pollhandler.py rename to tests/ext/test_pollhandler.py diff --git a/tests/ext/test_updater.py b/tests/ext/test_updater.py index 84a86c988da..b2b218cc137 100644 --- a/tests/ext/test_updater.py +++ b/tests/ext/test_updater.py @@ -30,12 +30,12 @@ from telegram._utils.defaultvalue import DEFAULT_NONE from telegram.error import InvalidToken, RetryAfter, TelegramError, TimedOut from telegram.ext import ExtBot, InvalidCallbackData, Updater -from telegram.request import HTTPXRequest from tests.auxil.build_messages import make_message, make_message_update from tests.auxil.envvars import TEST_WITH_OPT_DEPS from tests.auxil.files import TEST_DATA_PATH, data_file +from tests.auxil.monkeypatch import empty_get_updates, return_true from tests.auxil.networking import send_webhook_message -from tests.auxil.pytest_classes import PytestBot, make_bot +from tests.auxil.pytest_classes import make_bot from tests.auxil.slots import mro_slots UNIX_AVAILABLE = False @@ -179,14 +179,11 @@ async def test_start_without_initialize(self, updater, method): @pytest.mark.parametrize("method", ["start_polling", "start_webhook"]) async def test_shutdown_while_running(self, updater, method, monkeypatch): - async def set_webhook(*args, **kwargs): - return True - - monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) - ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port + monkeypatch.setattr(updater.bot, "get_updates", empty_get_updates) + async with updater: if "webhook" in method: await getattr(updater, method)( @@ -246,13 +243,12 @@ async def get_updates(*args, **kwargs): await asyncio.sleep(0.1) return [] - orig_del_webhook = updater.bot.delete_webhook - async def delete_webhook(*args, **kwargs): # Dropping pending updates is done by passing the parameter to delete_webhook if kwargs.get("drop_pending_updates"): self.message_count += 1 - return await orig_del_webhook(*args, **kwargs) + await asyncio.sleep(0) + return True monkeypatch.setattr(updater.bot, "get_updates", get_updates) monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) @@ -264,7 +260,6 @@ async def delete_webhook(*args, **kwargs): await updates.join() await updater.stop() assert not updater.running - assert not (await updater.bot.get_webhook_info()).url if drop_pending_updates: assert self.message_count == 1 else: @@ -281,7 +276,6 @@ async def delete_webhook(*args, **kwargs): await updates.join() await updater.stop() assert not updater.running - assert not (await updater.bot.get_webhook_info()).url self.received = [] self.message_count = 0 @@ -384,11 +378,8 @@ async def get_updates(*args, **kwargs): assert log_found async def test_polling_mark_updates_as_read_failure(self, monkeypatch, updater, caplog): - async def get_updates(*args, **kwargs): - await asyncio.sleep(0) - return [] - monkeypatch.setattr(updater.bot, "get_updates", get_updates) + monkeypatch.setattr(updater.bot, "get_updates", empty_get_updates) async with updater: await updater.start_polling() @@ -411,7 +402,10 @@ async def get_updates(*args, **kwargs): assert log_found - async def test_start_polling_already_running(self, updater): + async def test_start_polling_already_running(self, updater, monkeypatch): + + monkeypatch.setattr(updater.bot, "get_updates", empty_get_updates) + async with updater: await updater.start_polling() task = asyncio.create_task(updater.start_polling()) @@ -498,15 +492,13 @@ async def get_updates(*args, **kwargs): async def test_start_polling_bootstrap_retries( self, updater, monkeypatch, exception_class, retries ): - async def do_request(*args, **kwargs): + async def delete_webhook(*args, **kwargs): self.message_count += 1 raise exception_class(str(self.message_count)) - async with updater: - # Patch within the context so that updater.bot.initialize can still be called - # by the context manager - monkeypatch.setattr(HTTPXRequest, "do_request", do_request) + monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) + async with updater: if exception_class == InvalidToken: with pytest.raises(InvalidToken, match="1"): await updater.start_polling(bootstrap_retries=retries) @@ -705,14 +697,23 @@ async def delete_webhook(*args, **kwargs): "unix", [None, "file_path", "socket_object"] if UNIX_AVAILABLE else [None] ) async def test_webhook_basic( - self, monkeypatch, updater, drop_pending_updates, ext_bot, secret_token, unix, file_path + self, + monkeypatch, + updater, + drop_pending_updates, + ext_bot, + secret_token, + unix, + file_path, + one_time_bot, + one_time_raw_bot, ): # Testing with both ExtBot and Bot to make sure any logic in WebhookHandler # that depends on this distinction works if ext_bot and not isinstance(updater.bot, ExtBot): - updater.bot = ExtBot(updater.bot.token) + updater.bot = one_time_bot if not ext_bot and type(updater.bot) is not Bot: - updater.bot = PytestBot(updater.bot.token) + updater.bot = one_time_raw_bot async def delete_webhook(*args, **kwargs): # Dropping pending updates is done by passing the parameter to delete_webhook @@ -720,10 +721,7 @@ async def delete_webhook(*args, **kwargs): self.message_count += 1 return True - async def set_webhook(*args, **kwargs): - return True - - monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) + monkeypatch.setattr(updater.bot, "set_webhook", return_true) monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) ip = "127.0.0.1" @@ -873,12 +871,6 @@ async def test_no_unix(self, updater): await updater.start_webhook(unix="DoesntMatter", webhook_url="TOKEN") async def test_start_webhook_already_running(self, updater, monkeypatch): - async def return_true(*args, **kwargs): - return True - - monkeypatch.setattr(updater.bot, "set_webhook", return_true) - monkeypatch.setattr(updater.bot, "delete_webhook", return_true) - ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port async with updater: @@ -977,12 +969,9 @@ async def test_webhook_arbitrary_callback_data( extensively in test_bot.py in conjunction with get_updates.""" updater = Updater(bot=cdc_bot, update_queue=asyncio.Queue()) - async def return_true(*args, **kwargs): - return True + monkeypatch.setattr(updater.bot, "set_webhook", return_true) try: - monkeypatch.setattr(updater.bot, "set_webhook", return_true) - monkeypatch.setattr(updater.bot, "delete_webhook", return_true) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port @@ -1025,11 +1014,6 @@ async def return_true(*args, **kwargs): updater.bot.callback_data_cache.clear_callback_queries() async def test_webhook_invalid_ssl(self, monkeypatch, updater): - async def return_true(*args, **kwargs): - return True - - monkeypatch.setattr(updater.bot, "set_webhook", return_true) - monkeypatch.setattr(updater.bot, "delete_webhook", return_true) ip = "127.0.0.1" port = randrange(1024, 49152) # Select random port @@ -1056,9 +1040,6 @@ async def set_webhook(**kwargs): self.test_flag.append(bool(kwargs.get("certificate"))) return True - async def return_true(*args, **kwargs): - return True - orig_wh_server_init = WebhookServer.__init__ def webhook_server_init(*args, **kwargs): @@ -1066,7 +1047,7 @@ def webhook_server_init(*args, **kwargs): orig_wh_server_init(*args, **kwargs) monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) - monkeypatch.setattr(updater.bot, "delete_webhook", return_true) + monkeypatch.setattr( "telegram.ext._utils.webhookhandler.WebhookServer.__init__", webhook_server_init ) @@ -1088,15 +1069,13 @@ def webhook_server_init(*args, **kwargs): async def test_start_webhook_bootstrap_retries( self, updater, monkeypatch, exception_class, retries ): - async def do_request(*args, **kwargs): + async def set_webhook(*args, **kwargs): self.message_count += 1 raise exception_class(str(self.message_count)) - async with updater: - # Patch within the context so that updater.bot.initialize can still be called - # by the context manager - monkeypatch.setattr(HTTPXRequest, "do_request", do_request) + monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) + async with updater: if exception_class == InvalidToken: with pytest.raises(InvalidToken, match="1"): await updater.start_webhook(bootstrap_retries=retries) @@ -1107,11 +1086,6 @@ async def do_request(*args, **kwargs): ) async def test_webhook_invalid_posts(self, updater, monkeypatch): - async def return_true(*args, **kwargs): - return True - - monkeypatch.setattr(updater.bot, "set_webhook", return_true) - monkeypatch.setattr(updater.bot, "delete_webhook", return_true) ip = "127.0.0.1" port = randrange(1024, 49152) @@ -1146,17 +1120,9 @@ async def return_true(*args, **kwargs): await updater.stop() async def test_webhook_update_de_json_fails(self, monkeypatch, updater, caplog): - async def delete_webhook(*args, **kwargs): - return True - - async def set_webhook(*args, **kwargs): - return True - def de_json_fails(*args, **kwargs): raise TypeError("Invalid input") - monkeypatch.setattr(updater.bot, "set_webhook", set_webhook) - monkeypatch.setattr(updater.bot, "delete_webhook", delete_webhook) orig_de_json = Update.de_json monkeypatch.setattr(Update, "de_json", de_json_fails) From 1223e851c36809055b27edd9ccf00ce29d2a65c4 Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Wed, 11 Sep 2024 22:34:18 +0200 Subject: [PATCH 3/9] Add Parameter `httpx_kwargs` to `HTTPXRequest` (#4451) --- telegram/request/_httpxrequest.py | 20 ++++++++++++++++-- tests/ext/test_applicationbuilder.py | 2 +- tests/request/test_request.py | 31 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/telegram/request/_httpxrequest.py b/telegram/request/_httpxrequest.py index 3dc6cf05fba..d74ed00d870 100644 --- a/telegram/request/_httpxrequest.py +++ b/telegram/request/_httpxrequest.py @@ -17,7 +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/]. """This module contains methods to make POST and GET requests using the httpx library.""" -from typing import Collection, Optional, Tuple, Union +from typing import Any, Collection, Dict, Optional, Tuple, Union import httpx @@ -122,6 +122,20 @@ class HTTPXRequest(BaseRequest): :meth:`do_request`. Defaults to ``20`` seconds. .. versionadded:: 21.0 + httpx_kwargs (Dict[:obj:`str`, Any], optional): Additional keyword arguments to be passed + to the `httpx.AsyncClient `_ + constructor. + + Warning: + This parameter is intended for advanced users that want to fine-tune the behavior + of the underlying ``httpx`` client. The values passed here will override all the + defaults set by ``python-telegram-bot`` and all other parameters passed to + :class:`HTTPXRequest`. The only exception is the :paramref:`media_write_timeout` + parameter, which is not passed to the client constructor. + No runtime warnings will be issued about parameters that are overridden in this + way. + + .. versionadded:: NEXT.VERSION """ @@ -139,6 +153,7 @@ def __init__( socket_options: Optional[Collection[SocketOpt]] = None, proxy: Optional[Union[str, httpx.Proxy, httpx.URL]] = None, media_write_timeout: Optional[float] = 20.0, + httpx_kwargs: Optional[Dict[str, Any]] = None, ): if proxy_url is not None and proxy is not None: raise ValueError("The parameters `proxy_url` and `proxy` are mutually exclusive.") @@ -183,6 +198,7 @@ def __init__( "limits": limits, "transport": transport, **http_kwargs, + **(httpx_kwargs or {}), } try: @@ -221,7 +237,7 @@ def read_timeout(self) -> Optional[float]: return self._client.timeout.read def _build_client(self) -> httpx.AsyncClient: - return httpx.AsyncClient(**self._client_kwargs) # type: ignore[arg-type] + return httpx.AsyncClient(**self._client_kwargs) async def initialize(self) -> None: """See :meth:`BaseRequest.initialize`.""" diff --git a/tests/ext/test_applicationbuilder.py b/tests/ext/test_applicationbuilder.py index 189164d1b8c..235a80f682d 100644 --- a/tests/ext/test_applicationbuilder.py +++ b/tests/ext/test_applicationbuilder.py @@ -74,7 +74,7 @@ def test_all_methods_request(self, builder, get_updates): arguments = inspect.signature(HTTPXRequest.__init__).parameters.keys() prefix = "get_updates_" if get_updates else "" for argument in arguments: - if argument == "self": + if argument in ("self", "httpx_kwargs"): continue if argument == "media_write_timeout" and get_updates: # get_updates never makes media requests diff --git a/tests/request/test_request.py b/tests/request/test_request.py index 6adcdf7c068..2bbfcf52de6 100644 --- a/tests/request/test_request.py +++ b/tests/request/test_request.py @@ -134,6 +134,37 @@ def test_slot_behaviour(self): assert getattr(inst, at, "err") != "err", f"got extra slot '{at}'" assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot" + def test_httpx_kwargs(self, monkeypatch): + self.test_flag = {} + + orig_init = httpx.AsyncClient.__init__ + + class Client(httpx.AsyncClient): + def __init__(*args, **kwargs): + orig_init(*args, **kwargs) + self.test_flag["args"] = args + self.test_flag["kwargs"] = kwargs + + monkeypatch.setattr(httpx, "AsyncClient", Client) + + HTTPXRequest( + connect_timeout=1, + connection_pool_size=42, + http_version="2", + httpx_kwargs={ + "timeout": httpx.Timeout(7), + "limits": httpx.Limits(max_connections=7), + "http1": True, + "verify": False, + }, + ) + kwargs = self.test_flag["kwargs"] + + assert kwargs["timeout"].connect == 7 + assert kwargs["limits"].max_connections == 7 + assert kwargs["http1"] is True + assert kwargs["verify"] is False + async def test_context_manager(self, monkeypatch): async def initialize(): self.test_flag = ["initialize"] From ec909e62cf4285e170a38f487b33f0e8a41e48e0 Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Fri, 13 Sep 2024 19:10:09 +0200 Subject: [PATCH 4/9] Enforce the `offline_bot` Fixture in `Test*WithoutRequest` (#4465) --- tests/_files/test_animation.py | 32 +- tests/_files/test_audio.py | 28 +- tests/_files/test_chatphoto.py | 12 +- tests/_files/test_contact.py | 22 +- tests/_files/test_document.py | 26 +- tests/_files/test_file.py | 14 +- tests/_files/test_inputmedia.py | 24 +- tests/_files/test_location.py | 46 +- tests/_files/test_photo.py | 32 +- tests/_files/test_sticker.py | 92 ++-- tests/_files/test_venue.py | 18 +- tests/_files/test_video.py | 32 +- tests/_files/test_videonote.py | 36 +- tests/_files/test_voice.py | 32 +- tests/_games/test_game.py | 8 +- tests/_games/test_gamehighscore.py | 6 +- tests/_inline/test_inlinekeyboardbutton.py | 4 +- tests/_inline/test_inlinekeyboardmarkup.py | 8 +- tests/_inline/test_inlinequery.py | 4 +- .../test_inputinvoicemessagecontent.py | 8 +- tests/_passport/test_no_passport.py | 4 +- tests/_passport/test_passport.py | 42 +- tests/_payment/test_invoice.py | 24 +- tests/_payment/test_orderinfo.py | 4 +- tests/_payment/test_precheckoutquery.py | 6 +- tests/_payment/test_refundedpayment.py | 4 +- tests/_payment/test_shippingaddress.py | 4 +- tests/_payment/test_shippingquery.py | 6 +- tests/_payment/test_successfulpayment.py | 4 +- tests/conftest.py | 37 +- tests/request/test_request.py | 38 +- tests/test_birthdate.py | 4 +- tests/test_bot.py | 507 +++++++++--------- tests/test_botcommand.py | 6 +- tests/test_botcommandscope.py | 20 +- tests/test_business.py | 4 +- tests/test_callbackquery.py | 4 +- tests/test_chat.py | 4 +- tests/test_chatadministratorrights.py | 4 +- tests/test_chatbackground.py | 40 +- tests/test_chatboost.py | 52 +- tests/test_chatfullinfo.py | 8 +- tests/test_chatinvitelink.py | 12 +- tests/test_chatjoinrequest.py | 10 +- tests/test_chatlocation.py | 4 +- tests/test_chatmember.py | 26 +- tests/test_chatmemberupdated.py | 23 +- tests/test_chatpermissions.py | 4 +- tests/test_choseninlineresult.py | 8 +- tests/test_dice.py | 6 +- tests/test_forum.py | 12 +- tests/test_giveaway.py | 26 +- tests/test_inlinequeryresultsbutton.py | 8 +- tests/test_keyboardbutton.py | 2 +- tests/test_keyboardbuttonrequest.py | 10 +- tests/test_maybeinaccessiblemessage.py | 12 +- tests/test_menubutton.py | 22 +- tests/test_message.py | 16 +- tests/test_messageentity.py | 4 +- tests/test_messageorigin.py | 26 +- tests/test_paidmedia.py | 28 +- tests/test_poll.py | 8 +- tests/test_proximityalerttriggered.py | 4 +- tests/test_reaction.py | 28 +- tests/test_reply.py | 18 +- tests/test_sentwebappmessage.py | 2 +- tests/test_shared.py | 20 +- tests/test_stars.py | 58 +- tests/test_story.py | 6 +- tests/test_update.py | 8 +- tests/test_user.py | 4 +- tests/test_userprofilephotos.py | 4 +- tests/test_videochat.py | 14 +- tests/test_webappdata.py | 4 +- tests/test_webappinfo.py | 4 +- tests/test_webhookinfo.py | 10 +- 76 files changed, 931 insertions(+), 830 deletions(-) diff --git a/tests/_files/test_animation.py b/tests/_files/test_animation.py index 493d9bfae03..55c2076e23f 100644 --- a/tests/_files/test_animation.py +++ b/tests/_files/test_animation.py @@ -84,7 +84,7 @@ def test_expected_values(self, animation): assert animation.file_name.startswith("game.gif") == self.file_name.startswith("game.gif") assert isinstance(animation.thumbnail, PhotoSize) - def test_de_json(self, bot, animation): + def test_de_json(self, offline_bot, animation): json_dict = { "file_id": self.animation_file_id, "file_unique_id": self.animation_file_unique_id, @@ -96,7 +96,7 @@ def test_de_json(self, bot, animation): "mime_type": self.mime_type, "file_size": self.file_size, } - animation = Animation.de_json(json_dict, bot) + animation = Animation.de_json(json_dict, offline_bot) assert animation.api_kwargs == {} assert animation.file_id == self.animation_file_id assert animation.file_unique_id == self.animation_file_unique_id @@ -140,18 +140,22 @@ 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 test_send_animation_custom_filename( + self, offline_bot, chat_id, animation_file, monkeypatch + ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.send_animation(chat_id, animation_file, filename="custom_filename") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_send_animation_local_files(self, monkeypatch, offline_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 + offline_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() @@ -167,18 +171,18 @@ async def make_assertion(_, data, *args, **kwargs): data.get("thumbnail"), InputFile ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_animation(chat_id, file, thumbnail=file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_animation(chat_id, file, thumbnail=file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False - async def test_send_with_animation(self, monkeypatch, bot, chat_id, animation): + async def test_send_with_animation(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_animation(animation=animation, chat_id=chat_id) async def test_get_file_instance_method(self, monkeypatch, animation): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_audio.py b/tests/_files/test_audio.py index f6b76c1f0c9..ed0d74d4d72 100644 --- a/tests/_files/test_audio.py +++ b/tests/_files/test_audio.py @@ -91,7 +91,7 @@ def test_expected_values(self, audio): assert audio.thumbnail.width == self.thumb_width assert audio.thumbnail.height == self.thumb_height - def test_de_json(self, bot, audio): + def test_de_json(self, offline_bot, audio): json_dict = { "file_id": self.audio_file_id, "file_unique_id": self.audio_file_unique_id, @@ -103,7 +103,7 @@ def test_de_json(self, bot, audio): "file_size": self.file_size, "thumbnail": audio.thumbnail.to_dict(), } - json_audio = Audio.de_json(json_dict, bot) + json_audio = Audio.de_json(json_dict, offline_bot) assert json_audio.api_kwargs == {} assert json_audio.file_id == self.audio_file_id @@ -147,25 +147,25 @@ 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 test_send_with_audio(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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 test_send_audio_custom_filename(self, offline_bot, chat_id, audio_file, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.send_audio(chat_id, audio_file, filename="custom_filename") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_send_audio_local_files(self, monkeypatch, offline_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 + offline_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() @@ -179,11 +179,11 @@ async def make_assertion(_, data, *args, **kwargs): data.get("thumbnail"), InputFile ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_audio(chat_id, file, thumbnail=file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_audio(chat_id, file, thumbnail=file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, audio): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_chatphoto.py b/tests/_files/test_chatphoto.py index 5deaae38fb4..5bbb6a8f71e 100644 --- a/tests/_files/test_chatphoto.py +++ b/tests/_files/test_chatphoto.py @@ -66,14 +66,14 @@ def test_slot_behaviour(self, chat_photo): 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" - def test_de_json(self, bot, chat_photo): + def test_de_json(self, offline_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, } - chat_photo = ChatPhoto.de_json(json_dict, bot) + chat_photo = ChatPhoto.de_json(json_dict, offline_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 @@ -121,12 +121,14 @@ 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 test_send_with_chat_photo( + self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + message = await offline_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): diff --git a/tests/_files/test_contact.py b/tests/_files/test_contact.py index cb5777eb4dd..0869d7ff33e 100644 --- a/tests/_files/test_contact.py +++ b/tests/_files/test_contact.py @@ -52,22 +52,22 @@ def test_slot_behaviour(self, contact): 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): + def test_de_json_required(self, offline_bot): json_dict = {"phone_number": self.phone_number, "first_name": self.first_name} - contact = Contact.de_json(json_dict, bot) + contact = Contact.de_json(json_dict, offline_bot) assert contact.api_kwargs == {} assert contact.phone_number == self.phone_number assert contact.first_name == self.first_name - def test_de_json_all(self, bot): + def test_de_json_all(self, offline_bot): json_dict = { "phone_number": self.phone_number, "first_name": self.first_name, "last_name": self.last_name, "user_id": self.user_id, } - contact = Contact.de_json(json_dict, bot) + contact = Contact.de_json(json_dict, offline_bot) assert contact.api_kwargs == {} assert contact.phone_number == self.phone_number @@ -104,20 +104,20 @@ def test_equality(self): assert a != e assert hash(a) != hash(e) - async def test_send_contact_without_required(self, bot, chat_id): + async def test_send_contact_without_required(self, offline_bot, chat_id): with pytest.raises(ValueError, match="Either contact or phone_number and first_name"): - await bot.send_contact(chat_id=chat_id) + await offline_bot.send_contact(chat_id=chat_id) - async def test_send_mutually_exclusive(self, bot, chat_id, contact): + async def test_send_mutually_exclusive(self, offline_bot, chat_id, contact): with pytest.raises(ValueError, match="Not both"): - await bot.send_contact( + await offline_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 test_send_with_contact(self, monkeypatch, offline_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 @@ -125,8 +125,8 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): 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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_contact(contact=contact, chat_id=chat_id) @pytest.mark.parametrize( ("default_bot", "custom"), diff --git a/tests/_files/test_document.py b/tests/_files/test_document.py index 02f60ac464a..90b6bdf1121 100644 --- a/tests/_files/test_document.py +++ b/tests/_files/test_document.py @@ -83,7 +83,7 @@ def test_expected_values(self, document): assert document.thumbnail.width == self.thumb_width assert document.thumbnail.height == self.thumb_height - def test_de_json(self, bot, document): + def test_de_json(self, offline_bot, document): json_dict = { "file_id": self.document_file_id, "file_unique_id": self.document_file_unique_id, @@ -92,7 +92,7 @@ def test_de_json(self, bot, document): "mime_type": self.mime_type, "file_size": self.file_size, } - test_document = Document.de_json(json_dict, bot) + test_document = Document.de_json(json_dict, offline_bot) assert test_document.api_kwargs == {} assert test_document.file_id == self.document_file_id @@ -128,13 +128,13 @@ def test_equality(self, document): assert a != e assert hash(a) != hash(e) - async def test_error_send_without_required_args(self, bot, chat_id): + async def test_error_send_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.send_document(chat_id=chat_id) + await offline_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 + self, monkeypatch, offline_bot, chat_id, document, disable_content_type_detection ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.parameters @@ -143,9 +143,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) return data["document"] == document.file_id and type_detection - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - message = await bot.send_document( + message = await offline_bot.send_document( document=document, chat_id=chat_id, disable_content_type_detection=disable_content_type_detection, @@ -181,10 +181,10 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) @pytest.mark.parametrize("local_mode", [True, False]) - async def test_send_document_local_files(self, monkeypatch, bot, chat_id, local_mode): + async def test_send_document_local_files(self, monkeypatch, offline_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 + offline_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() @@ -200,11 +200,11 @@ async def make_assertion(_, data, *args, **kwargs): data.get("thumbnail"), InputFile ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_document(chat_id, file, thumbnail=file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_document(chat_id, file, thumbnail=file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, document): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_file.py b/tests/_files/test_file.py index ae9d92c0425..70874d5feb8 100644 --- a/tests/_files/test_file.py +++ b/tests/_files/test_file.py @@ -107,14 +107,14 @@ def test_slot_behaviour(self, file): assert getattr(file, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(file)) == len(set(mro_slots(file))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_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, } - new_file = File.de_json(json_dict, bot) + new_file = File.de_json(json_dict, offline_bot) assert new_file.api_kwargs == {} assert new_file.file_id == self.file_id @@ -131,11 +131,11 @@ 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(self.file_id, self.file_unique_id, bot) - b = File("", self.file_unique_id, bot) + def test_equality(self, offline_bot): + a = File(self.file_id, self.file_unique_id, offline_bot) + b = File("", self.file_unique_id, offline_bot) c = File(self.file_id, self.file_unique_id, None) - d = File("", "", bot) + d = File("", "", offline_bot) e = Voice(self.file_id, self.file_unique_id, 0) assert a == b @@ -223,7 +223,7 @@ async def test(*args, **kwargs): assert buf2[len(buf) :] == buf assert buf2[: len(buf)] == buf - async def test_download_encrypted(self, monkeypatch, bot, encrypted_file): + async def test_download_encrypted(self, monkeypatch, offline_bot, encrypted_file): async def test(*args, **kwargs): return data_file("image_encrypted.jpg").read_bytes() diff --git a/tests/_files/test_inputmedia.py b/tests/_files/test_inputmedia.py index ff398113a48..6b54e4d196a 100644 --- a/tests/_files/test_inputmedia.py +++ b/tests/_files/test_inputmedia.py @@ -655,7 +655,7 @@ def media_group_no_caption_only_parse_mode(photo, thumb): # noqa: F811 class TestSendMediaGroupWithoutRequest: async def test_send_media_group_throws_error_with_group_caption_and_individual_captions( self, - bot, + offline_bot, chat_id, media_group, media_group_no_caption_only_caption_entities, @@ -670,11 +670,11 @@ async def test_send_media_group_throws_error_with_group_caption_and_individual_c ValueError, match="You can only supply either group caption or media with captions.", ): - await bot.send_media_group(chat_id, group, caption="foo") + await offline_bot.send_media_group(chat_id, group, caption="foo") async def test_send_media_group_custom_filename( self, - bot, + offline_bot, chat_id, photo_file, # noqa: F811 animation_file, # noqa: F811 @@ -690,7 +690,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): if result is True: raise Exception("Test was successful") - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) media = [ InputMediaAnimation(animation_file, filename="custom_filename"), @@ -700,10 +700,10 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ] with pytest.raises(Exception, match="Test was successful"): - await bot.send_media_group(chat_id, media) + await offline_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 + self, offline_bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 ): async def make_assertion(method, url, request_data: RequestData, *args, **kwargs): nonlocal input_video @@ -715,13 +715,13 @@ async def make_assertion(method, url, request_data: RequestData, *args, **kwargs result = video_check and thumb_check raise Exception(f"Test was {'successful' if result else 'failing'}") - monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) + monkeypatch.setattr(offline_bot.request, "_request_wrapper", make_assertion) input_video = InputMediaVideo(video_file, thumbnail=photo_file) with pytest.raises(Exception, match="Test was successful"): - await bot.send_media_group(chat_id, [input_video, input_video]) + await offline_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 + self, offline_bot, chat_id, video_file, photo_file, monkeypatch # noqa: F811 ): async def make_assertion( method: str, url: str, request_data: Optional[RequestData] = None, *args, **kwargs @@ -734,10 +734,12 @@ async def make_assertion( result = video_check and thumb_check raise Exception(f"Test was {'successful' if result else 'failing'}") - monkeypatch.setattr(bot.request, "_request_wrapper", make_assertion) + monkeypatch.setattr(offline_bot.request, "_request_wrapper", make_assertion) input_video = InputMediaVideo(video_file, thumbnail=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) + await offline_bot.edit_message_media( + chat_id=chat_id, message_id=123, media=input_video + ) @pytest.mark.parametrize( ("default_bot", "custom"), diff --git a/tests/_files/test_location.py b/tests/_files/test_location.py index 72c6f720066..402f0ba7b11 100644 --- a/tests/_files/test_location.py +++ b/tests/_files/test_location.py @@ -55,7 +55,7 @@ def test_slot_behaviour(self, location): assert getattr(location, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(location)) == len(set(mro_slots(location))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "latitude": self.latitude, "longitude": self.longitude, @@ -64,7 +64,7 @@ def test_de_json(self, bot): "heading": self.heading, "proximity_alert_radius": self.proximity_alert_radius, } - location = Location.de_json(json_dict, bot) + location = Location.de_json(json_dict, offline_bot) assert location.api_kwargs == {} assert location.latitude == self.latitude @@ -96,26 +96,28 @@ def test_equality(self): assert a != d assert hash(a) != hash(d) - async def test_send_location_without_required(self, bot, chat_id): + async def test_send_location_without_required(self, offline_bot, chat_id): with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.send_location(chat_id=chat_id) + await offline_bot.send_location(chat_id=chat_id) - async def test_edit_location_without_required(self, bot): + async def test_edit_location_without_required(self, offline_bot): with pytest.raises(ValueError, match="Either location or latitude and longitude"): - await bot.edit_message_live_location(chat_id=2, message_id=3) + await offline_bot.edit_message_live_location(chat_id=2, message_id=3) - async def test_send_location_with_all_args(self, bot, location): + async def test_send_location_with_all_args(self, offline_bot, location): with pytest.raises(ValueError, match="Not both"): - await bot.send_location(chat_id=1, latitude=2.5, longitude=4.6, location=location) + await offline_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): + async def test_edit_location_with_all_args(self, offline_bot, location): with pytest.raises(ValueError, match="Not both"): - await bot.edit_message_live_location( + await offline_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 test_edit_live_inline_message(self, monkeypatch, offline_bot, location): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters lat = data["latitude"] == str(location.latitude) @@ -127,8 +129,8 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): live = data["live_period"] == "900" return lat and lon and id_ and ha and heading and prox_alert and live - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.edit_message_live_location( + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.edit_message_live_location( inline_message_id=1234, location=location, horizontal_accuracy=50, @@ -138,30 +140,30 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) # TODO: Needs improvement with in inline sent live location. - async def test_stop_live_inline_message(self, monkeypatch, bot): + async def test_stop_live_inline_message(self, monkeypatch, offline_bot): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.json_parameters["inline_message_id"] == "1234" - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.stop_message_live_location(inline_message_id=1234) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.stop_message_live_location(inline_message_id=1234) - async def test_send_with_location(self, monkeypatch, bot, chat_id, location): + async def test_send_with_location(self, monkeypatch, offline_bot, chat_id, 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.send_location(location=location, chat_id=chat_id) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_location(location=location, chat_id=chat_id) - async def test_edit_live_location_with_location(self, monkeypatch, bot, location): + async def test_edit_live_location_with_location(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.edit_message_live_location(None, None, location=location) @pytest.mark.parametrize( ("default_bot", "custom"), diff --git a/tests/_files/test_photo.py b/tests/_files/test_photo.py index 6ba9e46acc4..919c3155bcb 100644 --- a/tests/_files/test_photo.py +++ b/tests/_files/test_photo.py @@ -105,7 +105,7 @@ def test_expected_values(self, photo, thumb): # so far assert thumb.file_size in [1475, 1477] - def test_de_json(self, bot, photo): + def test_de_json(self, offline_bot, photo): json_dict = { "file_id": photo.file_id, "file_unique_id": photo.file_unique_id, @@ -113,7 +113,7 @@ def test_de_json(self, bot, photo): "height": self.height, "file_size": self.file_size, } - json_photo = PhotoSize.de_json(json_dict, bot) + json_photo = PhotoSize.de_json(json_dict, offline_bot) assert json_photo.api_kwargs == {} assert json_photo.file_id == photo.file_id @@ -160,22 +160,22 @@ def test_equality(self, photo): assert a != e assert hash(a) != hash(e) - async def test_error_without_required_args(self, bot, chat_id): + async def test_error_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.send_photo(chat_id=chat_id) + await offline_bot.send_photo(chat_id=chat_id) - async def test_send_photo_custom_filename(self, bot, chat_id, photo_file, monkeypatch): + async def test_send_photo_custom_filename(self, offline_bot, chat_id, photo_file, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.send_photo(chat_id, photo_file, filename="custom_filename") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_send_photo_local_files(self, monkeypatch, offline_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 + offline_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() @@ -187,18 +187,18 @@ async def make_assertion(_, data, *args, **kwargs): else: test_flag = isinstance(data.get("photo"), InputFile) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_photo(chat_id, file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_photo(chat_id, file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False - async def test_send_with_photosize(self, monkeypatch, bot, chat_id, photo): + async def test_send_with_photosize(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_photo(photo=photo, chat_id=chat_id) async def test_get_file_instance_method(self, monkeypatch, photo): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_sticker.py b/tests/_files/test_sticker.py index 3f374cc2ea0..3fa608e3a4d 100644 --- a/tests/_files/test_sticker.py +++ b/tests/_files/test_sticker.py @@ -165,7 +165,7 @@ def test_to_dict(self, sticker): assert sticker_dict["type"] == sticker.type assert sticker_dict["needs_repainting"] == sticker.needs_repainting - def test_de_json(self, bot, sticker): + def test_de_json(self, offline_bot, sticker): json_dict = { "file_id": self.sticker_file_id, "file_unique_id": self.sticker_file_unique_id, @@ -181,7 +181,7 @@ def test_de_json(self, bot, sticker): "custom_emoji_id": self.custom_emoji_id, "needs_repainting": self.needs_repainting, } - json_sticker = Sticker.de_json(json_dict, bot) + json_sticker = Sticker.de_json(json_dict, offline_bot) assert json_sticker.api_kwargs == {} assert json_sticker.file_id == self.sticker_file_id @@ -284,22 +284,22 @@ def test_equality(self, sticker): assert a != e assert hash(a) != hash(e) - async def test_error_without_required_args(self, bot, chat_id): + async def test_error_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.send_sticker(chat_id) + await offline_bot.send_sticker(chat_id) - async def test_send_with_sticker(self, monkeypatch, bot, chat_id, sticker): + async def test_send_with_sticker(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_send_sticker_local_files(self, monkeypatch, offline_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 + offline_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() @@ -311,11 +311,11 @@ async def make_assertion(_, data, *args, **kwargs): else: test_flag = isinstance(data.get("sticker"), InputFile) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_sticker(chat_id, file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_sticker(chat_id, file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False @pytest.mark.parametrize( ("default_bot", "custom"), @@ -587,8 +587,8 @@ def test_slot_behaviour(self): 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}" + def test_de_json(self, offline_bot, sticker): + name = f"test_by_{offline_bot.username}" json_dict = { "name": name, "title": self.title, @@ -597,7 +597,7 @@ def test_de_json(self, bot, sticker): "sticker_type": self.sticker_type, "contains_masks": self.contains_masks, } - sticker_set = StickerSet.de_json(json_dict, bot) + sticker_set = StickerSet.de_json(json_dict, offline_bot) assert sticker_set.name == name assert sticker_set.title == self.title @@ -653,11 +653,11 @@ def test_equality(self): @pytest.mark.parametrize("local_mode", [True, False]) async def test_upload_sticker_file_local_files( - self, monkeypatch, bot, chat_id, local_mode, recwarn + self, monkeypatch, offline_bot, chat_id, local_mode, recwarn ): try: - bot._local_mode = local_mode - # For just test that the correct paths are passed as we have no local bot API set up + offline_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() @@ -670,24 +670,24 @@ async def make_assertion(_, data, *args, **kwargs): else isinstance(data.get("sticker"), InputFile) ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.upload_sticker_file( + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.upload_sticker_file( chat_id, sticker=file, sticker_format=StickerFormat.STATIC ) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False @pytest.mark.parametrize("local_mode", [True, False]) async def test_create_new_sticker_set_local_files( self, monkeypatch, - bot, + offline_bot, chat_id, local_mode, ): - monkeypatch.setattr(bot, "_local_mode", local_mode) - # For just test that the correct paths are passed as we have no local bot API set up + monkeypatch.setattr(offline_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") # always assumed to be local mode because we don't have access to local_mode setting @@ -698,8 +698,8 @@ async def make_assertion(_, data, *args, **kwargs): nonlocal test_flag test_flag = data.get("stickers")[0].sticker == expected - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.create_new_sticker_set( + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.create_new_sticker_set( chat_id, "name", "title", @@ -707,7 +707,9 @@ async def make_assertion(_, data, *args, **kwargs): ) assert test_flag - async def test_create_new_sticker_all_params(self, monkeypatch, bot, chat_id, mask_position): + async def test_create_new_sticker_all_params( + self, monkeypatch, offline_bot, chat_id, mask_position + ): async def make_assertion(_, data, *args, **kwargs): assert data["user_id"] == chat_id assert data["name"] == "name" @@ -715,8 +717,8 @@ async def make_assertion(_, data, *args, **kwargs): assert data["stickers"] == ["wow.png", "wow.tgs", "wow.webp"] assert data["needs_repainting"] is True - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.create_new_sticker_set( + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.create_new_sticker_set( chat_id, "name", "title", @@ -725,9 +727,11 @@ async def make_assertion(_, data, *args, **kwargs): ) @pytest.mark.parametrize("local_mode", [True, False]) - async def test_add_sticker_to_set_local_files(self, monkeypatch, bot, chat_id, local_mode): - monkeypatch.setattr(bot, "_local_mode", local_mode) - # For just test that the correct paths are passed as we have no local bot API set up + async def test_add_sticker_to_set_local_files( + self, monkeypatch, offline_bot, chat_id, local_mode + ): + monkeypatch.setattr(offline_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") # always assumed to be local mode because we don't have access to local_mode setting @@ -738,8 +742,8 @@ async def make_assertion(_, data, *args, **kwargs): nonlocal test_flag test_flag = data.get("sticker").sticker == expected - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.add_sticker_to_set( + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.add_sticker_to_set( chat_id, "name", sticker=InputSticker(sticker=file, emoji_list=["this"], format="static"), @@ -748,11 +752,11 @@ async def make_assertion(_, data, *args, **kwargs): @pytest.mark.parametrize("local_mode", [True, False]) async def test_set_sticker_set_thumbnail_local_files( - self, monkeypatch, bot, chat_id, local_mode + self, monkeypatch, offline_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 + offline_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() @@ -764,11 +768,13 @@ async def make_assertion(_, data, *args, **kwargs): else: test_flag = isinstance(data.get("thumbnail"), InputFile) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.set_sticker_set_thumbnail("name", chat_id, thumbnail=file, format="static") + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.set_sticker_set_thumbnail( + "name", chat_id, thumbnail=file, format="static" + ) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, sticker): async def make_assertion(*_, **kwargs): @@ -1085,14 +1091,14 @@ def test_slot_behaviour(self, mask_position): 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): + def test_mask_position_de_json(self, offline_bot): json_dict = { "point": self.point, "x_shift": self.x_shift, "y_shift": self.y_shift, "scale": self.scale, } - mask_position = MaskPosition.de_json(json_dict, bot) + mask_position = MaskPosition.de_json(json_dict, offline_bot) assert mask_position.api_kwargs == {} assert mask_position.point == self.point diff --git a/tests/_files/test_venue.py b/tests/_files/test_venue.py index b78223bbf5d..31883591e2a 100644 --- a/tests/_files/test_venue.py +++ b/tests/_files/test_venue.py @@ -57,7 +57,7 @@ def test_slot_behaviour(self, venue): assert getattr(venue, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(venue)) == len(set(mro_slots(venue))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "location": self.location.to_dict(), "title": self.title, @@ -67,7 +67,7 @@ def test_de_json(self, bot): "google_place_id": self.google_place_id, "google_place_type": self.google_place_type, } - venue = Venue.de_json(json_dict, bot) + venue = Venue.de_json(json_dict, offline_bot) assert venue.api_kwargs == {} assert venue.location == self.location @@ -110,13 +110,13 @@ def test_equality(self): assert a != d2 assert hash(a) != hash(d2) - async def test_send_venue_without_required(self, bot, chat_id): + async def test_send_venue_without_required(self, offline_bot, chat_id): with pytest.raises(ValueError, match="Either venue or latitude, longitude, address and"): - await bot.send_venue(chat_id=chat_id) + await offline_bot.send_venue(chat_id=chat_id) - async def test_send_venue_mutually_exclusive(self, bot, chat_id, venue): + async def test_send_venue_mutually_exclusive(self, offline_bot, chat_id, venue): with pytest.raises(ValueError, match="Not both"): - await bot.send_venue( + await offline_bot.send_venue( chat_id=chat_id, latitude=1, longitude=1, @@ -125,7 +125,7 @@ async def test_send_venue_mutually_exclusive(self, bot, chat_id, venue): venue=venue, ) - async def test_send_with_venue(self, monkeypatch, bot, chat_id, venue): + async def test_send_with_venue(self, monkeypatch, offline_bot, chat_id, venue): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters return ( @@ -139,8 +139,8 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): and data["google_place_type"] == self.google_place_type ) - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.send_venue(chat_id, venue=venue) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + message = await offline_bot.send_venue(chat_id, venue=venue) assert message @pytest.mark.parametrize( diff --git a/tests/_files/test_video.py b/tests/_files/test_video.py index 06666ea16b6..d4ace54e3e5 100644 --- a/tests/_files/test_video.py +++ b/tests/_files/test_video.py @@ -93,7 +93,7 @@ def test_expected_values(self, video): assert video.file_size == self.file_size assert video.mime_type == self.mime_type - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "file_id": self.video_file_id, "file_unique_id": self.video_file_unique_id, @@ -104,7 +104,7 @@ def test_de_json(self, bot): "file_size": self.file_size, "file_name": self.file_name, } - json_video = Video.de_json(json_dict, bot) + json_video = Video.de_json(json_dict, offline_bot) assert json_video.api_kwargs == {} assert json_video.file_id == self.video_file_id @@ -149,30 +149,30 @@ def test_equality(self, video): assert a != e assert hash(a) != hash(e) - async def test_error_without_required_args(self, bot, chat_id): + async def test_error_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.send_video(chat_id=chat_id) + await offline_bot.send_video(chat_id=chat_id) - async def test_send_with_video(self, monkeypatch, bot, chat_id, video): + async def test_send_with_video(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_video(chat_id, video=video) - async def test_send_video_custom_filename(self, bot, chat_id, video_file, monkeypatch): + async def test_send_video_custom_filename(self, offline_bot, chat_id, video_file, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.send_video(chat_id, video_file, filename="custom_filename") + assert await offline_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): + async def test_send_video_local_files(self, monkeypatch, offline_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 + offline_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() @@ -186,11 +186,11 @@ async def make_assertion(_, data, *args, **kwargs): data.get("thumbnail"), InputFile ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_video(chat_id, file, thumbnail=file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_video(chat_id, file, thumbnail=file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, video): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_videonote.py b/tests/_files/test_videonote.py index b86355e446d..d85de9fb4b0 100644 --- a/tests/_files/test_videonote.py +++ b/tests/_files/test_videonote.py @@ -85,7 +85,7 @@ def test_expected_values(self, video_note): assert video_note.duration == self.duration assert video_note.file_size == self.file_size - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "file_id": self.videonote_file_id, "file_unique_id": self.videonote_file_unique_id, @@ -93,7 +93,7 @@ def test_de_json(self, bot): "duration": self.duration, "file_size": self.file_size, } - json_video_note = VideoNote.de_json(json_dict, bot) + json_video_note = VideoNote.de_json(json_dict, offline_bot) assert json_video_note.api_kwargs == {} assert json_video_note.file_id == self.videonote_file_id @@ -132,32 +132,36 @@ def test_equality(self, video_note): assert a != e assert hash(a) != hash(e) - async def test_error_without_required_args(self, bot, chat_id): + async def test_error_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.send_video_note(chat_id=chat_id) + await offline_bot.send_video_note(chat_id=chat_id) - async def test_send_with_video_note(self, monkeypatch, bot, chat_id, video_note): + async def test_send_with_video_note(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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 + self, offline_bot, chat_id, video_note_file, monkeypatch ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.send_video_note(chat_id, video_note_file, filename="custom_filename") + assert await offline_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): + async def test_send_video_note_local_files( + self, monkeypatch, offline_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 + offline_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() @@ -173,11 +177,11 @@ async def make_assertion(_, data, *args, **kwargs): data.get("thumbnail"), InputFile ) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_video_note(chat_id, file, thumbnail=file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_video_note(chat_id, file, thumbnail=file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, video_note): async def make_assertion(*_, **kwargs): diff --git a/tests/_files/test_voice.py b/tests/_files/test_voice.py index 454db0aaef4..e32bb195c8e 100644 --- a/tests/_files/test_voice.py +++ b/tests/_files/test_voice.py @@ -78,7 +78,7 @@ def test_expected_values(self, voice): assert voice.mime_type == self.mime_type assert voice.file_size == self.file_size - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "file_id": self.voice_file_id, "file_unique_id": self.voice_file_unique_id, @@ -86,7 +86,7 @@ def test_de_json(self, bot): "mime_type": self.mime_type, "file_size": self.file_size, } - json_voice = Voice.de_json(json_dict, bot) + json_voice = Voice.de_json(json_dict, offline_bot) assert json_voice.api_kwargs == {} assert json_voice.file_id == self.voice_file_id @@ -125,30 +125,30 @@ def test_equality(self, voice): assert a != e assert hash(a) != hash(e) - async def test_error_without_required_args(self, bot, chat_id): + async def test_error_without_required_args(self, offline_bot, chat_id): with pytest.raises(TypeError): - await bot.sendVoice(chat_id) + await offline_bot.sendVoice(chat_id) - async def test_send_voice_custom_filename(self, bot, chat_id, voice_file, monkeypatch): + async def test_send_voice_custom_filename(self, offline_bot, chat_id, voice_file, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return next(iter(request_data.multipart_data.values()))[0] == "custom_filename" - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.send_voice(chat_id, voice_file, filename="custom_filename") + assert await offline_bot.send_voice(chat_id, voice_file, filename="custom_filename") - async def test_send_with_voice(self, monkeypatch, bot, chat_id, voice): + async def test_send_with_voice(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_send_voice_local_files(self, monkeypatch, offline_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 + offline_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() @@ -160,11 +160,11 @@ async def make_assertion(_, data, *args, **kwargs): else: test_flag = isinstance(data.get("voice"), InputFile) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.send_voice(chat_id, file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.send_voice(chat_id, file) assert test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False async def test_get_file_instance_method(self, monkeypatch, voice): async def make_assertion(*_, **kwargs): diff --git a/tests/_games/test_game.py b/tests/_games/test_game.py index 23e0d5e9cea..89a6013211d 100644 --- a/tests/_games/test_game.py +++ b/tests/_games/test_game.py @@ -55,20 +55,20 @@ def test_slot_behaviour(self, game): assert getattr(game, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(game)) == len(set(mro_slots(game))), "duplicate slot" - def test_de_json_required(self, bot): + def test_de_json_required(self, offline_bot): json_dict = { "title": self.title, "description": self.description, "photo": [self.photo[0].to_dict()], } - game = Game.de_json(json_dict, bot) + game = Game.de_json(json_dict, offline_bot) assert game.api_kwargs == {} assert game.title == self.title assert game.description == self.description assert game.photo == tuple(self.photo) - def test_de_json_all(self, bot): + def test_de_json_all(self, offline_bot): json_dict = { "title": self.title, "description": self.description, @@ -77,7 +77,7 @@ def test_de_json_all(self, bot): "text_entities": [self.text_entities[0].to_dict()], "animation": self.animation.to_dict(), } - game = Game.de_json(json_dict, bot) + game = Game.de_json(json_dict, offline_bot) assert game.api_kwargs == {} assert game.title == self.title diff --git a/tests/_games/test_gamehighscore.py b/tests/_games/test_gamehighscore.py index fc76867b499..c07488c80fc 100644 --- a/tests/_games/test_gamehighscore.py +++ b/tests/_games/test_gamehighscore.py @@ -42,20 +42,20 @@ def test_slot_behaviour(self, game_highscore): 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): + def test_de_json(self, offline_bot): json_dict = { "position": self.position, "user": self.user.to_dict(), "score": self.score, } - highscore = GameHighScore.de_json(json_dict, bot) + highscore = GameHighScore.de_json(json_dict, offline_bot) assert highscore.api_kwargs == {} assert highscore.position == self.position assert highscore.user == self.user assert highscore.score == self.score - assert GameHighScore.de_json(None, bot) is None + assert GameHighScore.de_json(None, offline_bot) is None def test_to_dict(self, game_highscore): game_highscore_dict = game_highscore.to_dict() diff --git a/tests/_inline/test_inlinekeyboardbutton.py b/tests/_inline/test_inlinekeyboardbutton.py index 2569a8902ea..6e406f3ecc3 100644 --- a/tests/_inline/test_inlinekeyboardbutton.py +++ b/tests/_inline/test_inlinekeyboardbutton.py @@ -116,7 +116,7 @@ def test_to_dict(self, inline_keyboard_button): == inline_keyboard_button.switch_inline_query_chosen_chat.to_dict() ) - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "text": self.text, "url": self.url, @@ -150,7 +150,7 @@ def test_de_json(self, bot): == self.switch_inline_query_chosen_chat ) - none = InlineKeyboardButton.de_json({}, bot) + none = InlineKeyboardButton.de_json({}, offline_bot) assert none is None def test_equality(self): diff --git a/tests/_inline/test_inlinekeyboardmarkup.py b/tests/_inline/test_inlinekeyboardmarkup.py index 2f5bd2a5adf..461379436b9 100644 --- a/tests/_inline/test_inlinekeyboardmarkup.py +++ b/tests/_inline/test_inlinekeyboardmarkup.py @@ -192,7 +192,9 @@ def test_wrong_keyboard_inputs(self): with pytest.raises(ValueError, match="should be a sequence of sequences"): InlineKeyboardMarkup([[[InlineKeyboardButton("only_2d_array_is_allowed", "1")]]]) - async def test_expected_values_empty_switch(self, inline_keyboard_markup, bot, monkeypatch): + async def test_expected_values_empty_switch( + self, inline_keyboard_markup, offline_bot, monkeypatch + ): async def make_assertion( url, data, @@ -224,8 +226,8 @@ async def make_assertion( 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) + monkeypatch.setattr(offline_bot, "_send_message", make_assertion) + await offline_bot.send_message(123, "test", reply_markup=inline_keyboard_markup) class TestInlineKeyborardMarkupWithRequest(InlineKeyboardMarkupTestBase): diff --git a/tests/_inline/test_inlinequery.py b/tests/_inline/test_inlinequery.py index 4d2e73ffb87..7ff22c445c5 100644 --- a/tests/_inline/test_inlinequery.py +++ b/tests/_inline/test_inlinequery.py @@ -55,7 +55,7 @@ def test_slot_behaviour(self, inline_query): assert getattr(inline_query, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(inline_query)) == len(set(mro_slots(inline_query))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "from": self.from_user.to_dict(), @@ -63,7 +63,7 @@ def test_de_json(self, bot): "offset": self.offset, "location": self.location.to_dict(), } - inline_query_json = InlineQuery.de_json(json_dict, bot) + inline_query_json = InlineQuery.de_json(json_dict, offline_bot) assert inline_query_json.api_kwargs == {} assert inline_query_json.id == self.id_ diff --git a/tests/_inline/test_inputinvoicemessagecontent.py b/tests/_inline/test_inputinvoicemessagecontent.py index 17bfad01359..4e35e9f6f43 100644 --- a/tests/_inline/test_inputinvoicemessagecontent.py +++ b/tests/_inline/test_inputinvoicemessagecontent.py @@ -203,8 +203,8 @@ def test_to_dict(self, input_invoice_message_content): == input_invoice_message_content.is_flexible ) - def test_de_json(self, bot): - assert InputInvoiceMessageContent.de_json({}, bot=bot) is None + def test_de_json(self, offline_bot): + assert InputInvoiceMessageContent.de_json({}, bot=offline_bot) is None json_dict = { "title": self.title, @@ -229,7 +229,9 @@ def test_de_json(self, bot): "is_flexible": self.is_flexible, } - input_invoice_message_content = InputInvoiceMessageContent.de_json(json_dict, bot=bot) + input_invoice_message_content = InputInvoiceMessageContent.de_json( + json_dict, bot=offline_bot + ) assert input_invoice_message_content.api_kwargs == {} assert input_invoice_message_content.title == self.title diff --git a/tests/_passport/test_no_passport.py b/tests/_passport/test_no_passport.py index 8b1af252cb3..ff3ce0a439c 100644 --- a/tests/_passport/test_no_passport.py +++ b/tests/_passport/test_no_passport.py @@ -28,7 +28,7 @@ """ import pytest -from telegram import _bot as bot +import telegram from telegram._passport import credentials from tests.auxil.envvars import TEST_WITH_OPT_DEPS @@ -39,7 +39,7 @@ 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) + telegram.Bot(bot_info["token"], private_key=1, private_key_password=2) def test_credentials_decrypt(self): with pytest.raises(RuntimeError, match="passport"): diff --git a/tests/_passport/test_passport.py b/tests/_passport/test_passport.py index 9303ae7eb13..b094f808f81 100644 --- a/tests/_passport/test_passport.py +++ b/tests/_passport/test_passport.py @@ -390,8 +390,8 @@ 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) + def test_de_json_and_to_dict(self, offline_bot): + passport_data = PassportData.de_json(RAW_PASSPORT_DATA, offline_bot) assert passport_data.api_kwargs == {} assert passport_data.to_dict() == RAW_PASSPORT_DATA @@ -414,14 +414,14 @@ def test_equality(self, passport_data): assert a != c assert hash(a) != hash(c) - def test_bot_init_invalid_key(self, bot): + def test_bot_init_invalid_key(self, offline_bot): with pytest.raises(TypeError): - Bot(bot.token, private_key="Invalid key!") + Bot(offline_bot.token, private_key="Invalid key!") with pytest.raises(ValueError, match="Could not deserialize key data"): - Bot(bot.token, private_key=b"Invalid key!") + Bot(offline_bot.token, private_key=b"Invalid key!") - def test_all_types(self, passport_data, bot, all_passport_data): + def test_all_types(self, passport_data, offline_bot, all_passport_data): credentials = passport_data.decrypted_credentials.to_dict() # Copy credentials from other types to all types so we can decrypt everything @@ -446,46 +446,46 @@ def test_all_types(self, passport_data, bot, all_passport_data): # Replaced below "credentials": {"data": "data", "hash": "hash", "secret": "secret"}, }, - bot=bot, + bot=offline_bot, ) assert new.api_kwargs == {} - new.credentials._decrypted_data = Credentials.de_json(credentials, bot) + new.credentials._decrypted_data = Credentials.de_json(credentials, offline_bot) assert new.credentials.api_kwargs == {} assert isinstance(new, PassportData) assert new.decrypted_data - async def test_passport_data_okay_with_non_crypto_bot(self, bot): - async with make_bot(token=bot.token) as b: + async def test_passport_data_okay_with_non_crypto_bot(self, offline_bot): + async with make_bot(token=offline_bot.token) as b: assert PassportData.de_json(RAW_PASSPORT_DATA, bot=b) - def test_wrong_hash(self, bot): + def test_wrong_hash(self, offline_bot): data = deepcopy(RAW_PASSPORT_DATA) data["credentials"]["hash"] = "bm90Y29ycmVjdGhhc2g=" # Not correct hash - passport_data = PassportData.de_json(data, bot=bot) + passport_data = PassportData.de_json(data, bot=offline_bot) with pytest.raises(PassportDecryptionError): assert passport_data.decrypted_data - async def test_wrong_key(self, bot): + async def test_wrong_key(self, offline_bot): short_key = ( b"-----BEGIN RSA PRIVATE" b" KEY-----\r\nMIIBOQIBAAJBAKU+OZ2jJm7sCA/ec4gngNZhXYPu+DZ/TAwSMl0W7vAPXAsLplBk\r\nO8l6IBHx8N0ZC4Bc65mO3b2G8YAzqndyqH8CAwEAAQJAWOx3jQFzeVXDsOaBPdAk\r\nYTncXVeIc6tlfUl9mOLyinSbRNCy1XicOiOZFgH1rRKOGIC1235QmqxFvdecySoY\r\nwQIhAOFeGgeX9CrEPuSsd9+kqUcA2avCwqdQgSdy2qggRFyJAiEAu7QHT8JQSkHU\r\nDELfzrzc24AhjyG0z1DpGZArM8COascCIDK42SboXj3Z2UXiQ0CEcMzYNiVgOisq\r\nBUd5pBi+2mPxAiAM5Z7G/Sv1HjbKrOGh29o0/sXPhtpckEuj5QMC6E0gywIgFY6S\r\nNjwrAA+cMmsgY0O2fAzEKkDc5YiFsiXaGaSS4eA=\r\n-----END" b" RSA PRIVATE KEY-----" ) - async with make_bot(token=bot.token, private_key=short_key) as b: + async with make_bot(token=offline_bot.token, private_key=short_key) as b: passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot=b) with pytest.raises(PassportDecryptionError): assert passport_data.decrypted_data - async with make_bot(token=bot.token, private_key=short_key) as b: + async with make_bot(token=offline_bot.token, private_key=short_key) as b: passport_data = PassportData.de_json(RAW_PASSPORT_DATA, bot=b) with pytest.raises(PassportDecryptionError): assert passport_data.decrypted_data async def test_mocked_download_passport_file(self, passport_data, monkeypatch): - # The files are not coming from our test bot, therefore the file id is invalid/wrong - # when coming from this bot, so we monkeypatch the call, to make sure that Bot.get_file + # The files are not coming from our test offline_bot, therefore the file id is invalid/wrong + # when coming from this offline_bot, so we monkeypatch the call, to make sure that Bot.get_file # at least gets called # TODO: Actually download a passport file in a test selfie = passport_data.decrypted_data[1].selfie @@ -501,7 +501,9 @@ async def get_file(*_, **kwargs): 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 test_mocked_set_passport_data_errors( + self, monkeypatch, offline_bot, chat_id, passport_data + ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.parameters return ( @@ -514,8 +516,8 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): == passport_data.decrypted_credentials.secure_data.driver_license.data.data_hash ) - monkeypatch.setattr(bot.request, "post", make_assertion) - message = await bot.set_passport_data_errors( + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + message = await offline_bot.set_passport_data_errors( chat_id, [ PassportElementErrorSelfie( diff --git a/tests/_payment/test_invoice.py b/tests/_payment/test_invoice.py index 2293fe58745..585f4fd3e62 100644 --- a/tests/_payment/test_invoice.py +++ b/tests/_payment/test_invoice.py @@ -58,7 +58,7 @@ def test_slot_behaviour(self, invoice): assert getattr(invoice, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(invoice)) == len(set(mro_slots(invoice))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): invoice_json = Invoice.de_json( { "title": self.title, @@ -67,7 +67,7 @@ def test_de_json(self, bot): "currency": self.currency, "total_amount": self.total_amount, }, - bot, + offline_bot, ) assert invoice_json.api_kwargs == {} @@ -87,15 +87,15 @@ def test_to_dict(self, invoice): assert invoice_dict["currency"] == invoice.currency assert invoice_dict["total_amount"] == invoice.total_amount - async def test_send_invoice_all_args_mock(self, bot, monkeypatch): + async def test_send_invoice_all_args_mock(self, offline_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 all(kwargs[key] == key for key in kwargs) - monkeypatch.setattr(bot, "_send_message", make_assertion) - assert await bot.send_invoice( + monkeypatch.setattr(offline_bot, "_send_message", make_assertion) + assert await offline_bot.send_invoice( chat_id="chat_id", title="title", description="description", @@ -122,13 +122,13 @@ async def make_assertion(*args, **_): protect_content=True, ) - async def test_send_all_args_create_invoice_link(self, bot, monkeypatch): + async def test_send_all_args_create_invoice_link(self, offline_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( + monkeypatch.setattr(offline_bot, "_post", make_assertion) + assert await offline_bot.create_invoice_link( title="title", description="description", payload="payload", @@ -151,13 +151,15 @@ async def make_assertion(*args, **_): is_flexible="is_flexible", ) - async def test_send_object_as_provider_data(self, monkeypatch, bot, chat_id, provider_token): + async def test_send_object_as_provider_data( + self, monkeypatch, offline_bot, chat_id, provider_token + ): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.json_parameters["provider_data"] == '{"test_data": 123456789}' - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.send_invoice( + assert await offline_bot.send_invoice( chat_id, self.title, self.description, diff --git a/tests/_payment/test_orderinfo.py b/tests/_payment/test_orderinfo.py index 8e27ed34390..4f6317222da 100644 --- a/tests/_payment/test_orderinfo.py +++ b/tests/_payment/test_orderinfo.py @@ -45,14 +45,14 @@ def test_slot_behaviour(self, order_info): assert getattr(order_info, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(order_info)) == len(set(mro_slots(order_info))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_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) + order_info = OrderInfo.de_json(json_dict, offline_bot) assert order_info.api_kwargs == {} assert order_info.name == self.name diff --git a/tests/_payment/test_precheckoutquery.py b/tests/_payment/test_precheckoutquery.py index aaca70407a4..e61adbcf9c3 100644 --- a/tests/_payment/test_precheckoutquery.py +++ b/tests/_payment/test_precheckoutquery.py @@ -60,7 +60,7 @@ def test_slot_behaviour(self, pre_checkout_query): 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): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "invoice_payload": self.invoice_payload, @@ -70,10 +70,10 @@ def test_de_json(self, bot): "from": self.from_user.to_dict(), "order_info": self.order_info.to_dict(), } - pre_checkout_query = PreCheckoutQuery.de_json(json_dict, bot) + pre_checkout_query = PreCheckoutQuery.de_json(json_dict, offline_bot) assert pre_checkout_query.api_kwargs == {} - assert pre_checkout_query.get_bot() is bot + assert pre_checkout_query.get_bot() is offline_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 diff --git a/tests/_payment/test_refundedpayment.py b/tests/_payment/test_refundedpayment.py index 8ea4d1a5001..32581f785f8 100644 --- a/tests/_payment/test_refundedpayment.py +++ b/tests/_payment/test_refundedpayment.py @@ -48,7 +48,7 @@ def test_slot_behaviour(self, refunded_payment): 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): + def test_de_json(self, offline_bot): json_dict = { "invoice_payload": self.invoice_payload, "currency": self.currency, @@ -56,7 +56,7 @@ def test_de_json(self, bot): "telegram_payment_charge_id": self.telegram_payment_charge_id, "provider_payment_charge_id": self.provider_payment_charge_id, } - refunded_payment = RefundedPayment.de_json(json_dict, bot) + refunded_payment = RefundedPayment.de_json(json_dict, offline_bot) assert refunded_payment.api_kwargs == {} assert refunded_payment.invoice_payload == self.invoice_payload diff --git a/tests/_payment/test_shippingaddress.py b/tests/_payment/test_shippingaddress.py index 41fbeba5a16..371c8d2fc0c 100644 --- a/tests/_payment/test_shippingaddress.py +++ b/tests/_payment/test_shippingaddress.py @@ -50,7 +50,7 @@ def test_slot_behaviour(self, shipping_address): 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): + def test_de_json(self, offline_bot): json_dict = { "country_code": self.country_code, "state": self.state, @@ -59,7 +59,7 @@ def test_de_json(self, bot): "street_line2": self.street_line2, "post_code": self.post_code, } - shipping_address = ShippingAddress.de_json(json_dict, bot) + shipping_address = ShippingAddress.de_json(json_dict, offline_bot) assert shipping_address.api_kwargs == {} assert shipping_address.country_code == self.country_code diff --git a/tests/_payment/test_shippingquery.py b/tests/_payment/test_shippingquery.py index 4821cbae9c9..da99c1fd177 100644 --- a/tests/_payment/test_shippingquery.py +++ b/tests/_payment/test_shippingquery.py @@ -54,21 +54,21 @@ def test_slot_behaviour(self, shipping_query): 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): + def test_de_json(self, offline_bot): json_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) + shipping_query = ShippingQuery.de_json(json_dict, offline_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.get_bot() is bot + assert shipping_query.get_bot() is offline_bot def test_to_dict(self, shipping_query): shipping_query_dict = shipping_query.to_dict() diff --git a/tests/_payment/test_successfulpayment.py b/tests/_payment/test_successfulpayment.py index c4562d0a87d..2b4cf091850 100644 --- a/tests/_payment/test_successfulpayment.py +++ b/tests/_payment/test_successfulpayment.py @@ -52,7 +52,7 @@ def test_slot_behaviour(self, successful_payment): 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): + def test_de_json(self, offline_bot): json_dict = { "invoice_payload": self.invoice_payload, "shipping_option_id": self.shipping_option_id, @@ -62,7 +62,7 @@ def test_de_json(self, bot): "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) + successful_payment = SuccessfulPayment.de_json(json_dict, offline_bot) assert successful_payment.api_kwargs == {} assert successful_payment.invoice_payload == self.invoice_payload diff --git a/tests/conftest.py b/tests/conftest.py index e8ef01cabac..b637f89573c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,9 +39,9 @@ ) from telegram.ext import Defaults from tests.auxil.build_messages import DATE -from tests.auxil.ci_bots import BOT_INFO_PROVIDER +from tests.auxil.ci_bots import BOT_INFO_PROVIDER, JOB_INDEX from tests.auxil.constants import PRIVATE_KEY -from tests.auxil.envvars import RUN_TEST_OFFICIAL, TEST_WITH_OPT_DEPS +from tests.auxil.envvars import GITHUB_ACTION, RUN_TEST_OFFICIAL, TEST_WITH_OPT_DEPS from tests.auxil.files import data_file from tests.auxil.networking import NonchalantHttpxRequest from tests.auxil.pytest_classes import PytestBot, make_bot @@ -98,6 +98,39 @@ def pytest_collection_modifyitems(items: List[pytest.Item]): parent.add_marker(pytest.mark.no_req) +if GITHUB_ACTION and JOB_INDEX == 0: + # let's not slow down the tests too much with these additional checks + # that's why we run them only in GitHub actions and only on *one* of the several test + # matrix entries + @pytest.fixture(autouse=True) + def _disallow_requests_in_without_request_tests(request): + """This fixture prevents tests that don't require requests from using the online-bot. + This is a sane-effort approach on trying to prevent requests from being made in the + *WithoutRequest classes. Note that we can not prevent all requests, as one can still + manually build a `Bot` object or use `httpx` directly. See #4317 and #4465 for some + discussion. + """ + + if type(request).__name__ == "SubRequest": + # Some fixtures used in the *WithoutRequests test classes do use requests, e.g. + # `animation`. Separating that would be too much effort, hence we allow that. + # Unfortunately the `SubRequest` class is not public, so we check only the name for + # less dependency on pytest's internal structure. + return + + if not request.cls: + return + name = request.cls.__name__ + if not name.endswith("WithoutRequest") or not request.fixturenames: + return + + if "bot" in request.fixturenames: + pytest.fail( + f"Test function {request.function} in test class {name} should not have a `bot` " + f"fixture. Use `offline_bot` instead." + ) + + # Redefine the event_loop fixture to have a session scope. Otherwise `bot` fixture can't be # session. See https://github.com/pytest-dev/pytest-asyncio/issues/68 for more details. @pytest.fixture(scope="session") diff --git a/tests/request/test_request.py b/tests/request/test_request.py index 2bbfcf52de6..bd186c2efb3 100644 --- a/tests/request/test_request.py +++ b/tests/request/test_request.py @@ -84,7 +84,7 @@ async def httpx_request(): TEST_WITH_OPT_DEPS, reason="Only relevant if the optional dependency is not installed" ) class TestNoSocksHTTP2WithoutRequest: - async def test_init(self, bot): + async def test_init(self, offline_bot): with pytest.raises(RuntimeError, match=r"python-telegram-bot\[socks\]"): HTTPXRequest(proxy="socks5://foo") with pytest.raises(RuntimeError, match=r"python-telegram-bot\[http2\]"): @@ -546,28 +546,10 @@ async def aclose(*args, **kwargs): assert self.test_flag["init"] == 1 assert self.test_flag["shutdown"] == 1 - async def test_multiple_init_cycles(self): - # nothing really to assert - this should just not fail - httpx_request = HTTPXRequest() - async with httpx_request: - await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET") - async with httpx_request: - await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET") - async def test_http_version_error(self): with pytest.raises(ValueError, match="`http_version` must be either"): HTTPXRequest(http_version="1.0") - async def test_http_1_response(self): - httpx_request = HTTPXRequest(http_version="1.1") - async with httpx_request: - resp = await httpx_request._client.request( - url="https://python-telegram-bot.org", - method="GET", - headers={"User-Agent": httpx_request.USER_AGENT}, - ) - assert resp.http_version == "HTTP/1.1" - async def test_do_request_after_shutdown(self, httpx_request): await httpx_request.shutdown() with pytest.raises(RuntimeError, match="not initialized"): @@ -831,6 +813,24 @@ async def test_read_timeout_property(self, read_timeout): @pytest.mark.skipif(not TEST_WITH_OPT_DEPS, reason="No need to run this twice") class TestHTTPXRequestWithRequest: + async def test_multiple_init_cycles(self): + # nothing really to assert - this should just not fail + httpx_request = HTTPXRequest() + async with httpx_request: + await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET") + async with httpx_request: + await httpx_request.do_request(url="https://python-telegram-bot.org", method="GET") + + async def test_http_1_response(self): + httpx_request = HTTPXRequest(http_version="1.1") + async with httpx_request: + resp = await httpx_request._client.request( + url="https://python-telegram-bot.org", + method="GET", + headers={"User-Agent": httpx_request.USER_AGENT}, + ) + assert resp.http_version == "HTTP/1.1" + 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_birthdate.py b/tests/test_birthdate.py index c22ebd9affd..11cb96a182e 100644 --- a/tests/test_birthdate.py +++ b/tests/test_birthdate.py @@ -48,9 +48,9 @@ def test_to_dict(self, birthdate): assert bd_dict["month"] == self.month assert bd_dict["year"] == self.year - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = {"day": self.day, "month": self.month, "year": self.year} - bd = Birthdate.de_json(json_dict, bot) + bd = Birthdate.de_json(json_dict, offline_bot) assert isinstance(bd, Birthdate) assert bd.day == self.day assert bd.month == self.month diff --git a/tests/test_bot.py b/tests/test_bot.py index 705b14c6d4d..fa723093f37 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -99,7 +99,7 @@ from tests.auxil.ci_bots import FALLBACKS from tests.auxil.envvars import GITHUB_ACTION, TEST_WITH_OPT_DEPS from tests.auxil.files import data_file -from tests.auxil.networking import NonchalantHttpxRequest, expect_bad_request +from tests.auxil.networking import OfflineRequest, expect_bad_request from tests.auxil.pytest_classes import PytestBot, PytestExtBot, make_bot from tests.auxil.slots import mro_slots @@ -224,8 +224,8 @@ def _reset(self): self.test_flag = None @pytest.mark.parametrize("bot_class", [Bot, ExtBot]) - def test_slot_behaviour(self, bot_class, bot): - inst = bot_class(bot.token) + def test_slot_behaviour(self, bot_class, offline_bot): + inst = bot_class(offline_bot.token) 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" @@ -235,27 +235,27 @@ async def test_no_token_passed(self): Bot("") async def test_repr(self): - bot = Bot(token="some_token", base_file_url="") - assert repr(bot) == "Bot[token=some_token]" + offline_bot = Bot(token="some_token", base_file_url="") + assert repr(offline_bot) == "Bot[token=some_token]" - async def test_to_dict(self, bot): - to_dict_bot = bot.to_dict() + async def test_to_dict(self, offline_bot): + to_dict_bot = offline_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 + assert to_dict_bot["id"] == offline_bot.id + assert to_dict_bot["username"] == offline_bot.username + assert to_dict_bot["first_name"] == offline_bot.first_name + if offline_bot.last_name: + assert to_dict_bot["last_name"] == offline_bot.last_name - async def test_initialize_and_shutdown(self, bot: PytestExtBot, monkeypatch): + async def test_initialize_and_shutdown(self, offline_bot: PytestExtBot, monkeypatch): async def initialize(*args, **kwargs): self.test_flag = ["initialize"] async def stop(*args, **kwargs): self.test_flag.append("stop") - temp_bot = PytestBot(token=bot.token, request=NonchalantHttpxRequest()) + temp_bot = PytestBot(token=offline_bot.token, request=OfflineRequest()) orig_stop = temp_bot.request.shutdown try: @@ -263,14 +263,14 @@ async def stop(*args, **kwargs): monkeypatch.setattr(temp_bot.request, "shutdown", stop) await temp_bot.initialize() assert self.test_flag == ["initialize"] - assert temp_bot.bot == bot.bot + assert temp_bot.bot == offline_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): + async def test_multiple_inits_and_shutdowns(self, offline_bot, monkeypatch): self.received = defaultdict(int) async def initialize(*args, **kwargs): @@ -282,7 +282,7 @@ async def shutdown(*args, **kwargs): monkeypatch.setattr(HTTPXRequest, "initialize", initialize) monkeypatch.setattr(HTTPXRequest, "shutdown", shutdown) - test_bot = PytestBot(bot.token) + test_bot = PytestBot(offline_bot.token) await test_bot.initialize() await test_bot.initialize() await test_bot.initialize() @@ -290,37 +290,37 @@ async def shutdown(*args, **kwargs): await test_bot.shutdown() await test_bot.shutdown() - # 2 instead of 1 since we have to request objects for each bot + # 2 instead of 1 since we have to request objects for each offline_bot assert self.received["init"] == 2 assert self.received["shutdown"] == 2 - async def test_context_manager(self, monkeypatch, bot): + async def test_context_manager(self, monkeypatch, offline_bot): async def initialize(): self.test_flag = ["initialize"] async def shutdown(*args): self.test_flag.append("stop") - monkeypatch.setattr(bot, "initialize", initialize) - monkeypatch.setattr(bot, "shutdown", shutdown) + monkeypatch.setattr(offline_bot, "initialize", initialize) + monkeypatch.setattr(offline_bot, "shutdown", shutdown) - async with bot: + async with offline_bot: pass assert self.test_flag == ["initialize", "stop"] - async def test_context_manager_exception_on_init(self, monkeypatch, bot): + async def test_context_manager_exception_on_init(self, monkeypatch, offline_bot): async def initialize(): raise RuntimeError("initialize") async def shutdown(): self.test_flag = "stop" - monkeypatch.setattr(bot, "initialize", initialize) - monkeypatch.setattr(bot, "shutdown", shutdown) + monkeypatch.setattr(offline_bot, "initialize", initialize) + monkeypatch.setattr(offline_bot, "shutdown", shutdown) with pytest.raises(RuntimeError, match="initialize"): - async with bot: + async with offline_bot: pass assert self.test_flag == "stop" @@ -362,43 +362,43 @@ async def test_equality(self): "link", ], ) - async def test_get_me_and_properties_not_initialized(self, bot: Bot, attribute): - bot = Bot(token=bot.token) + async def test_get_me_and_properties_not_initialized(self, offline_bot: Bot, attribute): + offline_bot = Bot(token=offline_bot.token) try: with pytest.raises(RuntimeError, match="not properly initialized"): - bot[attribute] + offline_bot[attribute] finally: - await bot.shutdown() + await offline_bot.shutdown() - async def test_get_me_and_properties(self, bot): - get_me_bot = await ExtBot(bot.token).get_me() + async def test_get_me_and_properties(self, offline_bot): + get_me_bot = await ExtBot(offline_bot.token).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 - - def test_bot_pickling_error(self, bot): + assert get_me_bot.id == offline_bot.id + assert get_me_bot.username == offline_bot.username + assert get_me_bot.first_name == offline_bot.first_name + assert get_me_bot.last_name == offline_bot.last_name + assert get_me_bot.name == offline_bot.name + assert get_me_bot.can_join_groups == offline_bot.can_join_groups + assert get_me_bot.can_read_all_group_messages == offline_bot.can_read_all_group_messages + assert get_me_bot.supports_inline_queries == offline_bot.supports_inline_queries + assert f"https://t.me/{get_me_bot.username}" == offline_bot.link + + def test_bot_pickling_error(self, offline_bot): with pytest.raises(pickle.PicklingError, match="Bot objects cannot be pickled"): - pickle.dumps(bot) + pickle.dumps(offline_bot) - def test_bot_deepcopy_error(self, bot): + def test_bot_deepcopy_error(self, offline_bot): with pytest.raises(TypeError, match="Bot objects cannot be deepcopied"): - copy.deepcopy(bot) + copy.deepcopy(offline_bot) @pytest.mark.parametrize( ("cls", "logger_name"), [(Bot, "telegram.Bot"), (ExtBot, "telegram.ext.ExtBot")] ) - async def test_bot_method_logging(self, bot: PytestExtBot, cls, logger_name, caplog): + async def test_bot_method_logging(self, offline_bot: PytestExtBot, cls, logger_name, caplog): # Second argument makes sure that we ignore logs from e.g. httpx with caplog.at_level(logging.DEBUG, logger="telegram"): - await cls(bot.token).get_me() + await cls(offline_bot.token).get_me() # Only for stabilizing this test- if len(caplog.records) == 4: for idx, record in enumerate(caplog.records): @@ -430,13 +430,13 @@ def test_camel_case_aliases(self, bot_class, bot_method_name, bot_method): @bot_methods(include_do_api_request=True) def test_coroutine_functions(self, bot_class, bot_method_name, bot_method): - """Check that all bot methods are defined as async def ...""" + """Check that all offline_bot methods are defined as async def ...""" 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(include_do_api_request=True) 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.""" + """Check that all offline_bot methods have `api_kwargs` and timeout params.""" param_names = inspect.signature(bot_method).parameters.keys() params = ("pool_timeout", "read_timeout", "connect_timeout", "write_timeout", "api_kwargs") @@ -453,11 +453,12 @@ async def test_defaults_handling( bot_class, bot_method_name: str, bot_method, - bot: PytestExtBot, + offline_bot: PytestExtBot, raw_bot: PytestBot, ): """ - Here we check that the bot methods handle tg.ext.Defaults correctly. This has two parts: + Here we check that the offline_bot methods handle tg.ext.Defaults correctly. This has two + parts: 1. Check that ExtBot actually inserts the defaults values correctly 2. Check that tg.Bot just replaces `DefaultValue(obj)` with `obj`, i.e. that it doesn't @@ -466,8 +467,8 @@ async def test_defaults_handling( As for most defaults, we can't really check the effect, we just check if we're passing the correct kwargs to - Request.post. As bot method tests a scattered across the different test files, we do - this here in one place. + Request.post. As offline_bot method tests a scattered across the different test files, we + do this here in one place. The same test is also run for all the shortcuts (Message.reply_text) etc in the corresponding tests. @@ -477,12 +478,14 @@ async def test_defaults_handling( """ # Mocking get_me within check_defaults_handling messes with the cached values like # Bot.{bot, username, id, …}` unless we return the expected User object. - return_value = bot.bot if bot_method_name.lower().replace("_", "") == "getme" else None + return_value = ( + offline_bot.bot if bot_method_name.lower().replace("_", "") == "getme" else None + ) # Check that ExtBot does the right thing - bot_method = getattr(bot, bot_method_name) + bot_method = getattr(offline_bot, bot_method_name) raw_bot_method = getattr(raw_bot, bot_method_name) - assert await check_defaults_handling(bot_method, bot, return_value=return_value) + assert await check_defaults_handling(bot_method, offline_bot, return_value=return_value) assert await check_defaults_handling(raw_bot_method, raw_bot, return_value=return_value) @pytest.mark.parametrize( @@ -523,19 +526,19 @@ def test_ext_bot_signature(self, name, method): 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 test_unknown_kwargs(self, offline_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( + monkeypatch.setattr(offline_bot.request, "post", post) + await offline_bot.send_message( 123, "text", api_kwargs={"unknown_kwarg_1": 7, "unknown_kwarg_2": 5} ) - async def test_get_updates_deserialization_error(self, bot, monkeypatch, caplog): + async def test_get_updates_deserialization_error(self, offline_bot, monkeypatch, caplog): async def faulty_do_request(*args, **kwargs): return ( HTTPStatus.OK, @@ -544,10 +547,10 @@ async def faulty_do_request(*args, **kwargs): monkeypatch.setattr(HTTPXRequest, "do_request", faulty_do_request) - bot = PytestExtBot(get_updates_request=HTTPXRequest(), token=bot.token) + offline_bot = PytestExtBot(get_updates_request=HTTPXRequest(), token=offline_bot.token) with caplog.at_level(logging.CRITICAL), pytest.raises(AttributeError): - await bot.get_updates() + await offline_bot.get_updates() assert len(caplog.records) == 1 assert caplog.records[0].name == "telegram.ext.ExtBot" @@ -558,7 +561,7 @@ async def faulty_do_request(*args, **kwargs): ) assert caplog.records[0].exc_info[0] is AttributeError - async def test_answer_web_app_query(self, bot, raw_bot, monkeypatch): + async def test_answer_web_app_query(self, offline_bot, raw_bot, monkeypatch): params = False # For now just test that our internals pass the correct data @@ -583,9 +586,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): result = InlineQueryResultArticle("1", "title", InputTextMessageContent("text")) copied_result = copy.copy(result) - ext_bot = bot + ext_bot = offline_bot for bot_type in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with + # We need to test 1) below both the offline_bot and raw_bot and setting this up with # pytest.parametrize appears to be difficult ... monkeypatch.setattr(bot_type.request, "post", make_assertion) web_app_msg = await bot_type.answer_web_app_query("12345", result) @@ -679,7 +682,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): async def test_answer_web_app_query_defaults( self, default_bot, ilq_result, expected_params, monkeypatch ): - bot = default_bot + offline_bot = default_bot params = False # For now just test that our internals pass the correct data @@ -689,13 +692,13 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): params = request_data.parameters == expected_params return SentWebAppMessage("321").to_dict() - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_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) - web_app_msg = await bot.answer_web_app_query("12345", ilq_result) + web_app_msg = await offline_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" @@ -709,7 +712,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): # TODO: Needs improvement. We need incoming inline query to test answer. @pytest.mark.parametrize("button_type", ["start", "web_app"]) - async def test_answer_inline_query(self, monkeypatch, bot, raw_bot, button_type): + async def test_answer_inline_query(self, monkeypatch, offline_bot, raw_bot, button_type): # For now just test that our internals pass the correct data async def make_assertion(url, request_data: RequestData, *args, **kwargs): expected = { @@ -785,9 +788,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): button = None copied_results = copy.copy(results) - ext_bot = bot + ext_bot = offline_bot for bot_type in (ext_bot, raw_bot): - # We need to test 1) below both the bot and raw_bot and setting this up with + # We need to test 1) below both the offline_bot and raw_bot and setting this up with # pytest.parametrize appears to be difficult ... monkeypatch.setattr(bot_type.request, "post", make_assertion) assert await bot_type.answer_inline_query( @@ -817,7 +820,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.delattr(bot_type.request, "post") - async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, bot): + async def test_answer_inline_query_no_default_parse_mode(self, monkeypatch, offline_bot): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.parameters == { "cache_time": 300, @@ -853,7 +856,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): "is_personal": True, } - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) results = [ InlineQueryResultArticle("11", "first", InputTextMessageContent("first")), InlineQueryResultArticle("12", "second", InputMessageContentLPO("second")), @@ -871,7 +874,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ] copied_results = copy.copy(results) - assert await bot.answer_inline_query( + assert await offline_bot.answer_inline_query( 1234, results=results, cache_time=300, @@ -1003,7 +1006,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): async def test_answer_inline_query_current_offset_1( self, monkeypatch, - bot, + offline_bot, inline_results, current_offset, num_results, @@ -1019,13 +1022,15 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): next_offset_matches = data["next_offset"] == str(expected_next_offset) return length_matches and ids_match and next_offset_matches - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_inline_query( + assert await offline_bot.answer_inline_query( 1234, results=inline_results, current_offset=current_offset ) - async def test_answer_inline_query_current_offset_2(self, monkeypatch, bot, inline_results): + async def test_answer_inline_query_current_offset_2( + self, monkeypatch, offline_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 @@ -1035,9 +1040,11 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): next_offset_matches = data["next_offset"] == "1" return length_matches and ids_match and next_offset_matches - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) + assert await offline_bot.answer_inline_query( + 1234, results=inline_results, current_offset=0 + ) inline_results = inline_results[:30] @@ -1049,11 +1056,13 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): next_offset_matches = not data["next_offset"] return length_matches and ids_match and next_offset_matches - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_inline_query(1234, results=inline_results, current_offset=0) + assert await offline_bot.answer_inline_query( + 1234, results=inline_results, current_offset=0 + ) - async def test_answer_inline_query_current_offset_callback(self, monkeypatch, bot): + async def test_answer_inline_query_current_offset_callback(self, monkeypatch, offline_bot): # 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 @@ -1063,9 +1072,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): next_offset = data["next_offset"] == "2" return length and ids and next_offset - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_inline_query( + assert await offline_bot.answer_inline_query( 1234, results=inline_results_callback, current_offset=1 ) @@ -1076,61 +1085,63 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): next_offset = not data["next_offset"] return length and next_offset - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_inline_query( + assert await offline_bot.answer_inline_query( 1234, results=inline_results_callback, current_offset=6 ) - async def test_send_edit_message_mutually_exclusive_link_preview(self, bot, chat_id): + async def test_send_edit_message_mutually_exclusive_link_preview(self, offline_bot, chat_id): """Test that link_preview is mutually exclusive with disable_web_page_preview.""" with pytest.raises(ValueError, match="`link_preview_options` are mutually exclusive"): - await bot.send_message( + await offline_bot.send_message( chat_id, "text", disable_web_page_preview=True, link_preview_options="something" ) with pytest.raises(ValueError, match="`link_preview_options` are mutually exclusive"): - await bot.edit_message_text( + await offline_bot.edit_message_text( "text", chat_id, 1, disable_web_page_preview=True, link_preview_options="something" ) - async def test_rtm_aswr_mutually_exclusive_reply_parameters(self, bot, chat_id): + async def test_rtm_aswr_mutually_exclusive_reply_parameters(self, offline_bot, chat_id): """Test that reply_to_message_id and allow_sending_without_reply are mutually exclusive with reply_parameters.""" with pytest.raises(ValueError, match="`reply_to_message_id` and"): - await bot.send_message(chat_id, "text", reply_to_message_id=1, reply_parameters=True) + await offline_bot.send_message( + chat_id, "text", reply_to_message_id=1, reply_parameters=True + ) with pytest.raises(ValueError, match="`allow_sending_without_reply` and"): - await bot.send_message( + await offline_bot.send_message( chat_id, "text", allow_sending_without_reply=True, reply_parameters=True ) # Test with copy message with pytest.raises(ValueError, match="`reply_to_message_id` and"): - await bot.copy_message( + await offline_bot.copy_message( chat_id, chat_id, 1, reply_to_message_id=1, reply_parameters=True ) with pytest.raises(ValueError, match="`allow_sending_without_reply` and"): - await bot.copy_message( + await offline_bot.copy_message( chat_id, chat_id, 1, allow_sending_without_reply=True, reply_parameters=True ) # Test with send media group media = InputMediaPhoto(photo_file) with pytest.raises(ValueError, match="`reply_to_message_id` and"): - await bot.send_media_group( + await offline_bot.send_media_group( chat_id, media, reply_to_message_id=1, reply_parameters=True ) with pytest.raises(ValueError, match="`allow_sending_without_reply` and"): - await bot.send_media_group( + await offline_bot.send_media_group( chat_id, media, allow_sending_without_reply=True, reply_parameters=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): + # Here we only test the behaviour for offline_bot apis in local mode + async def test_get_file_local_mode(self, offline_bot, monkeypatch): path = str(data_file("game.gif")) async def make_assertion(*args, **kwargs): @@ -1141,14 +1152,14 @@ async def make_assertion(*args, **kwargs): "file_path": path, } - monkeypatch.setattr(bot, "_post", make_assertion) + monkeypatch.setattr(offline_bot, "_post", make_assertion) - resulting_path = (await bot.get_file("file_id")).file_path - assert bot.token not in resulting_path + resulting_path = (await offline_bot.get_file("file_id")).file_path + assert offline_bot.token not in resulting_path assert resulting_path == path # TODO: Needs improvement. No feasible way to test until bots can add members. - async def test_ban_chat_member(self, monkeypatch, bot): + async def test_ban_chat_member(self, monkeypatch, offline_bot): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters chat_id = data["chat_id"] == "2" @@ -1157,13 +1168,13 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): revoke_msgs = data.get("revoke_messages", "true") == "true" return chat_id and user_id and until_date and revoke_msgs - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) until = from_timestamp(1577887200) - 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) + assert await offline_bot.ban_chat_member(2, 32) + assert await offline_bot.ban_chat_member(2, 32, until_date=until) + assert await offline_bot.ban_chat_member(2, 32, until_date=1577887200) + assert await offline_bot.ban_chat_member(2, 32, revoke_messages=True) async def test_ban_chat_member_default_tz(self, monkeypatch, tz_bot): until = dtm.datetime(2020, 1, 11, 16, 13) @@ -1182,7 +1193,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): 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) - async def test_ban_chat_sender_chat(self, monkeypatch, bot): + async def test_ban_chat_sender_chat(self, monkeypatch, offline_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 @@ -1190,12 +1201,12 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): sender_chat_id = data["sender_chat_id"] == 32 return chat_id and sender_chat_id - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.ban_chat_sender_chat(2, 32) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.ban_chat_sender_chat(2, 32) # 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 test_unban_chat_member(self, monkeypatch, offline_bot, only_if_banned): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.parameters chat_id = data["chat_id"] == 2 @@ -1203,21 +1214,21 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): 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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.unban_chat_member(2, 32, only_if_banned=only_if_banned) + assert await offline_bot.unban_chat_member(2, 32, only_if_banned=only_if_banned) - async def test_unban_chat_sender_chat(self, monkeypatch, bot): + async def test_unban_chat_sender_chat(self, monkeypatch, offline_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 - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.unban_chat_sender_chat(2, 32) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.unban_chat_sender_chat(2, 32) - async def test_set_chat_permissions(self, monkeypatch, bot, chat_permissions): + async def test_set_chat_permissions(self, monkeypatch, offline_bot, chat_permissions): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters chat_id = data["chat_id"] == "2" @@ -1225,11 +1236,11 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): use_independent_chat_permissions = data["use_independent_chat_permissions"] return chat_id and permissions and use_independent_chat_permissions - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.set_chat_permissions(2, chat_permissions, True) + assert await offline_bot.set_chat_permissions(2, chat_permissions, True) - async def test_set_chat_administrator_custom_title(self, monkeypatch, bot): + async def test_set_chat_administrator_custom_title(self, monkeypatch, offline_bot): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.parameters chat_id = data["chat_id"] == 2 @@ -1237,11 +1248,11 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): custom_title = data["custom_title"] == "custom_title" return chat_id and user_id and custom_title - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.set_chat_administrator_custom_title(2, 32, "custom_title") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.set_chat_administrator_custom_title(2, 32, "custom_title") # TODO: Needs improvement. Need an incoming callbackquery to test - async def test_answer_callback_query(self, monkeypatch, bot): + async def test_answer_callback_query(self, monkeypatch, offline_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 == { @@ -1252,27 +1263,27 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): "text": "answer", } - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.answer_callback_query( + assert await offline_bot.answer_callback_query( 23, text="answer", show_alert=True, url="no_url", cache_time=1 ) @pytest.mark.parametrize("drop_pending_updates", [True, False]) async def test_set_webhook_delete_webhook_drop_pending_updates( - self, bot, drop_pending_updates, monkeypatch + self, offline_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) + monkeypatch.setattr(offline_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) + assert await offline_bot.set_webhook("", drop_pending_updates=drop_pending_updates) + assert await offline_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): + async def test_set_webhook_params(self, offline_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/ @@ -1297,7 +1308,7 @@ async def make_assertion(*args, **_): and kwargs["secret_token"] == "SoSecretToken" ) - monkeypatch.setattr(bot, "_post", make_assertion) + monkeypatch.setattr(offline_bot, "_post", make_assertion) cert_path = data_file("sslcert.pem") if local_file == "str": @@ -1307,7 +1318,7 @@ async def make_assertion(*args, **_): else: certificate = cert_path.read_bytes() - assert await bot.set_webhook( + assert await offline_bot.set_webhook( "example.com", certificate, 7, @@ -1318,7 +1329,7 @@ async def make_assertion(*args, **_): ) # TODO: Needs improvement. Need incoming shipping queries to test - async def test_answer_shipping_query_ok(self, monkeypatch, bot): + async def test_answer_shipping_query_ok(self, monkeypatch, offline_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 == { @@ -1329,11 +1340,13 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ], } - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_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]) + assert await offline_bot.answer_shipping_query( + 1, True, shipping_options=[shipping_options] + ) - async def test_answer_shipping_query_error_message(self, monkeypatch, bot): + async def test_answer_shipping_query_error_message(self, monkeypatch, offline_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 == { @@ -1342,19 +1355,19 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): "ok": False, } - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.answer_shipping_query(1, False, error_message="Not enough fish") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_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): + async def test_answer_pre_checkout_query_ok(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.answer_pre_checkout_query(1, True) - async def test_answer_pre_checkout_query_error_message(self, monkeypatch, bot): + async def test_answer_pre_checkout_query_error_message(self, monkeypatch, offline_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 == { @@ -1363,10 +1376,12 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): "ok": False, } - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.answer_pre_checkout_query(1, False, error_message="Not enough fish") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.answer_pre_checkout_query( + 1, False, error_message="Not enough fish" + ) - async def test_restrict_chat_member(self, bot, chat_permissions, monkeypatch): + async def test_restrict_chat_member(self, offline_bot, chat_permissions, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters chat_id = data["chat_id"] == "@chat" @@ -1382,9 +1397,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): and use_independent_chat_permissions ) - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.restrict_chat_member("@chat", 2, chat_permissions, 200, True) + assert await offline_bot.restrict_chat_member("@chat", 2, chat_permissions, 200, True) async def test_restrict_chat_member_default_tz( self, monkeypatch, tz_bot, channel_id, chat_permissions @@ -1406,10 +1421,10 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): ) @pytest.mark.parametrize("local_mode", [True, False]) - async def test_set_chat_photo_local_files(self, monkeypatch, bot, chat_id, local_mode): + async def test_set_chat_photo_local_files(self, monkeypatch, offline_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 + offline_bot._local_mode = local_mode + # For just test that the correct paths are passed as we have no local Bot API set up self.test_flag = False file = data_file("telegram.jpg") expected = file.as_uri() @@ -1420,13 +1435,13 @@ async def make_assertion(_, data, *args, **kwargs): else: self.test_flag = isinstance(data.get("photo"), InputFile) - monkeypatch.setattr(bot, "_post", make_assertion) - await bot.set_chat_photo(chat_id, file) + monkeypatch.setattr(offline_bot, "_post", make_assertion) + await offline_bot.set_chat_photo(chat_id, file) assert self.test_flag finally: - bot._local_mode = False + offline_bot._local_mode = False - async def test_timeout_propagation_explicit(self, monkeypatch, bot, chat_id): + async def test_timeout_propagation_explicit(self, monkeypatch, offline_bot, chat_id): # Use BaseException that's not a subclass of Exception such that # OkException should not be caught anywhere class OkException(BaseException): @@ -1441,19 +1456,19 @@ async def do_request(*args, **kwargs): return 200, b'{"ok": true, "result": []}' - monkeypatch.setattr(bot.request, "do_request", do_request) + monkeypatch.setattr(offline_bot.request, "do_request", do_request) # Test file uploading with pytest.raises(OkException): - await bot.send_photo( + await offline_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) + await offline_bot.get_chat_administrators(chat_id, read_timeout=timeout) - async def test_timeout_propagation_implicit(self, monkeypatch, bot, chat_id): + async def test_timeout_propagation_implicit(self, monkeypatch, offline_bot, chat_id): # Use BaseException that's not a subclass of Exception such that # OkException should not be caught anywhere class OkException(BaseException): @@ -1467,33 +1482,34 @@ async def request(*args, **kwargs): return 200, b'{"ok": true, "result": []}' monkeypatch.setattr(httpx.AsyncClient, "request", request) + monkeypatch.setattr(offline_bot, "_request", (object(), HTTPXRequest())) # Test file uploading with pytest.raises(OkException): - await bot.send_photo(chat_id, data_file("telegram.jpg").open("rb")) + await offline_bot.send_photo(chat_id, data_file("telegram.jpg").open("rb")) - async def test_log_out(self, monkeypatch, bot): + async def test_log_out(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", assertion) - assert await bot.log_out() + assert await offline_bot.log_out() - async def test_close(self, monkeypatch, bot): + async def test_close(self, monkeypatch, offline_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) + monkeypatch.setattr(offline_bot.request, "post", assertion) - assert await bot.close() + assert await offline_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 + self, monkeypatch, offline_bot, chat_id, media_message, json_keyboard, caption ): keyboard = InlineKeyboardMarkup( [[InlineKeyboardButton(text="test", callback_data="test2")]] @@ -1525,8 +1541,8 @@ async def post(url, request_data: RequestData, *args, **kwargs): pytest.fail("I got wrong parameters in post") return data - monkeypatch.setattr(bot.request, "post", post) - await bot.copy_message( + monkeypatch.setattr(offline_bot.request, "post", post) + await offline_bot.copy_message( chat_id, from_chat_id=chat_id, message_id=media_message.message_id, @@ -1557,7 +1573,7 @@ async def test_callback_data_maxsize(self, bot_info, acd_in, maxsize): 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 + offline_bot = cdc_bot async def post(*args, **kwargs): update = Update( @@ -1577,14 +1593,14 @@ async def post(*args, **kwargs): try: monkeypatch.setattr(BaseRequest, "post", post) - updates = await bot.get_updates(timeout=1) + updates = await offline_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() + offline_bot.callback_data_cache.clear_callback_data() + offline_bot.callback_data_cache.clear_callback_queries() @pytest.mark.parametrize( "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] @@ -1592,7 +1608,7 @@ async def post(*args, **kwargs): async def test_arbitrary_callback_data_pinned_message_reply_to_message( self, cdc_bot, monkeypatch, message_type ): - bot = cdc_bot + offline_bot = cdc_bot reply_markup = InlineKeyboardMarkup.from_button( InlineKeyboardButton(text="text", callback_data="callback_data") @@ -1602,11 +1618,11 @@ async def test_arbitrary_callback_data_pinned_message_reply_to_message( 1, dtm.datetime.utcnow(), None, - reply_markup=bot.callback_data_cache.process_keyboard(reply_markup), + reply_markup=offline_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) + message.pinned_message = Message.de_json(message.to_dict(), offline_bot) async def post(*args, **kwargs): update = Update( @@ -1617,7 +1633,7 @@ async def post(*args, **kwargs): dtm.datetime.utcnow(), None, pinned_message=message, - reply_to_message=Message.de_json(message.to_dict(), bot), + reply_to_message=Message.de_json(message.to_dict(), offline_bot), ) }, ) @@ -1625,7 +1641,7 @@ async def post(*args, **kwargs): try: monkeypatch.setattr(BaseRequest, "post", post) - updates = await bot.get_updates(timeout=1) + updates = await offline_bot.get_updates(timeout=1) assert isinstance(updates, tuple) assert len(updates) == 1 @@ -1646,11 +1662,11 @@ async def post(*args, **kwargs): ) finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() + offline_bot.callback_data_cache.clear_callback_data() + offline_bot.callback_data_cache.clear_callback_queries() async def test_get_updates_invalid_callback_data(self, cdc_bot, monkeypatch): - bot = cdc_bot + offline_bot = cdc_bot async def post(*args, **kwargs): return [ @@ -1674,7 +1690,7 @@ async def post(*args, **kwargs): try: monkeypatch.setattr(BaseRequest, "post", post) - updates = await bot.get_updates(timeout=1) + updates = await offline_bot.get_updates(timeout=1) assert isinstance(updates, tuple) assert len(updates) == 1 @@ -1682,12 +1698,12 @@ async def post(*args, **kwargs): finally: # Reset b/c bots scope is session - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() + offline_bot.callback_data_cache.clear_callback_data() + offline_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 + offline_bot = cdc_bot # For now just test that our internals pass the correct data async def make_assertion( @@ -1704,7 +1720,7 @@ async def make_assertion( inline_keyboard[0][0].callback_data[32:], ) assertion_3 = ( - bot.callback_data_cache._keyboard_data[keyboard].button_data[button] + offline_bot.callback_data_cache._keyboard_data[keyboard].button_data[button] == "replace_test" ) assertion_4 = data["results"][1].reply_markup is None @@ -1722,8 +1738,9 @@ async def make_assertion( ] ) - bot.username # call this here so `bot.get_me()` won't be called after mocking - monkeypatch.setattr(bot, "_post", make_assertion) + # call this here so `offline_bot.get_me()` won't be called after mocking + offline_bot.username + monkeypatch.setattr(offline_bot, "_post", make_assertion) results = [ InlineQueryResultArticle( "11", "first", InputTextMessageContent("first"), reply_markup=reply_markup @@ -1735,11 +1752,11 @@ async def make_assertion( ), ] - assert await bot.answer_inline_query(chat_id, results=results) + assert await offline_bot.answer_inline_query(chat_id, results=results) finally: - bot.callback_data_cache.clear_callback_data() - bot.callback_data_cache.clear_callback_queries() + offline_bot.callback_data_cache.clear_callback_data() + offline_bot.callback_data_cache.clear_callback_queries() @pytest.mark.parametrize( "message_type", ["channel_post", "edited_channel_post", "message", "edited_message"] @@ -1813,7 +1830,7 @@ async def test_http2_runtime_error(self, recwarn, bot_class): assert warning.filename == __file__, "wrong stacklevel!" assert warning.category is PTBUserWarning - async def test_set_get_my_name(self, bot, monkeypatch): + async def test_set_get_my_name(self, offline_bot, monkeypatch): """We only test that we pass the correct values to TG since this endpoint is heavily rate limited which makes automated tests rather infeasible.""" default_name = "default_bot_name" @@ -1853,20 +1870,20 @@ async def post(url, request_data: RequestData, *args, **kwargs): get_stack.task_done() return bot_name - monkeypatch.setattr(bot.request, "post", post) + monkeypatch.setattr(offline_bot.request, "post", post) # Set the names assert all( await asyncio.gather( - bot.set_my_name(default_name), - bot.set_my_name(en_name, language_code="en"), - bot.set_my_name(de_name, language_code="de"), + offline_bot.set_my_name(default_name), + offline_bot.set_my_name(en_name, language_code="en"), + offline_bot.set_my_name(de_name, language_code="de"), ) ) # Check that they were set correctly assert await asyncio.gather( - bot.get_my_name(), bot.get_my_name("en"), bot.get_my_name("de") + offline_bot.get_my_name(), offline_bot.get_my_name("en"), offline_bot.get_my_name("de") ) == [ BotName(default_name), BotName(en_name), @@ -1876,18 +1893,18 @@ async def post(url, request_data: RequestData, *args, **kwargs): # Delete the names assert all( await asyncio.gather( - bot.set_my_name(default_name), - bot.set_my_name(None, language_code="en"), - bot.set_my_name(None, language_code="de"), + offline_bot.set_my_name(default_name), + offline_bot.set_my_name(None, language_code="en"), + offline_bot.set_my_name(None, language_code="de"), ) ) # Check that they were deleted correctly assert await asyncio.gather( - bot.get_my_name(), bot.get_my_name("en"), bot.get_my_name("de") + offline_bot.get_my_name(), offline_bot.get_my_name("en"), offline_bot.get_my_name("de") ) == 3 * [BotName(default_name)] - async def test_set_message_reaction(self, bot, monkeypatch): + async def test_set_message_reaction(self, offline_bot, monkeypatch): """This is here so we can test the convenient conversion we do in the function without having to do multiple requests to Telegram""" @@ -1918,14 +1935,22 @@ async def post(url, request_data: RequestData, *args, **kwargs): assert request_data.parameters["reaction"] == expected_param[amount] amount += 1 - monkeypatch.setattr(bot.request, "post", post) - await bot.set_message_reaction(1, 2, [ReactionTypeEmoji(ReactionEmoji.THUMBS_UP)], True) - await bot.set_message_reaction(1, 2, ReactionTypeEmoji(ReactionEmoji.RED_HEART), True) - await bot.set_message_reaction(1, 2, [ReactionTypeCustomEmoji("custom_emoji_1")], True) - await bot.set_message_reaction(1, 2, ReactionTypeCustomEmoji("custom_emoji_2"), True) - await bot.set_message_reaction(1, 2, ReactionEmoji.THUMBS_DOWN, True) - await bot.set_message_reaction(1, 2, "custom_emoji_3", True) - await bot.set_message_reaction( + monkeypatch.setattr(offline_bot.request, "post", post) + await offline_bot.set_message_reaction( + 1, 2, [ReactionTypeEmoji(ReactionEmoji.THUMBS_UP)], True + ) + await offline_bot.set_message_reaction( + 1, 2, ReactionTypeEmoji(ReactionEmoji.RED_HEART), True + ) + await offline_bot.set_message_reaction( + 1, 2, [ReactionTypeCustomEmoji("custom_emoji_1")], True + ) + await offline_bot.set_message_reaction( + 1, 2, ReactionTypeCustomEmoji("custom_emoji_2"), True + ) + await offline_bot.set_message_reaction(1, 2, ReactionEmoji.THUMBS_DOWN, True) + await offline_bot.set_message_reaction(1, 2, "custom_emoji_3", True) + await offline_bot.set_message_reaction( 1, 2, [ @@ -2047,7 +2072,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): reply_parameters=ReplyParameters(**kwargs), ) - async def test_send_poll_question_parse_mode_entities(self, bot, monkeypatch): + async def test_send_poll_question_parse_mode_entities(self, offline_bot, monkeypatch): # Currently only custom emoji are supported as entities which we can't test # We just test that the correct data is passed for now @@ -2059,8 +2084,8 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert request_data.parameters["question_parse_mode"] == ParseMode.MARKDOWN_V2 return make_message("dummy reply").to_dict() - monkeypatch.setattr(bot.request, "post", make_assertion) - await bot.send_poll( + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + await offline_bot.send_poll( 1, question="😀😃", options=["option1", "option2"], @@ -2123,15 +2148,15 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): monkeypatch.setattr(default_bot.request, "post", make_assertion) await default_bot.copy_message(chat_id, 1, 1, reply_parameters=ReplyParameters(**kwargs)) - async def test_do_api_request_camel_case_conversion(self, bot, monkeypatch): + async def test_do_api_request_camel_case_conversion(self, offline_bot, monkeypatch): async def make_assertion(url, request_data: RequestData, *args, **kwargs): return url.endswith("camelCase") - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.do_api_request("camel_case") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.do_api_request("camel_case") @pytest.mark.filterwarnings("ignore::telegram.warnings.PTBUserWarning") - async def test_do_api_request_media_write_timeout(self, bot, chat_id, monkeypatch): + async def test_do_api_request_media_write_timeout(self, offline_bot, chat_id, monkeypatch): test_flag = None class CustomRequest(BaseRequest): @@ -2153,8 +2178,8 @@ async def do_request(self_, *args, **kwargs) -> Tuple[int, bytes]: custom_request = CustomRequest() - bot = Bot(bot.token, request=custom_request) - await bot.do_api_request( + offline_bot = Bot(offline_bot.token, request=custom_request) + await offline_bot.do_api_request( "send_document", api_kwargs={ "chat_id": chat_id, @@ -2194,7 +2219,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): api_kwargs={"chat_id": 2, "user_id": 32, "until_date": until_timestamp}, ) - async def test_business_connection_id_argument(self, bot, monkeypatch): + async def test_business_connection_id_argument(self, offline_bot, monkeypatch): """We can't connect to a business acc, so we just test that the correct data is passed. We also can't test every single method easily, so we just test a few. Our linting will catch any unused args with the others.""" @@ -2203,24 +2228,24 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert request_data.parameters.get("business_connection_id") == 42 return {} - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - await bot.send_message(2, "text", business_connection_id=42) - await bot.stop_poll(chat_id=1, message_id=2, business_connection_id=42) - await bot.pin_chat_message(chat_id=1, message_id=2, business_connection_id=42) - await bot.unpin_chat_message(chat_id=1, business_connection_id=42) + await offline_bot.send_message(2, "text", business_connection_id=42) + await offline_bot.stop_poll(chat_id=1, message_id=2, business_connection_id=42) + await offline_bot.pin_chat_message(chat_id=1, message_id=2, business_connection_id=42) + await offline_bot.unpin_chat_message(chat_id=1, business_connection_id=42) - async def test_message_effect_id_argument(self, bot, monkeypatch): + async def test_message_effect_id_argument(self, offline_bot, monkeypatch): """We can't test every single method easily, so we just test one. Our linting will catch any unused args with the others.""" async def make_assertion(url, request_data: RequestData, *args, **kwargs): return request_data.parameters.get("message_effect_id") == 42 - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.send_message(2, "text", message_effect_id=42) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.send_message(2, "text", message_effect_id=42) - async def test_get_business_connection(self, bot, monkeypatch): + async def test_get_business_connection(self, offline_bot, monkeypatch): bci = "42" user = User(1, "first", False) user_chat_id = 1 @@ -2236,11 +2261,11 @@ async def do_request(*args, **kwargs): return 200, f'{{"ok": true, "result": {bc}}}'.encode() return 400, b'{"ok": false, "result": []}' - monkeypatch.setattr(bot.request, "do_request", do_request) - obj = await bot.get_business_connection(business_connection_id=bci) + monkeypatch.setattr(offline_bot.request, "do_request", do_request) + obj = await offline_bot.get_business_connection(business_connection_id=bci) assert isinstance(obj, BusinessConnection) - async def test_refund_star_payment(self, bot, monkeypatch): + async def test_refund_star_payment(self, offline_bot, monkeypatch): # can't make actual request so we just test that the correct data is passed async def make_assertion(url, request_data: RequestData, *args, **kwargs): return ( @@ -2248,10 +2273,10 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): and request_data.parameters.get("telegram_payment_charge_id") == "37" ) - monkeypatch.setattr(bot.request, "post", make_assertion) - assert await bot.refund_star_payment(42, "37") + monkeypatch.setattr(offline_bot.request, "post", make_assertion) + assert await offline_bot.refund_star_payment(42, "37") - async def test_get_star_transactions(self, bot, monkeypatch): + async def test_get_star_transactions(self, offline_bot, monkeypatch): # we just want to test the offset parameter st = StarTransactions([StarTransaction("1", 1, dtm.datetime.now())]).to_json() @@ -2261,14 +2286,14 @@ async def do_request(url, request_data: RequestData, *args, **kwargs): return 200, f'{{"ok": true, "result": {st}}}'.encode() return 400, b'{"ok": false, "result": []}' - monkeypatch.setattr(bot.request, "do_request", do_request) - obj = await bot.get_star_transactions(offset=3) + monkeypatch.setattr(offline_bot.request, "do_request", do_request) + obj = await offline_bot.get_star_transactions(offset=3) assert isinstance(obj, StarTransactions) async def test_create_chat_subscription_invite_link( self, monkeypatch, - bot, + offline_bot, ): # Since the chat invite link object does not say if the sub args are passed we can # only check here @@ -2276,9 +2301,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): assert request_data.parameters.get("subscription_period") == 2592000 assert request_data.parameters.get("subscription_price") == 6 - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - await bot.create_chat_subscription_invite_link(1234, 2592000, 6) + await offline_bot.create_chat_subscription_invite_link(1234, 2592000, 6) class TestBotWithRequest: diff --git a/tests/test_botcommand.py b/tests/test_botcommand.py index 1e4a360e065..f38abb320ab 100644 --- a/tests/test_botcommand.py +++ b/tests/test_botcommand.py @@ -37,15 +37,15 @@ def test_slot_behaviour(self, bot_command): assert getattr(bot_command, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(bot_command)) == len(set(mro_slots(bot_command))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = {"command": self.command, "description": self.description} - bot_command = BotCommand.de_json(json_dict, bot) + bot_command = BotCommand.de_json(json_dict, offline_bot) assert bot_command.api_kwargs == {} assert bot_command.command == self.command assert bot_command.description == self.description - assert BotCommand.de_json(None, bot) is None + assert BotCommand.de_json(None, offline_bot) is None def test_to_dict(self, bot_command): bot_command_dict = bot_command.to_dict() diff --git a/tests/test_botcommandscope.py b/tests/test_botcommandscope.py index 63766b95e17..a4bddfc8f69 100644 --- a/tests/test_botcommandscope.py +++ b/tests/test_botcommandscope.py @@ -125,14 +125,14 @@ def test_slot_behaviour(self, bot_command_scope): set(mro_slots(bot_command_scope)) ), "duplicate slot" - def test_de_json(self, bot, scope_class_and_type, chat_id): + def test_de_json(self, offline_bot, scope_class_and_type, chat_id): cls = scope_class_and_type[0] type_ = scope_class_and_type[1] - assert cls.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None json_dict = {"type": type_, "chat_id": chat_id, "user_id": 42} - bot_command_scope = BotCommandScope.de_json(json_dict, bot) + bot_command_scope = BotCommandScope.de_json(json_dict, offline_bot) assert set(bot_command_scope.api_kwargs.keys()) == {"chat_id", "user_id"} - set( cls.__slots__ ) @@ -145,18 +145,18 @@ def test_de_json(self, bot, scope_class_and_type, chat_id): if "user_id" in cls.__slots__: assert bot_command_scope.user_id == 42 - def test_de_json_invalid_type(self, bot): + def test_de_json_invalid_type(self, offline_bot): json_dict = {"type": "invalid", "chat_id": chat_id, "user_id": 42} - bot_command_scope = BotCommandScope.de_json(json_dict, bot) + bot_command_scope = BotCommandScope.de_json(json_dict, offline_bot) assert type(bot_command_scope) is BotCommandScope assert bot_command_scope.type == "invalid" - def test_de_json_subclass(self, scope_class, bot, chat_id): + def test_de_json_subclass(self, scope_class, offline_bot, chat_id): """This makes sure that e.g. BotCommandScopeDefault(data) never returns a BotCommandScopeChat instance.""" json_dict = {"type": "invalid", "chat_id": chat_id, "user_id": 42} - assert type(scope_class.de_json(json_dict, bot)) is scope_class + assert type(scope_class.de_json(json_dict, offline_bot)) is scope_class def test_to_dict(self, bot_command_scope): bot_command_scope_dict = bot_command_scope.to_dict() @@ -172,7 +172,7 @@ def test_type_enum_conversion(self): assert type(BotCommandScope("default").type) is BotCommandScopeType assert BotCommandScope("unknown").type == "unknown" - def test_equality(self, bot_command_scope, bot): + def test_equality(self, bot_command_scope, offline_bot): a = BotCommandScope("base_type") b = BotCommandScope("base_type") c = bot_command_scope @@ -200,7 +200,7 @@ def test_equality(self, bot_command_scope, bot): if hasattr(c, "chat_id"): json_dict = c.to_dict() json_dict["chat_id"] = 0 - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) @@ -208,7 +208,7 @@ def test_equality(self, bot_command_scope, bot): if hasattr(c, "user_id"): json_dict = c.to_dict() json_dict["user_id"] = 0 - g = c.__class__.de_json(json_dict, bot) + g = c.__class__.de_json(json_dict, offline_bot) assert c != g assert hash(c) != hash(g) diff --git a/tests/test_business.py b/tests/test_business.py index 735f2e7177a..e3da3694804 100644 --- a/tests/test_business.py +++ b/tests/test_business.py @@ -139,7 +139,7 @@ def test_de_json(self): assert bc.api_kwargs == {} assert isinstance(bc, BusinessConnection) - def test_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "id": self.id_, "user": self.user.to_dict(), @@ -148,7 +148,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): "can_reply": self.can_reply, "is_enabled": self.is_enabled, } - chat_bot = BusinessConnection.de_json(json_dict, bot) + chat_bot = BusinessConnection.de_json(json_dict, offline_bot) chat_bot_raw = BusinessConnection.de_json(json_dict, raw_bot) chat_bot_tz = BusinessConnection.de_json(json_dict, tz_bot) diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py index 3131b34f249..7a53651a3fa 100644 --- a/tests/test_callbackquery.py +++ b/tests/test_callbackquery.py @@ -94,7 +94,7 @@ def test_slot_behaviour(self, callback_query): assert getattr(callback_query, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(callback_query)) == len(set(mro_slots(callback_query))), "same slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "from": self.from_user.to_dict(), @@ -104,7 +104,7 @@ def test_de_json(self, bot): "inline_message_id": self.inline_message_id, "game_short_name": self.game_short_name, } - callback_query = CallbackQuery.de_json(json_dict, bot) + callback_query = CallbackQuery.de_json(json_dict, offline_bot) assert callback_query.api_kwargs == {} assert callback_query.id == self.id_ diff --git a/tests/test_chat.py b/tests/test_chat.py index a3dcd6aa17f..adf2c42bc3c 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -63,7 +63,7 @@ def test_slot_behaviour(self, chat): assert getattr(chat, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(chat)) == len(set(mro_slots(chat))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "title": self.title, @@ -73,7 +73,7 @@ def test_de_json(self, bot): "first_name": self.first_name, "last_name": self.last_name, } - chat = Chat.de_json(json_dict, bot) + chat = Chat.de_json(json_dict, offline_bot) assert chat.id == self.id_ assert chat.title == self.title diff --git a/tests/test_chatadministratorrights.py b/tests/test_chatadministratorrights.py index e630693c2d7..e15de43c730 100644 --- a/tests/test_chatadministratorrights.py +++ b/tests/test_chatadministratorrights.py @@ -50,7 +50,7 @@ def test_slot_behaviour(self, chat_admin_rights): 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, chat_admin_rights): + def test_de_json(self, offline_bot, chat_admin_rights): json_dict = { "can_change_info": True, "can_delete_messages": True, @@ -68,7 +68,7 @@ def test_de_json(self, bot, chat_admin_rights): "can_edit_stories": True, "can_delete_stories": True, } - chat_administrator_rights_de = ChatAdministratorRights.de_json(json_dict, bot) + chat_administrator_rights_de = ChatAdministratorRights.de_json(json_dict, offline_bot) assert chat_administrator_rights_de.api_kwargs == {} assert chat_admin_rights == chat_administrator_rights_de diff --git a/tests/test_chatbackground.py b/tests/test_chatbackground.py index 900fc58709f..ccf90d41147 100644 --- a/tests/test_chatbackground.py +++ b/tests/test_chatbackground.py @@ -168,12 +168,12 @@ def test_slot_behaviour(self, background_type): 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_required_args(self, bot, background_type): + def test_de_json_required_args(self, offline_bot, background_type): cls = background_type.__class__ - assert cls.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None json_dict = make_json_dict(background_type) - const_background_type = BackgroundType.de_json(json_dict, bot) + const_background_type = BackgroundType.de_json(json_dict, offline_bot) assert const_background_type.api_kwargs == {} assert isinstance(const_background_type, BackgroundType) @@ -181,9 +181,9 @@ def test_de_json_required_args(self, bot, background_type): for bg_type_at, const_bg_type_at in iter_args(background_type, const_background_type): assert bg_type_at == const_bg_type_at - def test_de_json_all_args(self, bot, background_type): + def test_de_json_all_args(self, offline_bot, background_type): json_dict = make_json_dict(background_type, include_optional_args=True) - const_background_type = BackgroundType.de_json(json_dict, bot) + const_background_type = BackgroundType.de_json(json_dict, offline_bot) assert const_background_type.api_kwargs == {} @@ -194,19 +194,19 @@ def test_de_json_all_args(self, bot, background_type): ): assert bg_type_at == const_bg_type_at - def test_de_json_invalid_type(self, background_type, bot): + def test_de_json_invalid_type(self, background_type, offline_bot): json_dict = {"type": "invalid", "theme_name": BTDefaults.theme_name} - background_type = BackgroundType.de_json(json_dict, bot) + background_type = BackgroundType.de_json(json_dict, offline_bot) assert type(background_type) is BackgroundType assert background_type.type == "invalid" - def test_de_json_subclass(self, background_type, bot, chat_id): - """This makes sure that e.g. BackgroundTypeFill(data, bot) never returns a + def test_de_json_subclass(self, background_type, offline_bot, chat_id): + """This makes sure that e.g. BackgroundTypeFill(data, offline_bot) never returns a BackgroundTypeWallpaper instance.""" cls = background_type.__class__ json_dict = make_json_dict(background_type, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, background_type): bg_type_dict = background_type.to_dict() @@ -275,12 +275,12 @@ def test_slot_behaviour(self, background_fill): 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_required_args(self, bot, background_fill): + def test_de_json_required_args(self, offline_bot, background_fill): cls = background_fill.__class__ - assert cls.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None json_dict = make_json_dict(background_fill) - const_background_fill = BackgroundFill.de_json(json_dict, bot) + const_background_fill = BackgroundFill.de_json(json_dict, offline_bot) assert const_background_fill.api_kwargs == {} assert isinstance(const_background_fill, BackgroundFill) @@ -288,9 +288,9 @@ def test_de_json_required_args(self, bot, background_fill): for bg_fill_at, const_bg_fill_at in iter_args(background_fill, const_background_fill): assert bg_fill_at == const_bg_fill_at - def test_de_json_all_args(self, bot, background_fill): + def test_de_json_all_args(self, offline_bot, background_fill): json_dict = make_json_dict(background_fill, include_optional_args=True) - const_background_fill = BackgroundFill.de_json(json_dict, bot) + const_background_fill = BackgroundFill.de_json(json_dict, offline_bot) assert const_background_fill.api_kwargs == {} @@ -301,19 +301,19 @@ def test_de_json_all_args(self, bot, background_fill): ): assert bg_fill_at == const_bg_fill_at - def test_de_json_invalid_type(self, background_fill, bot): + def test_de_json_invalid_type(self, background_fill, offline_bot): json_dict = {"type": "invalid", "theme_name": BTDefaults.theme_name} - background_fill = BackgroundFill.de_json(json_dict, bot) + background_fill = BackgroundFill.de_json(json_dict, offline_bot) assert type(background_fill) is BackgroundFill assert background_fill.type == "invalid" - def test_de_json_subclass(self, background_fill, bot): - """This makes sure that e.g. BackgroundFillSolid(data, bot) never returns a + def test_de_json_subclass(self, background_fill, offline_bot): + """This makes sure that e.g. BackgroundFillSolid(data, offline_bot) never returns a BackgroundFillGradient instance.""" cls = background_fill.__class__ json_dict = make_json_dict(background_fill, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, background_fill): bg_fill_dict = background_fill.to_dict() diff --git a/tests/test_chatboost.py b/tests/test_chatboost.py index f0ef143618a..62123df73dc 100644 --- a/tests/test_chatboost.py +++ b/tests/test_chatboost.py @@ -170,13 +170,13 @@ def test_slot_behaviour(self, chat_boost_source): 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_required_args(self, bot, chat_boost_source): + def test_de_json_required_args(self, offline_bot, chat_boost_source): cls = chat_boost_source.__class__ - assert cls.de_json({}, bot) is None - assert ChatBoost.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None + assert ChatBoost.de_json({}, offline_bot) is None json_dict = make_json_dict(chat_boost_source) - const_boost_source = ChatBoostSource.de_json(json_dict, bot) + const_boost_source = ChatBoostSource.de_json(json_dict, offline_bot) assert const_boost_source.api_kwargs == {} assert isinstance(const_boost_source, ChatBoostSource) @@ -186,9 +186,9 @@ def test_de_json_required_args(self, bot, chat_boost_source): ): assert chat_mem_type_at == const_chat_mem_at - def test_de_json_all_args(self, bot, chat_boost_source): + def test_de_json_all_args(self, offline_bot, chat_boost_source): json_dict = make_json_dict(chat_boost_source, include_optional_args=True) - const_boost_source = ChatBoostSource.de_json(json_dict, bot) + const_boost_source = ChatBoostSource.de_json(json_dict, offline_bot) assert const_boost_source.api_kwargs == {} assert isinstance(const_boost_source, ChatBoostSource) @@ -198,19 +198,19 @@ def test_de_json_all_args(self, bot, chat_boost_source): ): assert c_mem_type_at == const_c_mem_at - def test_de_json_invalid_source(self, chat_boost_source, bot): + def test_de_json_invalid_source(self, chat_boost_source, offline_bot): json_dict = {"source": "invalid"} - chat_boost_source = ChatBoostSource.de_json(json_dict, bot) + chat_boost_source = ChatBoostSource.de_json(json_dict, offline_bot) assert type(chat_boost_source) is ChatBoostSource assert chat_boost_source.source == "invalid" - def test_de_json_subclass(self, chat_boost_source, bot): - """This makes sure that e.g. ChatBoostSourcePremium(data, bot) never returns a + def test_de_json_subclass(self, chat_boost_source, offline_bot): + """This makes sure that e.g. ChatBoostSourcePremium(data, offline_bot) never returns a ChatBoostSourceGiftCode instance.""" cls = chat_boost_source.__class__ json_dict = make_json_dict(chat_boost_source, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, chat_boost_source): chat_boost_dict = chat_boost_source.to_dict() @@ -263,14 +263,14 @@ def test_slot_behaviour(self, chat_boost): 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, chat_boost): + def test_de_json(self, offline_bot, chat_boost): json_dict = { "boost_id": "2", "add_date": self.date, "expiration_date": self.date, "source": self.default_source.to_dict(), } - cb = ChatBoost.de_json(json_dict, bot) + cb = ChatBoost.de_json(json_dict, offline_bot) assert isinstance(cb, ChatBoost) assert isinstance(cb.add_date, datetime.datetime) @@ -284,7 +284,7 @@ def test_de_json(self, bot, chat_boost): for slot in cb.__slots__: assert getattr(cb, slot) == getattr(chat_boost, slot), f"attribute {slot} differs" - def test_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "boost_id": "2", "add_date": self.date, @@ -292,7 +292,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): "source": self.default_source.to_dict(), } - cb_bot = ChatBoost.de_json(json_dict, bot) + cb_bot = ChatBoost.de_json(json_dict, offline_bot) cb_raw = ChatBoost.de_json(json_dict, raw_bot) cb_tz = ChatBoost.de_json(json_dict, tz_bot) @@ -347,7 +347,7 @@ def test_slot_behaviour(self, chat_boost_updated): 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, chat_boost): + def test_de_json(self, offline_bot, chat_boost): json_dict = { "chat": self.chat.to_dict(), "boost": { @@ -357,7 +357,7 @@ def test_de_json(self, bot, chat_boost): "source": self.default_source.to_dict(), }, } - cbu = ChatBoostUpdated.de_json(json_dict, bot) + cbu = ChatBoostUpdated.de_json(json_dict, offline_bot) assert isinstance(cbu, ChatBoostUpdated) assert cbu.chat == self.chat @@ -420,14 +420,14 @@ def test_slot_behaviour(self, chat_boost_removed): 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, chat_boost_removed): + def test_de_json(self, offline_bot, chat_boost_removed): json_dict = { "chat": self.chat.to_dict(), "boost_id": "2", "remove_date": self.date, "source": self.default_source.to_dict(), } - cbr = ChatBoostRemoved.de_json(json_dict, bot) + cbr = ChatBoostRemoved.de_json(json_dict, offline_bot) assert isinstance(cbr, ChatBoostRemoved) assert cbr.chat == self.chat @@ -435,7 +435,7 @@ def test_de_json(self, bot, chat_boost_removed): assert to_timestamp(cbr.remove_date) == self.date assert cbr.source == self.default_source - def test_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "chat": self.chat.to_dict(), "boost_id": "2", @@ -443,7 +443,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): "source": self.default_source.to_dict(), } - cbr_bot = ChatBoostRemoved.de_json(json_dict, bot) + cbr_bot = ChatBoostRemoved.de_json(json_dict, offline_bot) cbr_raw = ChatBoostRemoved.de_json(json_dict, raw_bot) cbr_tz = ChatBoostRemoved.de_json(json_dict, tz_bot) @@ -498,7 +498,7 @@ def test_slot_behaviour(self, user_chat_boosts): 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, user_chat_boosts): + def test_de_json(self, offline_bot, user_chat_boosts): json_dict = { "boosts": [ { @@ -509,7 +509,7 @@ def test_de_json(self, bot, user_chat_boosts): } ] } - ucb = UserChatBoosts.de_json(json_dict, bot) + ucb = UserChatBoosts.de_json(json_dict, offline_bot) assert isinstance(ucb, UserChatBoosts) assert isinstance(ucb.boosts[0], ChatBoost) @@ -525,7 +525,7 @@ def test_to_dict(self, user_chat_boosts): assert isinstance(user_chat_boosts_dict["boosts"], list) assert user_chat_boosts_dict["boosts"][0] == user_chat_boosts.boosts[0].to_dict() - async def test_get_user_chat_boosts(self, monkeypatch, bot): + async def test_get_user_chat_boosts(self, monkeypatch, offline_bot): async def make_assertion(url, request_data: RequestData, *args, **kwargs): data = request_data.json_parameters chat_id = data["chat_id"] == "3" @@ -534,9 +534,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs): pytest.fail("I got wrong parameters in post") return data - monkeypatch.setattr(bot.request, "post", make_assertion) + monkeypatch.setattr(offline_bot.request, "post", make_assertion) - assert await bot.get_user_chat_boosts("3", 2) + assert await offline_bot.get_user_chat_boosts("3", 2) class TestUserChatBoostsWithRequest(ChatBoostDefaults): diff --git a/tests/test_chatfullinfo.py b/tests/test_chatfullinfo.py index 7e5bc90baae..6c105493021 100644 --- a/tests/test_chatfullinfo.py +++ b/tests/test_chatfullinfo.py @@ -150,7 +150,7 @@ def test_slot_behaviour(self, chat_full_info): assert len(mro_slots(cfi)) == len(set(mro_slots(cfi))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "title": self.title, @@ -194,7 +194,7 @@ def test_de_json(self, bot): "last_name": self.last_name, "can_send_paid_media": self.can_send_paid_media, } - cfi = ChatFullInfo.de_json(json_dict, bot) + cfi = ChatFullInfo.de_json(json_dict, offline_bot) assert cfi.id == self.id_ assert cfi.title == self.title assert cfi.type == self.type_ @@ -239,7 +239,7 @@ def test_de_json(self, bot): assert cfi.max_reaction_count == self.max_reaction_count assert cfi.can_send_paid_media == self.can_send_paid_media - def test_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "id": self.id_, "type": self.type_, @@ -247,7 +247,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): "max_reaction_count": self.max_reaction_count, "emoji_status_expiration_date": to_timestamp(self.emoji_status_expiration_date), } - cfi_bot = ChatFullInfo.de_json(json_dict, bot) + cfi_bot = ChatFullInfo.de_json(json_dict, offline_bot) cfi_bot_raw = ChatFullInfo.de_json(json_dict, raw_bot) cfi_bot_tz = ChatFullInfo.de_json(json_dict, tz_bot) diff --git a/tests/test_chatinvitelink.py b/tests/test_chatinvitelink.py index 9331166b466..86ca7afd3ae 100644 --- a/tests/test_chatinvitelink.py +++ b/tests/test_chatinvitelink.py @@ -66,7 +66,7 @@ def test_slot_behaviour(self, invite_link): assert getattr(invite_link, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(invite_link)) == len(set(mro_slots(invite_link))), "duplicate slot" - def test_de_json_required_args(self, bot, creator): + def test_de_json_required_args(self, offline_bot, creator): json_dict = { "invite_link": self.link, "creator": creator.to_dict(), @@ -75,7 +75,7 @@ def test_de_json_required_args(self, bot, creator): "is_revoked": self.revoked, } - invite_link = ChatInviteLink.de_json(json_dict, bot) + invite_link = ChatInviteLink.de_json(json_dict, offline_bot) assert invite_link.api_kwargs == {} assert invite_link.invite_link == self.link @@ -84,7 +84,7 @@ def test_de_json_required_args(self, bot, creator): assert invite_link.is_primary == self.primary assert invite_link.is_revoked == self.revoked - def test_de_json_all_args(self, bot, creator): + def test_de_json_all_args(self, offline_bot, creator): json_dict = { "invite_link": self.link, "creator": creator.to_dict(), @@ -99,7 +99,7 @@ def test_de_json_all_args(self, bot, creator): "subscription_price": self.subscription_price, } - invite_link = ChatInviteLink.de_json(json_dict, bot) + invite_link = ChatInviteLink.de_json(json_dict, offline_bot) assert invite_link.api_kwargs == {} assert invite_link.invite_link == self.link @@ -115,7 +115,7 @@ def test_de_json_all_args(self, bot, creator): assert invite_link.subscription_period == self.subscription_period assert invite_link.subscription_price == self.subscription_price - def test_de_json_localization(self, tz_bot, bot, raw_bot, creator): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot, creator): json_dict = { "invite_link": self.link, "creator": creator.to_dict(), @@ -129,7 +129,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot, creator): } invite_link_raw = ChatInviteLink.de_json(json_dict, raw_bot) - invite_link_bot = ChatInviteLink.de_json(json_dict, bot) + invite_link_bot = ChatInviteLink.de_json(json_dict, offline_bot) invite_link_tz = ChatInviteLink.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable diff --git a/tests/test_chatjoinrequest.py b/tests/test_chatjoinrequest.py index cdf2787e8ea..cf0550c3006 100644 --- a/tests/test_chatjoinrequest.py +++ b/tests/test_chatjoinrequest.py @@ -70,14 +70,14 @@ def test_slot_behaviour(self, chat_join_request): 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, time): + def test_de_json(self, offline_bot, time): json_dict = { "chat": self.chat.to_dict(), "from": self.from_user.to_dict(), "date": to_timestamp(time), "user_chat_id": self.from_user.id, } - chat_join_request = ChatJoinRequest.de_json(json_dict, bot) + chat_join_request = ChatJoinRequest.de_json(json_dict, offline_bot) assert chat_join_request.api_kwargs == {} assert chat_join_request.chat == self.chat @@ -87,7 +87,7 @@ def test_de_json(self, bot, time): assert chat_join_request.user_chat_id == self.from_user.id json_dict.update({"bio": self.bio, "invite_link": self.invite_link.to_dict()}) - chat_join_request = ChatJoinRequest.de_json(json_dict, bot) + chat_join_request = ChatJoinRequest.de_json(json_dict, offline_bot) assert chat_join_request.api_kwargs == {} assert chat_join_request.chat == self.chat @@ -98,7 +98,7 @@ def test_de_json(self, bot, time): assert chat_join_request.bio == self.bio assert chat_join_request.invite_link == self.invite_link - def test_de_json_localization(self, tz_bot, bot, raw_bot, time): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot, time): json_dict = { "chat": self.chat.to_dict(), "from": self.from_user.to_dict(), @@ -107,7 +107,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot, time): } chatjoin_req_raw = ChatJoinRequest.de_json(json_dict, raw_bot) - chatjoin_req_bot = ChatJoinRequest.de_json(json_dict, bot) + chatjoin_req_bot = ChatJoinRequest.de_json(json_dict, offline_bot) chatjoin_req_tz = ChatJoinRequest.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable diff --git a/tests/test_chatlocation.py b/tests/test_chatlocation.py index 00481d644d5..b83306308be 100644 --- a/tests/test_chatlocation.py +++ b/tests/test_chatlocation.py @@ -40,12 +40,12 @@ def test_slot_behaviour(self, chat_location): 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): + def test_de_json(self, offline_bot): json_dict = { "location": self.location.to_dict(), "address": self.address, } - chat_location = ChatLocation.de_json(json_dict, bot) + chat_location = ChatLocation.de_json(json_dict, offline_bot) assert chat_location.api_kwargs == {} assert chat_location.location == self.location diff --git a/tests/test_chatmember.py b/tests/test_chatmember.py index 4296fdd2723..2058d4bdf2a 100644 --- a/tests/test_chatmember.py +++ b/tests/test_chatmember.py @@ -205,12 +205,12 @@ def test_slot_behaviour(self, chat_member_type): 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_required_args(self, bot, chat_member_type): + def test_de_json_required_args(self, offline_bot, chat_member_type): cls = chat_member_type.__class__ - assert cls.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None json_dict = make_json_dict(chat_member_type) - const_chat_member = ChatMember.de_json(json_dict, bot) + const_chat_member = ChatMember.de_json(json_dict, offline_bot) assert const_chat_member.api_kwargs == {} assert isinstance(const_chat_member, ChatMember) @@ -218,9 +218,9 @@ def test_de_json_required_args(self, bot, chat_member_type): for chat_mem_type_at, const_chat_mem_at in iter_args(chat_member_type, const_chat_member): assert chat_mem_type_at == const_chat_mem_at - def test_de_json_all_args(self, bot, chat_member_type): + def test_de_json_all_args(self, offline_bot, chat_member_type): json_dict = make_json_dict(chat_member_type, include_optional_args=True) - const_chat_member = ChatMember.de_json(json_dict, bot) + const_chat_member = ChatMember.de_json(json_dict, offline_bot) assert const_chat_member.api_kwargs == {} assert isinstance(const_chat_member, ChatMember) @@ -228,14 +228,16 @@ def test_de_json_all_args(self, bot, chat_member_type): for c_mem_type_at, const_c_mem_at in iter_args(chat_member_type, const_chat_member, True): assert c_mem_type_at == const_c_mem_at - def test_de_json_chatmemberbanned_localization(self, chat_member_type, tz_bot, bot, raw_bot): + def test_de_json_chatmemberbanned_localization( + self, chat_member_type, tz_bot, offline_bot, raw_bot + ): # We only test two classes because the other three don't have datetimes in them. if isinstance( chat_member_type, (ChatMemberBanned, ChatMemberRestricted, ChatMemberMember) ): json_dict = make_json_dict(chat_member_type, include_optional_args=True) chatmember_raw = ChatMember.de_json(json_dict, raw_bot) - chatmember_bot = ChatMember.de_json(json_dict, bot) + chatmember_bot = ChatMember.de_json(json_dict, offline_bot) chatmember_tz = ChatMember.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -248,19 +250,19 @@ def test_de_json_chatmemberbanned_localization(self, chat_member_type, tz_bot, b assert chatmember_bot.until_date.tzinfo == UTC assert chatmember_offset == tz_bot_offset - def test_de_json_invalid_status(self, chat_member_type, bot): + def test_de_json_invalid_status(self, chat_member_type, offline_bot): json_dict = {"status": "invalid", "user": CMDefaults.user.to_dict()} - chat_member_type = ChatMember.de_json(json_dict, bot) + chat_member_type = ChatMember.de_json(json_dict, offline_bot) assert type(chat_member_type) is ChatMember assert chat_member_type.status == "invalid" - def test_de_json_subclass(self, chat_member_type, bot, chat_id): - """This makes sure that e.g. ChatMemberAdministrator(data, bot) never returns a + def test_de_json_subclass(self, chat_member_type, offline_bot, chat_id): + """This makes sure that e.g. ChatMemberAdministrator(data, offline_bot) never returns a ChatMemberBanned instance.""" cls = chat_member_type.__class__ json_dict = make_json_dict(chat_member_type, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, chat_member_type): chat_member_dict = chat_member_type.to_dict() diff --git a/tests/test_chatmemberupdated.py b/tests/test_chatmemberupdated.py index 33b07863a5a..7bdd704fbcb 100644 --- a/tests/test_chatmemberupdated.py +++ b/tests/test_chatmemberupdated.py @@ -99,7 +99,9 @@ def test_slot_behaviour(self, chat_member_updated): assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - def test_de_json_required_args(self, bot, user, chat, old_chat_member, new_chat_member, time): + def test_de_json_required_args( + self, offline_bot, user, chat, old_chat_member, new_chat_member, time + ): json_dict = { "chat": chat.to_dict(), "from": user.to_dict(), @@ -108,7 +110,7 @@ def test_de_json_required_args(self, bot, user, chat, old_chat_member, new_chat_ "new_chat_member": new_chat_member.to_dict(), } - chat_member_updated = ChatMemberUpdated.de_json(json_dict, bot) + chat_member_updated = ChatMemberUpdated.de_json(json_dict, offline_bot) assert chat_member_updated.api_kwargs == {} assert chat_member_updated.chat == chat @@ -121,7 +123,7 @@ def test_de_json_required_args(self, bot, user, chat, old_chat_member, new_chat_ assert chat_member_updated.via_chat_folder_invite_link is None def test_de_json_all_args( - self, bot, user, time, invite_link, chat, old_chat_member, new_chat_member + self, offline_bot, user, time, invite_link, chat, old_chat_member, new_chat_member ): json_dict = { "chat": chat.to_dict(), @@ -134,7 +136,7 @@ def test_de_json_all_args( "via_join_request": True, } - chat_member_updated = ChatMemberUpdated.de_json(json_dict, bot) + chat_member_updated = ChatMemberUpdated.de_json(json_dict, offline_bot) assert chat_member_updated.api_kwargs == {} assert chat_member_updated.chat == chat @@ -148,7 +150,16 @@ def test_de_json_all_args( assert chat_member_updated.via_join_request is True def test_de_json_localization( - self, bot, raw_bot, tz_bot, user, chat, old_chat_member, new_chat_member, time, invite_link + self, + offline_bot, + raw_bot, + tz_bot, + user, + chat, + old_chat_member, + new_chat_member, + time, + invite_link, ): json_dict = { "chat": chat.to_dict(), @@ -159,7 +170,7 @@ def test_de_json_localization( "invite_link": invite_link.to_dict(), } - chat_member_updated_bot = ChatMemberUpdated.de_json(json_dict, bot) + chat_member_updated_bot = ChatMemberUpdated.de_json(json_dict, offline_bot) chat_member_updated_raw = ChatMemberUpdated.de_json(json_dict, raw_bot) chat_member_updated_tz = ChatMemberUpdated.de_json(json_dict, tz_bot) diff --git a/tests/test_chatpermissions.py b/tests/test_chatpermissions.py index 79b6bab8081..fcb93840f10 100644 --- a/tests/test_chatpermissions.py +++ b/tests/test_chatpermissions.py @@ -67,7 +67,7 @@ def test_slot_behaviour(self, chat_permissions): 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): + def test_de_json(self, offline_bot): json_dict = { "can_send_messages": self.can_send_messages, "can_send_media_messages": "can_send_media_messages", @@ -84,7 +84,7 @@ def test_de_json(self, bot): "can_send_video_notes": self.can_send_video_notes, "can_send_voice_notes": self.can_send_voice_notes, } - permissions = ChatPermissions.de_json(json_dict, bot) + permissions = ChatPermissions.de_json(json_dict, offline_bot) assert permissions.api_kwargs == {"can_send_media_messages": "can_send_media_messages"} assert permissions.can_send_messages == self.can_send_messages diff --git a/tests/test_choseninlineresult.py b/tests/test_choseninlineresult.py index 2b53b684770..8d6529c103c 100644 --- a/tests/test_choseninlineresult.py +++ b/tests/test_choseninlineresult.py @@ -49,16 +49,16 @@ def test_slot_behaviour(self, chosen_inline_result): 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_required(self, bot, user): + def test_de_json_required(self, offline_bot, user): json_dict = {"result_id": self.result_id, "from": user.to_dict(), "query": self.query} - result = ChosenInlineResult.de_json(json_dict, bot) + result = ChosenInlineResult.de_json(json_dict, offline_bot) assert result.api_kwargs == {} assert result.result_id == self.result_id assert result.from_user == user assert result.query == self.query - def test_de_json_all(self, bot, user): + def test_de_json_all(self, offline_bot, user): loc = Location(-42.003, 34.004) json_dict = { "result_id": self.result_id, @@ -67,7 +67,7 @@ def test_de_json_all(self, bot, user): "location": loc.to_dict(), "inline_message_id": "a random id", } - result = ChosenInlineResult.de_json(json_dict, bot) + result = ChosenInlineResult.de_json(json_dict, offline_bot) assert result.api_kwargs == {} assert result.result_id == self.result_id diff --git a/tests/test_dice.py b/tests/test_dice.py index df3c349d4d7..de82d29aef0 100644 --- a/tests/test_dice.py +++ b/tests/test_dice.py @@ -39,14 +39,14 @@ def test_slot_behaviour(self, dice): assert len(mro_slots(dice)) == len(set(mro_slots(dice))), "duplicate slot" @pytest.mark.parametrize("emoji", Dice.ALL_EMOJI) - def test_de_json(self, bot, emoji): + def test_de_json(self, offline_bot, emoji): json_dict = {"value": self.value, "emoji": emoji} - dice = Dice.de_json(json_dict, bot) + dice = Dice.de_json(json_dict, offline_bot) assert dice.api_kwargs == {} assert dice.value == self.value assert dice.emoji == emoji - assert Dice.de_json(None, bot) is None + assert Dice.de_json(None, offline_bot) is None def test_to_dict(self, dice): dice_dict = dice.to_dict() diff --git a/tests/test_forum.py b/tests/test_forum.py index 1f143616ee9..4fd65c5d8dd 100644 --- a/tests/test_forum.py +++ b/tests/test_forum.py @@ -86,8 +86,8 @@ async def test_expected_values(self, emoji_id, forum_group_id, forum_topic_objec assert forum_topic_object.name == TEST_TOPIC_NAME assert forum_topic_object.icon_custom_emoji_id == emoji_id - def test_de_json(self, bot, emoji_id, forum_group_id): - assert ForumTopic.de_json(None, bot=bot) is None + def test_de_json(self, offline_bot, emoji_id, forum_group_id): + assert ForumTopic.de_json(None, bot=offline_bot) is None json_dict = { "message_thread_id": forum_group_id, @@ -95,7 +95,7 @@ def test_de_json(self, bot, emoji_id, forum_group_id): "icon_color": TEST_TOPIC_ICON_COLOR, "icon_custom_emoji_id": emoji_id, } - topic = ForumTopic.de_json(json_dict, bot) + topic = ForumTopic.de_json(json_dict, offline_bot) assert topic.api_kwargs == {} assert topic.message_thread_id == forum_group_id @@ -333,11 +333,11 @@ def test_expected_values(self, topic_created): assert topic_created.icon_color == TEST_TOPIC_ICON_COLOR assert topic_created.name == TEST_TOPIC_NAME - def test_de_json(self, bot): - assert ForumTopicCreated.de_json(None, bot=bot) is None + def test_de_json(self, offline_bot): + assert ForumTopicCreated.de_json(None, bot=offline_bot) is None json_dict = {"icon_color": TEST_TOPIC_ICON_COLOR, "name": TEST_TOPIC_NAME} - action = ForumTopicCreated.de_json(json_dict, bot) + action = ForumTopicCreated.de_json(json_dict, offline_bot) assert action.api_kwargs == {} assert action.icon_color == TEST_TOPIC_ICON_COLOR diff --git a/tests/test_giveaway.py b/tests/test_giveaway.py index 35945118363..4aac4150c6a 100644 --- a/tests/test_giveaway.py +++ b/tests/test_giveaway.py @@ -66,7 +66,7 @@ def test_slot_behaviour(self, giveaway): assert getattr(giveaway, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(giveaway)) == len(set(mro_slots(giveaway))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "chats": [chat.to_dict() for chat in self.chats], "winners_selection_date": to_timestamp(self.winners_selection_date), @@ -78,7 +78,7 @@ def test_de_json(self, bot): "premium_subscription_month_count": self.premium_subscription_month_count, } - giveaway = Giveaway.de_json(json_dict, bot) + giveaway = Giveaway.de_json(json_dict, offline_bot) assert giveaway.api_kwargs == {} assert giveaway.chats == tuple(self.chats) @@ -90,9 +90,9 @@ def test_de_json(self, bot): assert giveaway.country_codes == tuple(self.country_codes) assert giveaway.premium_subscription_month_count == self.premium_subscription_month_count - assert Giveaway.de_json(None, bot) is None + assert Giveaway.de_json(None, offline_bot) is None - def test_de_json_localization(self, tz_bot, bot, raw_bot): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): json_dict = { "chats": [chat.to_dict() for chat in self.chats], "winners_selection_date": to_timestamp(self.winners_selection_date), @@ -105,7 +105,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot): } giveaway_raw = Giveaway.de_json(json_dict, raw_bot) - giveaway_bot = Giveaway.de_json(json_dict, bot) + giveaway_bot = Giveaway.de_json(json_dict, offline_bot) giveaway_bot_tz = Giveaway.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -213,7 +213,7 @@ def test_slot_behaviour(self, giveaway_winners): set(mro_slots(giveaway_winners)) ), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "chat": self.chat.to_dict(), "giveaway_message_id": self.giveaway_message_id, @@ -228,7 +228,7 @@ def test_de_json(self, bot): "prize_description": self.prize_description, } - giveaway_winners = GiveawayWinners.de_json(json_dict, bot) + giveaway_winners = GiveawayWinners.de_json(json_dict, offline_bot) assert giveaway_winners.api_kwargs == {} assert giveaway_winners.chat == self.chat @@ -246,9 +246,9 @@ def test_de_json(self, bot): assert giveaway_winners.was_refunded == self.was_refunded assert giveaway_winners.prize_description == self.prize_description - assert GiveawayWinners.de_json(None, bot) is None + assert GiveawayWinners.de_json(None, offline_bot) is None - def test_de_json_localization(self, tz_bot, bot, raw_bot): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): json_dict = { "chat": self.chat.to_dict(), "giveaway_message_id": self.giveaway_message_id, @@ -258,7 +258,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot): } giveaway_winners_raw = GiveawayWinners.de_json(json_dict, raw_bot) - giveaway_winners_bot = GiveawayWinners.de_json(json_dict, bot) + giveaway_winners_bot = GiveawayWinners.de_json(json_dict, offline_bot) giveaway_winners_bot_tz = GiveawayWinners.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -357,21 +357,21 @@ def test_slot_behaviour(self, giveaway_completed): set(mro_slots(giveaway_completed)) ), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "winner_count": self.winner_count, "unclaimed_prize_count": self.unclaimed_prize_count, "giveaway_message": self.giveaway_message.to_dict(), } - giveaway_completed = GiveawayCompleted.de_json(json_dict, bot) + giveaway_completed = GiveawayCompleted.de_json(json_dict, offline_bot) assert giveaway_completed.api_kwargs == {} assert giveaway_completed.winner_count == self.winner_count assert giveaway_completed.unclaimed_prize_count == self.unclaimed_prize_count assert giveaway_completed.giveaway_message == self.giveaway_message - assert GiveawayCompleted.de_json(None, bot) is None + assert GiveawayCompleted.de_json(None, offline_bot) is None def test_to_dict(self, giveaway_completed): giveaway_completed_dict = giveaway_completed.to_dict() diff --git a/tests/test_inlinequeryresultsbutton.py b/tests/test_inlinequeryresultsbutton.py index 90ce2c235ac..1ec59573a3b 100644 --- a/tests/test_inlinequeryresultsbutton.py +++ b/tests/test_inlinequeryresultsbutton.py @@ -51,16 +51,16 @@ def test_to_dict(self, inline_query_results_button): assert inline_query_results_button_dict["start_parameter"] == self.start_parameter assert inline_query_results_button_dict["web_app"] == self.web_app.to_dict() - def test_de_json(self, bot): - assert InlineQueryResultsButton.de_json(None, bot) is None - assert InlineQueryResultsButton.de_json({}, bot) is None + def test_de_json(self, offline_bot): + assert InlineQueryResultsButton.de_json(None, offline_bot) is None + assert InlineQueryResultsButton.de_json({}, offline_bot) is None json_dict = { "text": self.text, "start_parameter": self.start_parameter, "web_app": self.web_app.to_dict(), } - inline_query_results_button = InlineQueryResultsButton.de_json(json_dict, bot) + inline_query_results_button = InlineQueryResultsButton.de_json(json_dict, offline_bot) assert inline_query_results_button.text == self.text assert inline_query_results_button.start_parameter == self.start_parameter diff --git a/tests/test_keyboardbutton.py b/tests/test_keyboardbutton.py index 4493ed22320..91f5ccab71f 100644 --- a/tests/test_keyboardbutton.py +++ b/tests/test_keyboardbutton.py @@ -81,7 +81,7 @@ def test_to_dict(self, keyboard_button): assert keyboard_button_dict["request_users"] == keyboard_button.request_users.to_dict() @pytest.mark.parametrize("request_user", [True, False]) - def test_de_json(self, bot, request_user): + def test_de_json(self, request_user): json_dict = { "text": self.text, "request_location": self.request_location, diff --git a/tests/test_keyboardbuttonrequest.py b/tests/test_keyboardbuttonrequest.py index 8e42b1cd374..9d9a0295206 100644 --- a/tests/test_keyboardbuttonrequest.py +++ b/tests/test_keyboardbuttonrequest.py @@ -57,14 +57,14 @@ def test_to_dict(self, request_users): assert request_users_dict["user_is_premium"] == self.user_is_premium assert request_users_dict["max_quantity"] == self.max_quantity - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "request_id": self.request_id, "user_is_bot": self.user_is_bot, "user_is_premium": self.user_is_premium, "max_quantity": self.max_quantity, } - request_users = KeyboardButtonRequestUsers.de_json(json_dict, bot) + request_users = KeyboardButtonRequestUsers.de_json(json_dict, offline_bot) assert request_users.api_kwargs == {} assert request_users.request_id == self.request_id @@ -158,7 +158,7 @@ def test_to_dict(self, request_chat): ) assert request_chat_dict["bot_is_member"] == self.bot_is_member - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "request_id": self.request_id, "chat_is_channel": self.chat_is_channel, @@ -168,7 +168,7 @@ def test_de_json(self, bot): "bot_administrator_rights": self.bot_administrator_rights.to_dict(), "bot_is_member": self.bot_is_member, } - request_chat = KeyboardButtonRequestChat.de_json(json_dict, bot) + request_chat = KeyboardButtonRequestChat.de_json(json_dict, offline_bot) assert request_chat.api_kwargs == {} assert request_chat.request_id == self.request_id @@ -179,7 +179,7 @@ def test_de_json(self, bot): assert request_chat.bot_administrator_rights == self.bot_administrator_rights assert request_chat.bot_is_member == self.bot_is_member - empty_chat = KeyboardButtonRequestChat.de_json({}, bot) + empty_chat = KeyboardButtonRequestChat.de_json({}, offline_bot) assert empty_chat is None def test_equality(self): diff --git a/tests/test_maybeinaccessiblemessage.py b/tests/test_maybeinaccessiblemessage.py index da7db43ce0e..8cad89e884c 100644 --- a/tests/test_maybeinaccessiblemessage.py +++ b/tests/test_maybeinaccessiblemessage.py @@ -59,20 +59,20 @@ def test_to_dict(self, maybe_inaccessible_message): assert maybe_inaccessible_message_dict["message_id"] == self.message_id assert maybe_inaccessible_message_dict["date"] == to_timestamp(self.date) - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "chat": self.chat.to_dict(), "message_id": self.message_id, "date": to_timestamp(self.date), } - maybe_inaccessible_message = MaybeInaccessibleMessage.de_json(json_dict, bot) + maybe_inaccessible_message = MaybeInaccessibleMessage.de_json(json_dict, offline_bot) assert maybe_inaccessible_message.api_kwargs == {} assert maybe_inaccessible_message.chat == self.chat assert maybe_inaccessible_message.message_id == self.message_id assert maybe_inaccessible_message.date == self.date - def test_de_json_localization(self, tz_bot, bot, raw_bot): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): json_dict = { "chat": self.chat.to_dict(), "message_id": self.message_id, @@ -80,7 +80,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot): } maybe_inaccessible_message_raw = MaybeInaccessibleMessage.de_json(json_dict, raw_bot) - maybe_inaccessible_message_bot = MaybeInaccessibleMessage.de_json(json_dict, bot) + maybe_inaccessible_message_bot = MaybeInaccessibleMessage.de_json(json_dict, offline_bot) maybe_inaccessible_message_bot_tz = MaybeInaccessibleMessage.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -95,14 +95,14 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot): assert maybe_inaccessible_message_bot.date.tzinfo == UTC assert maybe_inaccessible_message_bot_tz_offset == tz_bot_offset - def test_de_json_zero_date(self, bot): + def test_de_json_zero_date(self, offline_bot): json_dict = { "chat": self.chat.to_dict(), "message_id": self.message_id, "date": 0, } - maybe_inaccessible_message = MaybeInaccessibleMessage.de_json(json_dict, bot) + maybe_inaccessible_message = MaybeInaccessibleMessage.de_json(json_dict, offline_bot) assert maybe_inaccessible_message.date == ZERO_DATE assert maybe_inaccessible_message.date is ZERO_DATE diff --git a/tests/test_menubutton.py b/tests/test_menubutton.py index d5930f805c2..d9ae7c1ef12 100644 --- a/tests/test_menubutton.py +++ b/tests/test_menubutton.py @@ -103,12 +103,12 @@ def test_slot_behaviour(self, menu_button): assert getattr(menu_button, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(menu_button)) == len(set(mro_slots(menu_button))), "duplicate slot" - def test_de_json(self, bot, scope_class_and_type): + def test_de_json(self, offline_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()} - menu_button = MenuButton.de_json(json_dict, bot) + menu_button = MenuButton.de_json(json_dict, offline_bot) assert set(menu_button.api_kwargs.keys()) == {"text", "web_app"} - set(cls.__slots__) assert isinstance(menu_button, MenuButton) @@ -119,22 +119,22 @@ def test_de_json(self, bot, scope_class_and_type): if "text" in cls.__slots__: assert menu_button.text == self.text - assert cls.de_json(None, bot) is None - assert MenuButton.de_json({}, bot) is None + assert cls.de_json(None, offline_bot) is None + assert MenuButton.de_json({}, offline_bot) is None - def test_de_json_invalid_type(self, bot): + def test_de_json_invalid_type(self, offline_bot): json_dict = {"type": "invalid", "text": self.text, "web_app": self.web_app.to_dict()} - menu_button = MenuButton.de_json(json_dict, bot) + menu_button = MenuButton.de_json(json_dict, offline_bot) 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" - def test_de_json_subclass(self, scope_class, bot): + def test_de_json_subclass(self, scope_class, offline_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()} - assert type(scope_class.de_json(json_dict, bot)) is scope_class + assert type(scope_class.de_json(json_dict, offline_bot)) is scope_class def test_de_json_empty_data(self, scope_class): if scope_class in (MenuButtonWebApp,): @@ -157,7 +157,7 @@ def test_type_enum_conversion(self): assert type(MenuButton("commands").type) is MenuButtonType assert MenuButton("unknown").type == "unknown" - def test_equality(self, menu_button, bot): + def test_equality(self, menu_button, offline_bot): a = MenuButton("base_type") b = MenuButton("base_type") c = menu_button @@ -185,7 +185,7 @@ def test_equality(self, menu_button, bot): if hasattr(c, "web_app"): json_dict = c.to_dict() json_dict["web_app"] = WebAppInfo("https://foo.bar/web_app").to_dict() - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) @@ -193,7 +193,7 @@ def test_equality(self, menu_button, bot): if hasattr(c, "text"): json_dict = c.to_dict() json_dict["text"] = "other text" - g = c.__class__.de_json(json_dict, bot) + g = c.__class__.de_json(json_dict, offline_bot) assert c != g assert hash(c) != hash(g) diff --git a/tests/test_message.py b/tests/test_message.py index 84b2b7c3929..02d6e5b5f4a 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -568,8 +568,8 @@ def test_slot_behaviour(self): 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) + def test_all_possibilities_de_json_and_to_dict(self, offline_bot, message_params): + new = Message.de_json(message_params.to_dict(), offline_bot) assert new.api_kwargs == {} assert new.to_dict() == message_params.to_dict() @@ -579,7 +579,7 @@ 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_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "message_id": 12, "from_user": None, @@ -589,7 +589,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): } message_raw = Message.de_json(json_dict, raw_bot) - message_bot = Message.de_json(json_dict, bot) + message_bot = Message.de_json(json_dict, offline_bot) message_tz = Message.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -609,7 +609,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): assert message_bot.edit_date.tzinfo == UTC assert edit_date_offset == edit_date_tz_bot_offset - def test_de_json_api_kwargs_backward_compatibility(self, bot, message_params): + def test_de_json_api_kwargs_backward_compatibility(self, offline_bot, message_params): message_dict = message_params.to_dict() keys = ( "user_shared", @@ -622,7 +622,7 @@ def test_de_json_api_kwargs_backward_compatibility(self, bot, message_params): ) for key in keys: message_dict[key] = key - message = Message.de_json(message_dict, bot) + message = Message.de_json(message_dict, offline_bot) assert message.api_kwargs == {key: key for key in keys} def test_equality(self): @@ -2653,10 +2653,10 @@ async def make_assertion(*args, **kwargs): ], ) async def test_default_do_quote( - self, bot, message, default_quote, chat_type, expected, monkeypatch + self, offline_bot, message, default_quote, chat_type, expected, monkeypatch ): original_bot = message.get_bot() - temp_bot = PytestExtBot(token=bot.token, defaults=Defaults(do_quote=default_quote)) + temp_bot = PytestExtBot(token=offline_bot.token, defaults=Defaults(do_quote=default_quote)) message.set_bot(temp_bot) async def make_assertion(*_, **kwargs): diff --git a/tests/test_messageentity.py b/tests/test_messageentity.py index 3598454d8eb..4c981f45319 100644 --- a/tests/test_messageentity.py +++ b/tests/test_messageentity.py @@ -55,9 +55,9 @@ def test_slot_behaviour(self, message_entity): 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): + def test_de_json(self, offline_bot): json_dict = {"type": self.type_, "offset": self.offset, "length": self.length} - entity = MessageEntity.de_json(json_dict, bot) + entity = MessageEntity.de_json(json_dict, offline_bot) assert entity.api_kwargs == {} assert entity.type == self.type_ diff --git a/tests/test_messageorigin.py b/tests/test_messageorigin.py index 10d9fa77894..7b239bc3763 100644 --- a/tests/test_messageorigin.py +++ b/tests/test_messageorigin.py @@ -136,12 +136,12 @@ def test_slot_behaviour(self, message_origin_type): 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_required_args(self, bot, message_origin_type): + def test_de_json_required_args(self, offline_bot, message_origin_type): cls = message_origin_type.__class__ - assert cls.de_json({}, bot) is None + assert cls.de_json({}, offline_bot) is None json_dict = make_json_dict(message_origin_type) - const_message_origin = MessageOrigin.de_json(json_dict, bot) + const_message_origin = MessageOrigin.de_json(json_dict, offline_bot) assert const_message_origin.api_kwargs == {} assert isinstance(const_message_origin, MessageOrigin) @@ -151,9 +151,9 @@ def test_de_json_required_args(self, bot, message_origin_type): ): assert msg_origin_type_at == const_msg_origin_at - def test_de_json_all_args(self, bot, message_origin_type): + def test_de_json_all_args(self, offline_bot, message_origin_type): json_dict = make_json_dict(message_origin_type, include_optional_args=True) - const_message_origin = MessageOrigin.de_json(json_dict, bot) + const_message_origin = MessageOrigin.de_json(json_dict, offline_bot) assert const_message_origin.api_kwargs == {} @@ -164,10 +164,12 @@ def test_de_json_all_args(self, bot, message_origin_type): ): assert msg_origin_type_at == const_msg_origin_at - def test_de_json_messageorigin_localization(self, message_origin_type, tz_bot, bot, raw_bot): + def test_de_json_messageorigin_localization( + self, message_origin_type, tz_bot, offline_bot, raw_bot + ): json_dict = make_json_dict(message_origin_type, include_optional_args=True) msgorigin_raw = MessageOrigin.de_json(json_dict, raw_bot) - msgorigin_bot = MessageOrigin.de_json(json_dict, bot) + msgorigin_bot = MessageOrigin.de_json(json_dict, offline_bot) msgorigin_tz = MessageOrigin.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -178,19 +180,19 @@ def test_de_json_messageorigin_localization(self, message_origin_type, tz_bot, b assert msgorigin_bot.date.tzinfo == UTC assert msgorigin_offset == tz_bot_offset - def test_de_json_invalid_type(self, message_origin_type, bot): + def test_de_json_invalid_type(self, message_origin_type, offline_bot): json_dict = {"type": "invalid", "date": MODefaults.date} - message_origin_type = MessageOrigin.de_json(json_dict, bot) + message_origin_type = MessageOrigin.de_json(json_dict, offline_bot) assert type(message_origin_type) is MessageOrigin assert message_origin_type.type == "invalid" - def test_de_json_subclass(self, message_origin_type, bot, chat_id): - """This makes sure that e.g. MessageOriginChat(data, bot) never returns a + def test_de_json_subclass(self, message_origin_type, offline_bot, chat_id): + """This makes sure that e.g. MessageOriginChat(data, offline_bot) never returns a MessageOriginUser instance.""" cls = message_origin_type.__class__ json_dict = make_json_dict(message_origin_type, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, message_origin_type): message_origin_dict = message_origin_type.to_dict() diff --git a/tests/test_paidmedia.py b/tests/test_paidmedia.py index be9ac14905b..6592125e789 100644 --- a/tests/test_paidmedia.py +++ b/tests/test_paidmedia.py @@ -150,7 +150,7 @@ def test_slot_behaviour(self, paid_media): 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, pm_scope_class_and_type): + def test_de_json(self, offline_bot, pm_scope_class_and_type): cls = pm_scope_class_and_type[0] type_ = pm_scope_class_and_type[1] @@ -162,7 +162,7 @@ def test_de_json(self, bot, pm_scope_class_and_type): "video": self.video.to_dict(), "photo": [p.to_dict() for p in self.photo], } - pm = PaidMedia.de_json(json_dict, bot) + pm = PaidMedia.de_json(json_dict, offline_bot) assert set(pm.api_kwargs.keys()) == { "width", "height", @@ -183,10 +183,10 @@ def test_de_json(self, bot, pm_scope_class_and_type): if "photo" in cls.__slots__: assert pm.photo == self.photo - assert cls.de_json(None, bot) is None - assert PaidMedia.de_json({}, bot) is None + assert cls.de_json(None, offline_bot) is None + assert PaidMedia.de_json({}, offline_bot) is None - def test_de_json_invalid_type(self, bot): + def test_de_json_invalid_type(self, offline_bot): json_dict = { "type": "invalid", "width": self.width, @@ -195,7 +195,7 @@ def test_de_json_invalid_type(self, bot): "video": self.video.to_dict(), "photo": [p.to_dict() for p in self.photo], } - pm = PaidMedia.de_json(json_dict, bot) + pm = PaidMedia.de_json(json_dict, offline_bot) assert pm.api_kwargs == { "width": self.width, "height": self.height, @@ -207,7 +207,7 @@ def test_de_json_invalid_type(self, bot): assert type(pm) is PaidMedia assert pm.type == "invalid" - def test_de_json_subclass(self, pm_scope_class, bot): + def test_de_json_subclass(self, pm_scope_class, offline_bot): """This makes sure that e.g. PaidMediaPreivew(data) never returns a TransactionPartnerPhoto instance.""" json_dict = { @@ -218,7 +218,7 @@ def test_de_json_subclass(self, pm_scope_class, bot): "video": self.video.to_dict(), "photo": [p.to_dict() for p in self.photo], } - assert type(pm_scope_class.de_json(json_dict, bot)) is pm_scope_class + assert type(pm_scope_class.de_json(json_dict, offline_bot)) is pm_scope_class def test_to_dict(self, paid_media): pm_dict = paid_media.to_dict() @@ -238,7 +238,7 @@ def test_type_enum_conversion(self): assert type(PaidMedia("video").type) is PaidMediaType assert PaidMedia("unknown").type == "unknown" - def test_equality(self, paid_media, bot): + def test_equality(self, paid_media, offline_bot): a = PaidMedia("base_type") b = PaidMedia("base_type") c = paid_media @@ -266,7 +266,7 @@ def test_equality(self, paid_media, bot): if hasattr(c, "video"): json_dict = c.to_dict() json_dict["video"] = Video("different", "d2", 1, 1, 1).to_dict() - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) @@ -274,7 +274,7 @@ def test_equality(self, paid_media, bot): if hasattr(c, "photo"): json_dict = c.to_dict() json_dict["photo"] = [PhotoSize("different", "d2", 1, 1, 1).to_dict()] - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) @@ -292,13 +292,13 @@ def test_slot_behaviour(self, paid_media_info): 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): + def test_de_json(self, offline_bot): json_dict = { "star_count": self.star_count, "paid_media": [t.to_dict() for t in self.paid_media], } - pmi = PaidMediaInfo.de_json(json_dict, bot) - pmi_none = PaidMediaInfo.de_json(None, bot) + pmi = PaidMediaInfo.de_json(json_dict, offline_bot) + pmi_none = PaidMediaInfo.de_json(None, offline_bot) assert pmi.paid_media == tuple(self.paid_media) assert pmi.star_count == self.star_count assert pmi_none is None diff --git a/tests/test_poll.py b/tests/test_poll.py index 81619a11299..aedc5cf524b 100644 --- a/tests/test_poll.py +++ b/tests/test_poll.py @@ -305,7 +305,7 @@ class PollTestBase: class TestPollWithoutRequest(PollTestBase): - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "id": self.id_, "question": self.question, @@ -321,7 +321,7 @@ def test_de_json(self, bot): "close_date": to_timestamp(self.close_date), "question_entities": [e.to_dict() for e in self.question_entities], } - poll = Poll.de_json(json_dict, bot) + poll = Poll.de_json(json_dict, offline_bot) assert poll.api_kwargs == {} assert poll.id == self.id_ @@ -343,7 +343,7 @@ def test_de_json(self, bot): assert to_timestamp(poll.close_date) == to_timestamp(self.close_date) assert poll.question_entities == tuple(self.question_entities) - def test_de_json_localization(self, tz_bot, bot, raw_bot): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): json_dict = { "id": self.id_, "question": self.question, @@ -361,7 +361,7 @@ def test_de_json_localization(self, tz_bot, bot, raw_bot): } poll_raw = Poll.de_json(json_dict, raw_bot) - poll_bot = Poll.de_json(json_dict, bot) + poll_bot = Poll.de_json(json_dict, offline_bot) poll_bot_tz = Poll.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable diff --git a/tests/test_proximityalerttriggered.py b/tests/test_proximityalerttriggered.py index de49b699fea..6367af9d383 100644 --- a/tests/test_proximityalerttriggered.py +++ b/tests/test_proximityalerttriggered.py @@ -44,13 +44,13 @@ def test_slot_behaviour(self, proximity_alert_triggered): 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): + def test_de_json(self, offline_bot): json_dict = { "traveler": self.traveler.to_dict(), "watcher": self.watcher.to_dict(), "distance": self.distance, } - proximity_alert_triggered = ProximityAlertTriggered.de_json(json_dict, bot) + proximity_alert_triggered = ProximityAlertTriggered.de_json(json_dict, offline_bot) assert proximity_alert_triggered.api_kwargs == {} assert proximity_alert_triggered.traveler == self.traveler diff --git a/tests/test_reaction.py b/tests/test_reaction.py index 67ece80e3b0..79f3e2c40be 100644 --- a/tests/test_reaction.py +++ b/tests/test_reaction.py @@ -115,13 +115,13 @@ def test_slot_behaviour(self, reaction_type): 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_required_args(self, bot, reaction_type): + def test_de_json_required_args(self, offline_bot, reaction_type): cls = reaction_type.__class__ - assert cls.de_json(None, bot) is None - assert ReactionType.de_json({}, bot) is None + assert cls.de_json(None, offline_bot) is None + assert ReactionType.de_json({}, offline_bot) is None json_dict = make_json_dict(reaction_type) - const_reaction_type = ReactionType.de_json(json_dict, bot) + const_reaction_type = ReactionType.de_json(json_dict, offline_bot) assert const_reaction_type.api_kwargs == {} assert isinstance(const_reaction_type, ReactionType) @@ -131,9 +131,9 @@ def test_de_json_required_args(self, bot, reaction_type): ): assert reaction_type_at == const_reaction_type_at - def test_de_json_all_args(self, bot, reaction_type): + def test_de_json_all_args(self, offline_bot, reaction_type): json_dict = make_json_dict(reaction_type, include_optional_args=True) - const_reaction_type = ReactionType.de_json(json_dict, bot) + const_reaction_type = ReactionType.de_json(json_dict, offline_bot) assert const_reaction_type.api_kwargs == {} assert isinstance(const_reaction_type, ReactionType) @@ -141,19 +141,19 @@ def test_de_json_all_args(self, bot, reaction_type): for c_mem_type_at, const_c_mem_at in iter_args(reaction_type, const_reaction_type, True): assert c_mem_type_at == const_c_mem_at - def test_de_json_invalid_type(self, bot, reaction_type): + def test_de_json_invalid_type(self, offline_bot, reaction_type): json_dict = {"type": "invalid"} - reaction_type = ReactionType.de_json(json_dict, bot) + reaction_type = ReactionType.de_json(json_dict, offline_bot) assert type(reaction_type) is ReactionType assert reaction_type.type == "invalid" - def test_de_json_subclass(self, reaction_type, bot, chat_id): - """This makes sure that e.g. ReactionTypeEmoji(data, bot) never returns a + def test_de_json_subclass(self, reaction_type, offline_bot, chat_id): + """This makes sure that e.g. ReactionTypeEmoji(data, offline_bot) never returns a ReactionTypeCustomEmoji instance.""" cls = reaction_type.__class__ json_dict = make_json_dict(reaction_type, True) - assert type(cls.de_json(json_dict, bot)) is cls + assert type(cls.de_json(json_dict, offline_bot)) is cls def test_to_dict(self, reaction_type): reaction_type_dict = reaction_type.to_dict() @@ -237,13 +237,13 @@ def test_slot_behaviour(self, reaction_count): set(mro_slots(reaction_count)) ), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "type": self.type.to_dict(), "total_count": self.total_count, } - reaction_count = ReactionCount.de_json(json_dict, bot) + reaction_count = ReactionCount.de_json(json_dict, offline_bot) assert reaction_count.api_kwargs == {} assert isinstance(reaction_count, ReactionCount) @@ -252,7 +252,7 @@ def test_de_json(self, bot): assert reaction_count.type.emoji == self.type.emoji assert reaction_count.total_count == self.total_count - assert ReactionCount.de_json(None, bot) is None + assert ReactionCount.de_json(None, offline_bot) is None def test_to_dict(self, reaction_count): reaction_count_dict = reaction_count.to_dict() diff --git a/tests/test_reply.py b/tests/test_reply.py index 5cacb7b6b5c..a450a721d7d 100644 --- a/tests/test_reply.py +++ b/tests/test_reply.py @@ -73,7 +73,7 @@ def test_slot_behaviour(self, external_reply_info): set(mro_slots(external_reply_info)) ), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "origin": self.origin.to_dict(), "chat": self.chat.to_dict(), @@ -83,7 +83,7 @@ def test_de_json(self, bot): "paid_media": self.paid_media.to_dict(), } - external_reply_info = ExternalReplyInfo.de_json(json_dict, bot) + external_reply_info = ExternalReplyInfo.de_json(json_dict, offline_bot) assert external_reply_info.api_kwargs == {} assert external_reply_info.origin == self.origin @@ -93,7 +93,7 @@ def test_de_json(self, bot): assert external_reply_info.giveaway == self.giveaway assert external_reply_info.paid_media == self.paid_media - assert ExternalReplyInfo.de_json(None, bot) is None + assert ExternalReplyInfo.de_json(None, offline_bot) is None def test_to_dict(self, external_reply_info): ext_reply_info_dict = external_reply_info.to_dict() @@ -151,7 +151,7 @@ def test_slot_behaviour(self, text_quote): assert getattr(text_quote, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(text_quote)) == len(set(mro_slots(text_quote))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "text": self.text, "position": self.position, @@ -159,7 +159,7 @@ def test_de_json(self, bot): "is_manual": self.is_manual, } - text_quote = TextQuote.de_json(json_dict, bot) + text_quote = TextQuote.de_json(json_dict, offline_bot) assert text_quote.api_kwargs == {} assert text_quote.text == self.text @@ -167,7 +167,7 @@ def test_de_json(self, bot): assert text_quote.entities == tuple(self.entities) assert text_quote.is_manual == self.is_manual - assert TextQuote.de_json(None, bot) is None + assert TextQuote.de_json(None, offline_bot) is None def test_to_dict(self, text_quote): text_quote_dict = text_quote.to_dict() @@ -233,7 +233,7 @@ def test_slot_behaviour(self, reply_parameters): set(mro_slots(reply_parameters)) ), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "message_id": self.message_id, "chat_id": self.chat_id, @@ -244,7 +244,7 @@ def test_de_json(self, bot): "quote_position": self.quote_position, } - reply_parameters = ReplyParameters.de_json(json_dict, bot) + reply_parameters = ReplyParameters.de_json(json_dict, offline_bot) assert reply_parameters.api_kwargs == {} assert reply_parameters.message_id == self.message_id @@ -255,7 +255,7 @@ def test_de_json(self, bot): assert reply_parameters.quote_entities == tuple(self.quote_entities) assert reply_parameters.quote_position == self.quote_position - assert ReplyParameters.de_json(None, bot) is None + assert ReplyParameters.de_json(None, offline_bot) is None def test_to_dict(self, reply_parameters): reply_parameters_dict = reply_parameters.to_dict() diff --git a/tests/test_sentwebappmessage.py b/tests/test_sentwebappmessage.py index e4bc116d035..bd206eedef1 100644 --- a/tests/test_sentwebappmessage.py +++ b/tests/test_sentwebappmessage.py @@ -45,7 +45,7 @@ def test_to_dict(self, sent_web_app_message): assert isinstance(sent_web_app_message_dict, dict) assert sent_web_app_message_dict["inline_message_id"] == self.inline_message_id - def test_de_json(self, bot): + def test_de_json(self, offline_bot): data = {"inline_message_id": self.inline_message_id} m = SentWebAppMessage.de_json(data, None) assert m.api_kwargs == {} diff --git a/tests/test_shared.py b/tests/test_shared.py index c51bcf5ea91..9cc8d4bcaa8 100644 --- a/tests/test_shared.py +++ b/tests/test_shared.py @@ -47,19 +47,19 @@ def test_to_dict(self, users_shared): assert users_shared_dict["request_id"] == self.request_id assert users_shared_dict["users"] == [user.to_dict() for user in self.users] - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "request_id": self.request_id, "users": [user.to_dict() for user in self.users], "user_ids": self.user_ids, } - users_shared = UsersShared.de_json(json_dict, bot) + users_shared = UsersShared.de_json(json_dict, offline_bot) assert users_shared.api_kwargs == {"user_ids": self.user_ids} assert users_shared.request_id == self.request_id assert users_shared.users == self.users - assert UsersShared.de_json({}, bot) is None + assert UsersShared.de_json({}, offline_bot) is None def test_equality(self): a = UsersShared(self.request_id, users=self.users) @@ -108,12 +108,12 @@ def test_to_dict(self, chat_shared): assert chat_shared_dict["request_id"] == self.request_id assert chat_shared_dict["chat_id"] == self.chat_id - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "request_id": self.request_id, "chat_id": self.chat_id, } - chat_shared = ChatShared.de_json(json_dict, bot) + chat_shared = ChatShared.de_json(json_dict, offline_bot) assert chat_shared.api_kwargs == {} assert chat_shared.request_id == self.request_id @@ -178,12 +178,12 @@ def test_to_dict(self, shared_user): assert shared_user_dict["username"] == self.username assert shared_user_dict["photo"] == [photo.to_dict() for photo in self.photo] - def test_de_json_required(self, bot): + def test_de_json_required(self, offline_bot): json_dict = { "user_id": self.user_id, "first_name": self.first_name, } - shared_user = SharedUser.de_json(json_dict, bot) + shared_user = SharedUser.de_json(json_dict, offline_bot) assert shared_user.api_kwargs == {} assert shared_user.user_id == self.user_id @@ -192,7 +192,7 @@ def test_de_json_required(self, bot): assert shared_user.username is None assert shared_user.photo == () - def test_de_json_all(self, bot): + def test_de_json_all(self, offline_bot): json_dict = { "user_id": self.user_id, "first_name": self.first_name, @@ -200,7 +200,7 @@ def test_de_json_all(self, bot): "username": self.username, "photo": [photo.to_dict() for photo in self.photo], } - shared_user = SharedUser.de_json(json_dict, bot) + shared_user = SharedUser.de_json(json_dict, offline_bot) assert shared_user.api_kwargs == {} assert shared_user.user_id == self.user_id @@ -209,7 +209,7 @@ def test_de_json_all(self, bot): assert shared_user.username == self.username assert shared_user.photo == self.photo - assert SharedUser.de_json({}, bot) is None + assert SharedUser.de_json({}, offline_bot) is None def test_equality(self, chat_shared): a = SharedUser( diff --git a/tests/test_stars.py b/tests/test_stars.py index ef700ae392a..23ddb410916 100644 --- a/tests/test_stars.py +++ b/tests/test_stars.py @@ -253,7 +253,7 @@ def test_slot_behaviour(self): 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): + def test_de_json(self, offline_bot): json_dict = { "id": self.id, "amount": self.amount, @@ -261,8 +261,8 @@ def test_de_json(self, bot): "source": self.source.to_dict(), "receiver": self.receiver.to_dict(), } - st = StarTransaction.de_json(json_dict, bot) - st_none = StarTransaction.de_json(None, bot) + st = StarTransaction.de_json(json_dict, offline_bot) + st_none = StarTransaction.de_json(None, offline_bot) assert st.api_kwargs == {} assert st.id == self.id assert st.amount == self.amount @@ -271,10 +271,10 @@ def test_de_json(self, bot): assert st.receiver == self.receiver assert st_none is None - def test_de_json_star_transaction_localization(self, tz_bot, bot, raw_bot): + def test_de_json_star_transaction_localization(self, tz_bot, offline_bot, raw_bot): json_dict = star_transaction().to_dict() st_raw = StarTransaction.de_json(json_dict, raw_bot) - st_bot = StarTransaction.de_json(json_dict, bot) + st_bot = StarTransaction.de_json(json_dict, offline_bot) st_tz = StarTransaction.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable @@ -343,12 +343,12 @@ def test_slot_behaviour(self, star_transactions): 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): + def test_de_json(self, offline_bot): json_dict = { "transactions": [t.to_dict() for t in self.transactions], } - st = StarTransactions.de_json(json_dict, bot) - st_none = StarTransactions.de_json(None, bot) + st = StarTransactions.de_json(json_dict, offline_bot) + st_none = StarTransactions.de_json(None, offline_bot) assert st.api_kwargs == {} assert st.transactions == tuple(self.transactions) assert st_none is None @@ -390,7 +390,7 @@ def test_slot_behaviour(self, transaction_partner): 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, tp_scope_class_and_type): + def test_de_json(self, offline_bot, tp_scope_class_and_type): cls = tp_scope_class_and_type[0] type_ = tp_scope_class_and_type[1] @@ -400,7 +400,7 @@ def test_de_json(self, bot, tp_scope_class_and_type): "withdrawal_state": self.withdrawal_state.to_dict(), "user": self.user.to_dict(), } - tp = TransactionPartner.de_json(json_dict, bot) + tp = TransactionPartner.de_json(json_dict, offline_bot) assert set(tp.api_kwargs.keys()) == {"user", "withdrawal_state", "invoice_payload"} - set( cls.__slots__ ) @@ -414,17 +414,17 @@ def test_de_json(self, bot, tp_scope_class_and_type): assert tp.user == self.user assert tp.invoice_payload == self.invoice_payload - assert cls.de_json(None, bot) is None - assert TransactionPartner.de_json({}, bot) is None + assert cls.de_json(None, offline_bot) is None + assert TransactionPartner.de_json({}, offline_bot) is None - def test_de_json_invalid_type(self, bot): + def test_de_json_invalid_type(self, offline_bot): json_dict = { "type": "invalid", "invoice_payload": self.invoice_payload, "withdrawal_state": self.withdrawal_state.to_dict(), "user": self.user.to_dict(), } - tp = TransactionPartner.de_json(json_dict, bot) + tp = TransactionPartner.de_json(json_dict, offline_bot) assert tp.api_kwargs == { "withdrawal_state": self.withdrawal_state.to_dict(), "user": self.user.to_dict(), @@ -434,7 +434,7 @@ def test_de_json_invalid_type(self, bot): assert type(tp) is TransactionPartner assert tp.type == "invalid" - def test_de_json_subclass(self, tp_scope_class, bot): + def test_de_json_subclass(self, tp_scope_class, offline_bot): """This makes sure that e.g. TransactionPartnerUser(data) never returns a TransactionPartnerFragment instance.""" json_dict = { @@ -443,7 +443,7 @@ def test_de_json_subclass(self, tp_scope_class, bot): "withdrawal_state": self.withdrawal_state.to_dict(), "user": self.user.to_dict(), } - assert type(tp_scope_class.de_json(json_dict, bot)) is tp_scope_class + assert type(tp_scope_class.de_json(json_dict, offline_bot)) is tp_scope_class def test_to_dict(self, transaction_partner): tp_dict = transaction_partner.to_dict() @@ -460,7 +460,7 @@ def test_type_enum_conversion(self): assert type(TransactionPartner("other").type) is TransactionPartnerType assert TransactionPartner("unknown").type == "unknown" - def test_equality(self, transaction_partner, bot): + def test_equality(self, transaction_partner, offline_bot): a = TransactionPartner("base_type") b = TransactionPartner("base_type") c = transaction_partner @@ -488,7 +488,7 @@ def test_equality(self, transaction_partner, bot): if hasattr(c, "user"): json_dict = c.to_dict() json_dict["user"] = User(2, "something", True).to_dict() - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) @@ -506,7 +506,7 @@ def test_slot_behaviour(self, revenue_withdrawal_state): 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, rws_scope_class_and_type): + def test_de_json(self, offline_bot, rws_scope_class_and_type): cls = rws_scope_class_and_type[0] type_ = rws_scope_class_and_type[1] @@ -515,7 +515,7 @@ def test_de_json(self, bot, rws_scope_class_and_type): "date": to_timestamp(self.date), "url": self.url, } - rws = RevenueWithdrawalState.de_json(json_dict, bot) + rws = RevenueWithdrawalState.de_json(json_dict, offline_bot) assert set(rws.api_kwargs.keys()) == {"date", "url"} - set(cls.__slots__) assert isinstance(rws, RevenueWithdrawalState) @@ -526,16 +526,16 @@ def test_de_json(self, bot, rws_scope_class_and_type): if "url" in cls.__slots__: assert rws.url == self.url - assert cls.de_json(None, bot) is None - assert RevenueWithdrawalState.de_json({}, bot) is None + assert cls.de_json(None, offline_bot) is None + assert RevenueWithdrawalState.de_json({}, offline_bot) is None - def test_de_json_invalid_type(self, bot): + def test_de_json_invalid_type(self, offline_bot): json_dict = { "type": "invalid", "date": to_timestamp(self.date), "url": self.url, } - rws = RevenueWithdrawalState.de_json(json_dict, bot) + rws = RevenueWithdrawalState.de_json(json_dict, offline_bot) assert rws.api_kwargs == { "date": to_timestamp(self.date), "url": self.url, @@ -544,7 +544,7 @@ def test_de_json_invalid_type(self, bot): assert type(rws) is RevenueWithdrawalState assert rws.type == "invalid" - def test_de_json_subclass(self, rws_scope_class, bot): + def test_de_json_subclass(self, rws_scope_class, offline_bot): """This makes sure that e.g. RevenueWithdrawalState(data) never returns a RevenueWithdrawalStateFailed instance.""" json_dict = { @@ -552,7 +552,7 @@ def test_de_json_subclass(self, rws_scope_class, bot): "date": to_timestamp(self.date), "url": self.url, } - assert type(rws_scope_class.de_json(json_dict, bot)) is rws_scope_class + assert type(rws_scope_class.de_json(json_dict, offline_bot)) is rws_scope_class def test_to_dict(self, revenue_withdrawal_state): rws_dict = revenue_withdrawal_state.to_dict() @@ -568,7 +568,7 @@ def test_type_enum_conversion(self): assert type(RevenueWithdrawalState("failed").type) is RevenueWithdrawalStateType assert RevenueWithdrawalState("unknown").type == "unknown" - def test_equality(self, revenue_withdrawal_state, bot): + def test_equality(self, revenue_withdrawal_state, offline_bot): a = RevenueWithdrawalState("base_type") b = RevenueWithdrawalState("base_type") c = revenue_withdrawal_state @@ -596,7 +596,7 @@ def test_equality(self, revenue_withdrawal_state, bot): if hasattr(c, "url"): json_dict = c.to_dict() json_dict["url"] = "something" - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c == f assert hash(c) == hash(f) @@ -604,7 +604,7 @@ def test_equality(self, revenue_withdrawal_state, bot): if hasattr(c, "date"): json_dict = c.to_dict() json_dict["date"] = to_timestamp(datetime.datetime.utcnow()) - f = c.__class__.de_json(json_dict, bot) + f = c.__class__.de_json(json_dict, offline_bot) assert c != f assert hash(c) != hash(f) diff --git a/tests/test_story.py b/tests/test_story.py index 1aad292cb45..190c4ec133c 100644 --- a/tests/test_story.py +++ b/tests/test_story.py @@ -38,14 +38,14 @@ def test_slot_behaviour(self, story): assert getattr(story, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(story)) == len(set(mro_slots(story))), "duplicate slot" - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = {"chat": self.chat.to_dict(), "id": self.id} - story = Story.de_json(json_dict, bot) + story = Story.de_json(json_dict, offline_bot) assert story.api_kwargs == {} assert story.chat == self.chat assert story.id == self.id assert isinstance(story, Story) - assert Story.de_json(None, bot) is None + assert Story.de_json(None, offline_bot) is None def test_to_dict(self, story): story_dict = story.to_dict() diff --git a/tests/test_update.py b/tests/test_update.py index 46619fbfd9d..f2e9dbf610e 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -227,11 +227,11 @@ def test_slot_behaviour(self): 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): + def test_de_json(self, offline_bot, paramdict): 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) + update = Update.de_json(json_dict, offline_bot) assert update.api_kwargs == {} assert update.update_id == self.update_id @@ -244,8 +244,8 @@ def test_de_json(self, bot, paramdict): assert getattr(update, _type) == paramdict[_type] assert i == 1 - def test_update_de_json_empty(self, bot): - update = Update.de_json(None, bot) + def test_update_de_json_empty(self, offline_bot): + update = Update.de_json(None, offline_bot) assert update is None diff --git a/tests/test_user.py b/tests/test_user.py index 073d0af58e0..d8a6265f0cf 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -91,8 +91,8 @@ def test_slot_behaviour(self, user): assert getattr(user, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(user)) == len(set(mro_slots(user))), "duplicate slot" - def test_de_json(self, json_dict, bot): - user = User.de_json(json_dict, bot) + def test_de_json(self, json_dict, offline_bot): + user = User.de_json(json_dict, offline_bot) assert user.api_kwargs == {} assert user.id == self.id_ diff --git a/tests/test_userprofilephotos.py b/tests/test_userprofilephotos.py index f0017ce6ca6..5ae686fad01 100644 --- a/tests/test_userprofilephotos.py +++ b/tests/test_userprofilephotos.py @@ -41,9 +41,9 @@ def test_slot_behaviour(self): 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): + def test_de_json(self, offline_bot): 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) + user_profile_photos = UserProfilePhotos.de_json(json_dict, offline_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) diff --git a/tests/test_videochat.py b/tests/test_videochat.py index 5fbdf8ba8eb..e5de669c672 100644 --- a/tests/test_videochat.py +++ b/tests/test_videochat.py @@ -105,9 +105,9 @@ def test_slot_behaviour(self, user1): assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" - def test_de_json(self, user1, user2, bot): + def test_de_json(self, user1, user2, offline_bot): json_data = {"users": [user1.to_dict(), user2.to_dict()]} - video_chat_participants = VideoChatParticipantsInvited.de_json(json_data, bot) + video_chat_participants = VideoChatParticipantsInvited.de_json(json_data, offline_bot) assert video_chat_participants.api_kwargs == {} assert isinstance(video_chat_participants.users, tuple) @@ -161,20 +161,20 @@ def test_slot_behaviour(self): def test_expected_values(self): assert VideoChatScheduled(self.start_date).start_date == self.start_date - def test_de_json(self, bot): - assert VideoChatScheduled.de_json({}, bot=bot) is None + def test_de_json(self, offline_bot): + assert VideoChatScheduled.de_json({}, bot=offline_bot) is None json_dict = {"start_date": to_timestamp(self.start_date)} - video_chat_scheduled = VideoChatScheduled.de_json(json_dict, bot) + video_chat_scheduled = VideoChatScheduled.de_json(json_dict, offline_bot) assert video_chat_scheduled.api_kwargs == {} assert abs(video_chat_scheduled.start_date - self.start_date) < dtm.timedelta(seconds=1) - def test_de_json_localization(self, tz_bot, bot, raw_bot): + def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): json_dict = {"start_date": to_timestamp(self.start_date)} videochat_raw = VideoChatScheduled.de_json(json_dict, raw_bot) - videochat_bot = VideoChatScheduled.de_json(json_dict, bot) + videochat_bot = VideoChatScheduled.de_json(json_dict, offline_bot) videochat_tz = VideoChatScheduled.de_json(json_dict, tz_bot) # comparing utcoffsets because comparing timezones is unpredicatable diff --git a/tests/test_webappdata.py b/tests/test_webappdata.py index a13043042c2..ba8d4360831 100644 --- a/tests/test_webappdata.py +++ b/tests/test_webappdata.py @@ -46,9 +46,9 @@ def test_to_dict(self, web_app_data): assert web_app_data_dict["data"] == self.data assert web_app_data_dict["button_text"] == self.button_text - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = {"data": self.data, "button_text": self.button_text} - web_app_data = WebAppData.de_json(json_dict, bot) + web_app_data = WebAppData.de_json(json_dict, offline_bot) assert web_app_data.api_kwargs == {} assert web_app_data.data == self.data diff --git a/tests/test_webappinfo.py b/tests/test_webappinfo.py index 40d65873351..76dd018d59f 100644 --- a/tests/test_webappinfo.py +++ b/tests/test_webappinfo.py @@ -44,9 +44,9 @@ def test_to_dict(self, web_app_info): assert isinstance(web_app_info_dict, dict) assert web_app_info_dict["url"] == self.url - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = {"url": self.url} - web_app_info = WebAppInfo.de_json(json_dict, bot) + web_app_info = WebAppInfo.de_json(json_dict, offline_bot) assert web_app_info.api_kwargs == {} assert web_app_info.url == self.url diff --git a/tests/test_webhookinfo.py b/tests/test_webhookinfo.py index 48bb5ee38e6..cfd6810b1e2 100644 --- a/tests/test_webhookinfo.py +++ b/tests/test_webhookinfo.py @@ -72,7 +72,7 @@ def test_to_dict(self, webhook_info): == self.last_synchronization_error_date ) - def test_de_json(self, bot): + def test_de_json(self, offline_bot): json_dict = { "url": self.url, "has_custom_certificate": self.has_custom_certificate, @@ -83,7 +83,7 @@ def test_de_json(self, bot): "ip_address": self.ip_address, "last_synchronization_error_date": self.last_synchronization_error_date, } - webhook_info = WebhookInfo.de_json(json_dict, bot) + webhook_info = WebhookInfo.de_json(json_dict, offline_bot) assert webhook_info.api_kwargs == {} assert webhook_info.url == self.url @@ -99,10 +99,10 @@ def test_de_json(self, bot): self.last_synchronization_error_date ) - none = WebhookInfo.de_json(None, bot) + none = WebhookInfo.de_json(None, offline_bot) assert none is None - def test_de_json_localization(self, bot, raw_bot, tz_bot): + def test_de_json_localization(self, offline_bot, raw_bot, tz_bot): json_dict = { "url": self.url, "has_custom_certificate": self.has_custom_certificate, @@ -113,7 +113,7 @@ def test_de_json_localization(self, bot, raw_bot, tz_bot): "ip_address": self.ip_address, "last_synchronization_error_date": self.last_synchronization_error_date, } - webhook_info_bot = WebhookInfo.de_json(json_dict, bot) + webhook_info_bot = WebhookInfo.de_json(json_dict, offline_bot) webhook_info_raw = WebhookInfo.de_json(json_dict, raw_bot) webhook_info_tz = WebhookInfo.de_json(json_dict, tz_bot) From b3155b2e55276e947b44de15a67cb066ffabd194 Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:32:22 -0400 Subject: [PATCH 5/9] Update Python 3.13 Test Suite to RC2 (#4471) --- .github/workflows/unit_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index c891151da11..fc9925c0806 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -20,7 +20,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-rc.1'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-rc.2'] os: [ubuntu-latest, windows-latest, macos-latest] fail-fast: False steps: From 6b5e46cc08ac5f38243fb2e287aa5fa765753f20 Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:16:39 +0200 Subject: [PATCH 6/9] Improve Type Completeness (#4466) --- .../workflows/type_completeness_monthly.yml | 33 +++++++++++++++++++ examples/nestedconversationbot.py | 4 +-- telegram/ext/_application.py | 12 ++++--- telegram/ext/_callbackcontext.py | 16 +++++---- telegram/ext/_handlers/basehandler.py | 7 ++-- .../_handlers/businessconnectionhandler.py | 4 +-- .../businessmessagesdeletedhandler.py | 4 +-- .../ext/_handlers/callbackqueryhandler.py | 4 +-- telegram/ext/_handlers/chatboosthandler.py | 8 ++--- .../ext/_handlers/chatjoinrequesthandler.py | 4 +-- telegram/ext/_handlers/chatmemberhandler.py | 4 +-- .../_handlers/choseninlineresulthandler.py | 4 +-- telegram/ext/_handlers/commandhandler.py | 4 +-- telegram/ext/_handlers/conversationhandler.py | 26 +++++++-------- telegram/ext/_handlers/inlinequeryhandler.py | 4 +-- telegram/ext/_handlers/messagehandler.py | 4 +-- .../ext/_handlers/messagereactionhandler.py | 4 +-- telegram/ext/_handlers/pollanswerhandler.py | 4 +-- telegram/ext/_handlers/pollhandler.py | 4 +-- .../ext/_handlers/precheckoutqueryhandler.py | 4 +-- telegram/ext/_handlers/prefixhandler.py | 4 +-- .../ext/_handlers/shippingqueryhandler.py | 4 +-- .../ext/_handlers/stringcommandhandler.py | 4 +-- telegram/ext/_handlers/stringregexhandler.py | 4 +-- telegram/ext/_handlers/typehandler.py | 4 +-- 25 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 .github/workflows/type_completeness_monthly.yml diff --git a/.github/workflows/type_completeness_monthly.yml b/.github/workflows/type_completeness_monthly.yml new file mode 100644 index 00000000000..a5492f9030c --- /dev/null +++ b/.github/workflows/type_completeness_monthly.yml @@ -0,0 +1,33 @@ +name: Check Type Completeness Monthly Run +on: + schedule: + # Run first friday of the month at 03:17 - odd time to spread load on GitHub Actions + - cron: '17 3 1-7 * 5' + +jobs: + test-type-completeness: + name: test-type-completeness + runs-on: ubuntu-latest + steps: + - uses: Bibo-Joshi/pyright-type-completeness@1.0.0 + id: pyright-type-completeness + with: + package-name: telegram + python-version: 3.12 + pyright-version: ~=1.1.367 + - name: Check Output + uses: jannekem/run-python-script-action@v1 + env: + TYPE_COMPLETENESS: ${{ steps.pyright-type-completeness.outputs.base-completeness-score }} + with: + script: | + import os + completeness = float(os.getenv("TYPE_COMPLETENESS")) + + if completeness >= 1: + exit(0) + + text = f"Type Completeness Decreased to {completeness}. ❌" + error(text) + set_summary(text) + exit(1) diff --git a/examples/nestedconversationbot.py b/examples/nestedconversationbot.py index 918f0becf24..fdc49de2b7f 100644 --- a/examples/nestedconversationbot.py +++ b/examples/nestedconversationbot.py @@ -371,8 +371,8 @@ def main() -> None: entry_points=[CommandHandler("start", start)], states={ SHOWING: [CallbackQueryHandler(start, pattern="^" + str(END) + "$")], - SELECTING_ACTION: selection_handlers, - SELECTING_LEVEL: selection_handlers, + SELECTING_ACTION: selection_handlers, # type: ignore[dict-item] + SELECTING_LEVEL: selection_handlers, # type: ignore[dict-item] DESCRIBING_SELF: [description_conv], STOPPING: [CommandHandler("start", start)], }, diff --git a/telegram/ext/_application.py b/telegram/ext/_application.py index a1013ce570a..86e38b1de9f 100644 --- a/telegram/ext/_application.py +++ b/telegram/ext/_application.py @@ -323,7 +323,7 @@ def __init__( self.update_queue: asyncio.Queue[object] = update_queue self.context_types: ContextTypes[CCT, UD, CD, BD] = context_types self.updater: Optional[Updater] = updater - self.handlers: Dict[int, List[BaseHandler[Any, CCT]]] = {} + self.handlers: Dict[int, List[BaseHandler[Any, CCT, Any]]] = {} self.error_handlers: Dict[ HandlerCallback[object, CCT, None], Union[bool, DefaultValue[bool]] ] = {} @@ -1352,7 +1352,7 @@ async def process_update(self, update: object) -> None: # (in __create_task_callback) self._mark_for_persistence_update(update=update) - def add_handler(self, handler: BaseHandler[Any, CCT], group: int = DEFAULT_GROUP) -> None: + def add_handler(self, handler: BaseHandler[Any, CCT, Any], group: int = DEFAULT_GROUP) -> None: """Register a handler. TL;DR: Order and priority counts. 0 or 1 handlers per group will be used. End handling of @@ -1420,8 +1420,8 @@ def add_handler(self, handler: BaseHandler[Any, CCT], group: int = DEFAULT_GROUP def add_handlers( self, handlers: Union[ - Union[List[BaseHandler[Any, CCT]], Tuple[BaseHandler[Any, CCT]]], - Dict[int, Union[List[BaseHandler[Any, CCT]], Tuple[BaseHandler[Any, CCT]]]], + Union[List[BaseHandler[Any, CCT, Any]], Tuple[BaseHandler[Any, CCT, Any]]], + Dict[int, Union[List[BaseHandler[Any, CCT, Any]], Tuple[BaseHandler[Any, CCT, Any]]]], ], group: Union[int, DefaultValue[int]] = _DEFAULT_0, ) -> None: @@ -1469,7 +1469,9 @@ def add_handlers( "dictionary where the keys are groups and values are sequences of handlers." ) - def remove_handler(self, handler: BaseHandler[Any, CCT], group: int = DEFAULT_GROUP) -> None: + def remove_handler( + self, handler: BaseHandler[Any, CCT, Any], group: int = DEFAULT_GROUP + ) -> None: """Remove a handler from the specified group. Args: diff --git a/telegram/ext/_callbackcontext.py b/telegram/ext/_callbackcontext.py index ea708e0e6b8..dfd2c3cc8d7 100644 --- a/telegram/ext/_callbackcontext.py +++ b/telegram/ext/_callbackcontext.py @@ -29,6 +29,7 @@ NoReturn, Optional, Type, + TypeVar, Union, ) @@ -49,6 +50,9 @@ "/wiki/Storing-bot%2C-user-and-chat-related-data" ) +# something like poor mans "typing.Self" for py<3.11 +ST = TypeVar("ST", bound="CallbackContext[Any, Any, Any, Any]") + class CallbackContext(Generic[BT, UD, CD, BD]): """ @@ -133,24 +137,24 @@ class CallbackContext(Generic[BT, UD, CD, BD]): ) def __init__( - self: "CCT", - application: "Application[BT, CCT, UD, CD, BD, Any]", + self: ST, + application: "Application[BT, ST, UD, CD, BD, Any]", chat_id: Optional[int] = None, user_id: Optional[int] = None, ): - self._application: Application[BT, CCT, UD, CD, BD, Any] = application + self._application: Application[BT, ST, UD, CD, BD, Any] = application self._chat_id: Optional[int] = chat_id self._user_id: Optional[int] = user_id self.args: Optional[List[str]] = None self.matches: Optional[List[Match[str]]] = None self.error: Optional[Exception] = None - self.job: Optional[Job[CCT]] = None + self.job: Optional[Job[Any]] = None self.coroutine: Optional[ Union[Generator[Optional[Future[object]], None, Any], Awaitable[Any]] ] = None @property - def application(self) -> "Application[BT, CCT, UD, CD, BD, Any]": + def application(self) -> "Application[BT, ST, UD, CD, BD, Any]": """:class:`telegram.ext.Application`: The application associated with this context.""" return self._application @@ -398,7 +402,7 @@ def bot(self) -> BT: return self._application.bot @property - def job_queue(self) -> Optional["JobQueue[CCT]"]: + def job_queue(self) -> Optional["JobQueue[ST]"]: """ :class:`telegram.ext.JobQueue`: The :class:`JobQueue` used by the :class:`telegram.ext.Application`. diff --git a/telegram/ext/_handlers/basehandler.py b/telegram/ext/_handlers/basehandler.py index ea0d9b1640f..bf6f5f155df 100644 --- a/telegram/ext/_handlers/basehandler.py +++ b/telegram/ext/_handlers/basehandler.py @@ -32,14 +32,14 @@ UT = TypeVar("UT") -class BaseHandler(Generic[UT, CCT], ABC): +class BaseHandler(Generic[UT, CCT, RT], ABC): """The base class for all update handlers. Create custom handlers by inheriting from it. Warning: When setting :paramref:`block` to :obj:`False`, you cannot rely on adding custom attributes to :class:`telegram.ext.CallbackContext`. See its docs for more info. - This class is a :class:`~typing.Generic` class and accepts two type variables: + This class is a :class:`~typing.Generic` class and accepts three type variables: 1. The type of the updates that this handler will handle. Must coincide with the type of the first argument of :paramref:`callback`. :meth:`check_update` must only accept @@ -54,6 +54,7 @@ class BaseHandler(Generic[UT, CCT], ABC): For this type variable, one should usually provide a :class:`~typing.TypeVar` that is also used for the mentioned method arguments. That way, a type checker can check whether this handler fits the definition of the :class:`~Application`. + 3. The return type of the :paramref:`callback` function accepted by this handler. .. seealso:: :wiki:`Types of Handlers ` @@ -89,7 +90,7 @@ async def callback(update: Update, context: CallbackContext) ) def __init__( - self, + self: "BaseHandler[UT, CCT, RT]", callback: HandlerCallback[UT, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, ): diff --git a/telegram/ext/_handlers/businessconnectionhandler.py b/telegram/ext/_handlers/businessconnectionhandler.py index c8cb3e843d0..e5d09c77cf1 100644 --- a/telegram/ext/_handlers/businessconnectionhandler.py +++ b/telegram/ext/_handlers/businessconnectionhandler.py @@ -29,7 +29,7 @@ RT = TypeVar("RT") -class BusinessConnectionHandler(BaseHandler[Update, CCT]): +class BusinessConnectionHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`Business Connections `. @@ -65,7 +65,7 @@ async def callback(update: Update, context: CallbackContext) ) def __init__( - self, + self: "BusinessConnectionHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], user_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/businessmessagesdeletedhandler.py b/telegram/ext/_handlers/businessmessagesdeletedhandler.py index 0ceb58fe05c..c041bb0adc0 100644 --- a/telegram/ext/_handlers/businessmessagesdeletedhandler.py +++ b/telegram/ext/_handlers/businessmessagesdeletedhandler.py @@ -29,7 +29,7 @@ RT = TypeVar("RT") -class BusinessMessagesDeletedHandler(BaseHandler[Update, CCT]): +class BusinessMessagesDeletedHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle :attr:`deleted Telegram Business messages `. @@ -65,7 +65,7 @@ async def callback(update: Update, context: CallbackContext) ) def __init__( - self, + self: "BusinessMessagesDeletedHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/callbackqueryhandler.py b/telegram/ext/_handlers/callbackqueryhandler.py index a149739a2fb..5e0a0a12aa0 100644 --- a/telegram/ext/_handlers/callbackqueryhandler.py +++ b/telegram/ext/_handlers/callbackqueryhandler.py @@ -33,7 +33,7 @@ RT = TypeVar("RT") -class CallbackQueryHandler(BaseHandler[Update, CCT]): +class CallbackQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`callback queries `. Optionally based on a regex. @@ -125,7 +125,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("game_pattern", "pattern") def __init__( - self, + self: "CallbackQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], pattern: Optional[ Union[str, Pattern[str], type, Callable[[object], Optional[bool]]] diff --git a/telegram/ext/_handlers/chatboosthandler.py b/telegram/ext/_handlers/chatboosthandler.py index 9d7219632a1..7a2dd1be6a6 100644 --- a/telegram/ext/_handlers/chatboosthandler.py +++ b/telegram/ext/_handlers/chatboosthandler.py @@ -23,10 +23,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler from telegram.ext._utils._update_parsing import parse_chat_id, parse_username -from telegram.ext._utils.types import CCT, HandlerCallback +from telegram.ext._utils.types import CCT, RT, HandlerCallback -class ChatBoostHandler(BaseHandler[Update, CCT]): +class ChatBoostHandler(BaseHandler[Update, CCT, RT]): """ Handler class to handle Telegram updates that contain a chat boost. @@ -84,8 +84,8 @@ async def callback(update: Update, context: CallbackContext) and :attr:`telegram.Update.removed_chat_boost`.""" def __init__( - self, - callback: HandlerCallback[Update, CCT, None], + self: "ChatBoostHandler[CCT, RT]", + callback: HandlerCallback[Update, CCT, RT], chat_boost_types: int = CHAT_BOOST, chat_id: Optional[int] = None, chat_username: Optional[str] = None, diff --git a/telegram/ext/_handlers/chatjoinrequesthandler.py b/telegram/ext/_handlers/chatjoinrequesthandler.py index 7007f61ab03..04576e63c32 100644 --- a/telegram/ext/_handlers/chatjoinrequesthandler.py +++ b/telegram/ext/_handlers/chatjoinrequesthandler.py @@ -28,7 +28,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback -class ChatJoinRequestHandler(BaseHandler[Update, CCT]): +class ChatJoinRequestHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain :attr:`telegram.Update.chat_join_request`. @@ -81,7 +81,7 @@ async def callback(update: Update, context: CallbackContext) ) def __init__( - self, + self: "ChatJoinRequestHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/chatmemberhandler.py b/telegram/ext/_handlers/chatmemberhandler.py index 592361b64c5..cf8bb28db10 100644 --- a/telegram/ext/_handlers/chatmemberhandler.py +++ b/telegram/ext/_handlers/chatmemberhandler.py @@ -29,7 +29,7 @@ RT = TypeVar("RT") -class ChatMemberHandler(BaseHandler[Update, CCT]): +class ChatMemberHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a chat member update. Warning: @@ -87,7 +87,7 @@ async def callback(update: Update, context: CallbackContext) and :attr:`telegram.Update.chat_member`.""" def __init__( - self, + self: "ChatMemberHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_member_types: int = MY_CHAT_MEMBER, block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/choseninlineresulthandler.py b/telegram/ext/_handlers/choseninlineresulthandler.py index db7a8721448..feac28ba658 100644 --- a/telegram/ext/_handlers/choseninlineresulthandler.py +++ b/telegram/ext/_handlers/choseninlineresulthandler.py @@ -32,7 +32,7 @@ from telegram.ext import Application -class ChosenInlineResultHandler(BaseHandler[Update, CCT]): +class ChosenInlineResultHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain :attr:`telegram.Update.chosen_inline_result`. @@ -76,7 +76,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("pattern",) def __init__( - self, + self: "ChosenInlineResultHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, pattern: Optional[Union[str, Pattern[str]]] = None, diff --git a/telegram/ext/_handlers/commandhandler.py b/telegram/ext/_handlers/commandhandler.py index edad3963aad..54d01acd6d0 100644 --- a/telegram/ext/_handlers/commandhandler.py +++ b/telegram/ext/_handlers/commandhandler.py @@ -33,7 +33,7 @@ RT = TypeVar("RT") -class CommandHandler(BaseHandler[Update, CCT]): +class CommandHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram commands. Commands are Telegram messages that start with ``/``, optionally followed by an ``@`` and the @@ -118,7 +118,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("commands", "filters", "has_args") def __init__( - self, + self: "CommandHandler[CCT, RT]", command: SCT[str], callback: HandlerCallback[Update, CCT, RT], filters: Optional[filters_module.BaseFilter] = None, diff --git a/telegram/ext/_handlers/conversationhandler.py b/telegram/ext/_handlers/conversationhandler.py index f3fad9f8324..83fa373fc61 100644 --- a/telegram/ext/_handlers/conversationhandler.py +++ b/telegram/ext/_handlers/conversationhandler.py @@ -55,7 +55,7 @@ if TYPE_CHECKING: from telegram.ext import Application, Job, JobQueue -_CheckUpdateType = Tuple[object, ConversationKey, BaseHandler[Update, CCT], object] +_CheckUpdateType = Tuple[object, ConversationKey, BaseHandler[Update, CCT, object], object] _LOGGER = get_logger(__name__, class_name="ConversationHandler") @@ -119,7 +119,7 @@ def resolve(self) -> object: return res -class ConversationHandler(BaseHandler[Update, CCT]): +class ConversationHandler(BaseHandler[Update, CCT, object]): """ A handler to hold a conversation with a single or multiple users through Telegram updates by managing three collections of other handlers. @@ -296,10 +296,10 @@ class ConversationHandler(BaseHandler[Update, CCT]): # pylint: disable=super-init-not-called def __init__( - self, - entry_points: List[BaseHandler[Update, CCT]], - states: Dict[object, List[BaseHandler[Update, CCT]]], - fallbacks: List[BaseHandler[Update, CCT]], + self: "ConversationHandler[CCT]", + entry_points: List[BaseHandler[Update, CCT, object]], + states: Dict[object, List[BaseHandler[Update, CCT, object]]], + fallbacks: List[BaseHandler[Update, CCT, object]], allow_reentry: bool = False, per_chat: bool = True, per_user: bool = True, @@ -324,9 +324,9 @@ def __init__( # Store the actual setting in a protected variable instead self._block: DVType[bool] = block - self._entry_points: List[BaseHandler[Update, CCT]] = entry_points - self._states: Dict[object, List[BaseHandler[Update, CCT]]] = states - self._fallbacks: List[BaseHandler[Update, CCT]] = fallbacks + self._entry_points: List[BaseHandler[Update, CCT, object]] = entry_points + self._states: Dict[object, List[BaseHandler[Update, CCT, object]]] = states + self._fallbacks: List[BaseHandler[Update, CCT, object]] = fallbacks self._allow_reentry: bool = allow_reentry self._per_user: bool = per_user @@ -359,7 +359,7 @@ def __init__( stacklevel=2, ) - all_handlers: List[BaseHandler[Update, CCT]] = [] + all_handlers: List[BaseHandler[Update, CCT, object]] = [] all_handlers.extend(entry_points) all_handlers.extend(fallbacks) @@ -466,7 +466,7 @@ def __repr__(self) -> str: ) @property - def entry_points(self) -> List[BaseHandler[Update, CCT]]: + def entry_points(self) -> List[BaseHandler[Update, CCT, object]]: """List[:class:`telegram.ext.BaseHandler`]: A list of :obj:`BaseHandler` objects that can trigger the start of the conversation. """ @@ -479,7 +479,7 @@ def entry_points(self, _: object) -> NoReturn: ) @property - def states(self) -> Dict[object, List[BaseHandler[Update, CCT]]]: + def states(self) -> Dict[object, List[BaseHandler[Update, CCT, object]]]: """Dict[:obj:`object`, List[:class:`telegram.ext.BaseHandler`]]: A :obj:`dict` that defines the different states of conversation a user can be in and one or more associated :obj:`BaseHandler` objects that should be used in that state. @@ -491,7 +491,7 @@ def states(self, _: object) -> NoReturn: raise AttributeError("You can not assign a new value to states after initialization.") @property - def fallbacks(self) -> List[BaseHandler[Update, CCT]]: + def fallbacks(self) -> List[BaseHandler[Update, CCT, object]]: """List[:class:`telegram.ext.BaseHandler`]: A list of handlers that might be used if the user is in a conversation, but every handler for their current state returned :obj:`False` on :meth:`check_update`. diff --git a/telegram/ext/_handlers/inlinequeryhandler.py b/telegram/ext/_handlers/inlinequeryhandler.py index 21a5925cb1d..9d2cbb710b2 100644 --- a/telegram/ext/_handlers/inlinequeryhandler.py +++ b/telegram/ext/_handlers/inlinequeryhandler.py @@ -32,7 +32,7 @@ RT = TypeVar("RT") -class InlineQueryHandler(BaseHandler[Update, CCT]): +class InlineQueryHandler(BaseHandler[Update, CCT, RT]): """ BaseHandler class to handle Telegram updates that contain a :attr:`telegram.Update.inline_query`. @@ -87,7 +87,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("chat_types", "pattern") def __init__( - self, + self: "InlineQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], pattern: Optional[Union[str, Pattern[str]]] = None, block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/messagehandler.py b/telegram/ext/_handlers/messagehandler.py index 0cd42884ba6..43d8c8d8115 100644 --- a/telegram/ext/_handlers/messagehandler.py +++ b/telegram/ext/_handlers/messagehandler.py @@ -32,7 +32,7 @@ RT = TypeVar("RT") -class MessageHandler(BaseHandler[Update, CCT]): +class MessageHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram messages. They might contain text, media or status updates. @@ -75,7 +75,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("filters",) def __init__( - self, + self: "MessageHandler[CCT, RT]", filters: Optional[filters_module.BaseFilter], callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/messagereactionhandler.py b/telegram/ext/_handlers/messagereactionhandler.py index 4b52a17a8ab..34a5292be96 100644 --- a/telegram/ext/_handlers/messagereactionhandler.py +++ b/telegram/ext/_handlers/messagereactionhandler.py @@ -28,7 +28,7 @@ from telegram.ext._utils.types import CCT, HandlerCallback -class MessageReactionHandler(BaseHandler[Update, CCT]): +class MessageReactionHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a message reaction. Note: @@ -110,7 +110,7 @@ async def callback(update: Update, context: CallbackContext) and :attr:`telegram.Update.message_reaction_count`.""" def __init__( - self, + self: "MessageReactionHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], chat_id: Optional[SCT[int]] = None, chat_username: Optional[SCT[str]] = None, diff --git a/telegram/ext/_handlers/pollanswerhandler.py b/telegram/ext/_handlers/pollanswerhandler.py index 91e8df82b70..5e0bb34dbea 100644 --- a/telegram/ext/_handlers/pollanswerhandler.py +++ b/telegram/ext/_handlers/pollanswerhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class PollAnswerHandler(BaseHandler[Update, CCT]): +class PollAnswerHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a :attr:`poll answer `. diff --git a/telegram/ext/_handlers/pollhandler.py b/telegram/ext/_handlers/pollhandler.py index fb183c53805..6bb41c3237e 100644 --- a/telegram/ext/_handlers/pollhandler.py +++ b/telegram/ext/_handlers/pollhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class PollHandler(BaseHandler[Update, CCT]): +class PollHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram updates that contain a :attr:`poll `. diff --git a/telegram/ext/_handlers/precheckoutqueryhandler.py b/telegram/ext/_handlers/precheckoutqueryhandler.py index 3c6f3f186df..de035364ec9 100644 --- a/telegram/ext/_handlers/precheckoutqueryhandler.py +++ b/telegram/ext/_handlers/precheckoutqueryhandler.py @@ -31,7 +31,7 @@ RT = TypeVar("RT") -class PreCheckoutQueryHandler(BaseHandler[Update, CCT]): +class PreCheckoutQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`telegram.Update.pre_checkout_query`. Warning: @@ -73,7 +73,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("pattern",) def __init__( - self, + self: "PreCheckoutQueryHandler[CCT, RT]", callback: HandlerCallback[Update, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, pattern: Optional[Union[str, Pattern[str]]] = None, diff --git a/telegram/ext/_handlers/prefixhandler.py b/telegram/ext/_handlers/prefixhandler.py index 3b10a0a1caf..bda265e1056 100644 --- a/telegram/ext/_handlers/prefixhandler.py +++ b/telegram/ext/_handlers/prefixhandler.py @@ -33,7 +33,7 @@ RT = TypeVar("RT") -class PrefixHandler(BaseHandler[Update, CCT]): +class PrefixHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle custom prefix commands. This is an intermediate handler between :class:`MessageHandler` and :class:`CommandHandler`. @@ -123,7 +123,7 @@ async def callback(update: Update, context: CallbackContext) __slots__ = ("commands", "filters") def __init__( - self, + self: "PrefixHandler[CCT, RT]", prefix: SCT[str], command: SCT[str], callback: HandlerCallback[Update, CCT, RT], diff --git a/telegram/ext/_handlers/shippingqueryhandler.py b/telegram/ext/_handlers/shippingqueryhandler.py index f0234c2a962..c186513093a 100644 --- a/telegram/ext/_handlers/shippingqueryhandler.py +++ b/telegram/ext/_handlers/shippingqueryhandler.py @@ -21,10 +21,10 @@ from telegram import Update from telegram.ext._handlers.basehandler import BaseHandler -from telegram.ext._utils.types import CCT +from telegram.ext._utils.types import CCT, RT -class ShippingQueryHandler(BaseHandler[Update, CCT]): +class ShippingQueryHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`telegram.Update.shipping_query`. Warning: diff --git a/telegram/ext/_handlers/stringcommandhandler.py b/telegram/ext/_handlers/stringcommandhandler.py index d5c29bf6639..ff655d9d6c4 100644 --- a/telegram/ext/_handlers/stringcommandhandler.py +++ b/telegram/ext/_handlers/stringcommandhandler.py @@ -29,7 +29,7 @@ from telegram.ext import Application -class StringCommandHandler(BaseHandler[str, CCT]): +class StringCommandHandler(BaseHandler[str, CCT, RT]): """Handler class to handle string commands. Commands are string updates that start with ``/``. The handler will add a :obj:`list` to the :class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings, @@ -71,7 +71,7 @@ async def callback(update: str, context: CallbackContext) __slots__ = ("command",) def __init__( - self, + self: "StringCommandHandler[CCT, RT]", command: str, callback: HandlerCallback[str, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/stringregexhandler.py b/telegram/ext/_handlers/stringregexhandler.py index c2e22c10655..bd97469495a 100644 --- a/telegram/ext/_handlers/stringregexhandler.py +++ b/telegram/ext/_handlers/stringregexhandler.py @@ -32,7 +32,7 @@ RT = TypeVar("RT") -class StringRegexHandler(BaseHandler[str, CCT]): +class StringRegexHandler(BaseHandler[str, CCT, RT]): """Handler class to handle string updates based on a regex which checks the update content. Read the documentation of the :mod:`re` module for more information. The :func:`re.match` @@ -74,7 +74,7 @@ async def callback(update: str, context: CallbackContext) __slots__ = ("pattern",) def __init__( - self, + self: "StringRegexHandler[CCT, RT]", pattern: Union[str, Pattern[str]], callback: HandlerCallback[str, CCT, RT], block: DVType[bool] = DEFAULT_TRUE, diff --git a/telegram/ext/_handlers/typehandler.py b/telegram/ext/_handlers/typehandler.py index 151a7fbf137..48a4530bcfa 100644 --- a/telegram/ext/_handlers/typehandler.py +++ b/telegram/ext/_handlers/typehandler.py @@ -29,7 +29,7 @@ UT = TypeVar("UT") -class TypeHandler(BaseHandler[UT, CCT]): +class TypeHandler(BaseHandler[UT, CCT, RT]): """Handler class to handle updates of custom types. Warning: @@ -70,7 +70,7 @@ async def callback(update: object, context: CallbackContext) __slots__ = ("strict", "type") def __init__( - self, + self: "TypeHandler[UT, CCT, RT]", type: Type[UT], # pylint: disable=redefined-builtin callback: HandlerCallback[UT, CCT, RT], strict: bool = False, From 9248c539d08468f6a689a1530c72418b4c84eba6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Sep 2024 08:17:31 +0200 Subject: [PATCH 7/9] Bump `pytest` from 8.3.2 to 8.3.3 (#4475) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements-unit-tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-unit-tests.txt b/requirements-unit-tests.txt index df1e83b4573..49c382392c8 100644 --- a/requirements-unit-tests.txt +++ b/requirements-unit-tests.txt @@ -4,7 +4,7 @@ build # For the test suite -pytest==8.3.2 +pytest==8.3.3 # needed because pytest doesn't come with native support for coroutines as tests pytest-asyncio==0.21.2 From 67a97ae5a7e5225c988abb5d2242b13bfe2ddfbd Mon Sep 17 00:00:00 2001 From: Harshil <37377066+harshil21@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:09:19 -0400 Subject: [PATCH 8/9] API 7.10 (#4461, #4460, #4463, #4464) Co-authored-by: aelkheir <90580077+aelkheir@users.noreply.github.com> Co-authored-by: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> --- README.rst | 4 +- docs/source/telegram.at-tree.rst | 1 + docs/source/telegram.ext.handlers-tree.rst | 1 + ...telegram.ext.paidmediapurchasedhandler.rst | 6 + docs/source/telegram.paidmediapurchased.rst | 6 + telegram/__init__.py | 10 +- telegram/_bot.py | 10 +- telegram/_chat.py | 2 + telegram/_chatboost.py | 21 ++- telegram/_giveaway.py | 60 ++++++- telegram/_paidmedia.py | 50 ++++++ telegram/_payment/stars.py | 15 +- telegram/_update.py | 33 +++- telegram/constants.py | 133 ++++++++------ telegram/ext/__init__.py | 2 + telegram/ext/_extbot.py | 2 + .../_handlers/paidmediapurchasedhandler.py | 95 ++++++++++ tests/README.rst | 2 +- tests/ext/test_paidmediapurchasedhandler.py | 169 ++++++++++++++++++ tests/test_chat.py | 5 +- tests/test_chatboost.py | 2 + tests/test_giveaway.py | 46 ++++- tests/test_message.py | 2 +- tests/test_paidmedia.py | 61 +++++++ tests/test_stars.py | 1 + tests/test_update.py | 10 ++ 26 files changed, 668 insertions(+), 81 deletions(-) create mode 100644 docs/source/telegram.ext.paidmediapurchasedhandler.rst create mode 100644 docs/source/telegram.paidmediapurchased.rst create mode 100644 telegram/ext/_handlers/paidmediapurchasedhandler.py create mode 100644 tests/ext/test_paidmediapurchasedhandler.py diff --git a/README.rst b/README.rst index 605942c0691..4c7cba54347 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ :target: https://pypi.org/project/python-telegram-bot/ :alt: Supported Python versions -.. image:: https://img.shields.io/badge/Bot%20API-7.9-blue?logo=telegram +.. image:: https://img.shields.io/badge/Bot%20API-7.10-blue?logo=telegram :target: https://core.telegram.org/bots/api-changelog :alt: Supported Bot API version @@ -81,7 +81,7 @@ After installing_ the library, be sure to check out the section on `working with Telegram API support ~~~~~~~~~~~~~~~~~~~~ -All types and methods of the Telegram Bot API **7.9** are natively supported by this library. +All types and methods of the Telegram Bot API **7.10** are natively supported by this library. In addition, Bot API functionality not yet natively included can still be used as described `in our wiki `_. Notable Features diff --git a/docs/source/telegram.at-tree.rst b/docs/source/telegram.at-tree.rst index bb6e4c81472..f40223391fc 100644 --- a/docs/source/telegram.at-tree.rst +++ b/docs/source/telegram.at-tree.rst @@ -120,6 +120,7 @@ Available Types telegram.paidmediainfo telegram.paidmediaphoto telegram.paidmediapreview + telegram.paidmediapurchased telegram.paidmediavideo telegram.photosize telegram.poll diff --git a/docs/source/telegram.ext.handlers-tree.rst b/docs/source/telegram.ext.handlers-tree.rst index 6749cacb9dd..72e0d824c53 100644 --- a/docs/source/telegram.ext.handlers-tree.rst +++ b/docs/source/telegram.ext.handlers-tree.rst @@ -18,6 +18,7 @@ Handlers telegram.ext.inlinequeryhandler telegram.ext.messagehandler telegram.ext.messagereactionhandler + telegram.ext.paidmediapurchasedhandler telegram.ext.pollanswerhandler telegram.ext.pollhandler telegram.ext.precheckoutqueryhandler diff --git a/docs/source/telegram.ext.paidmediapurchasedhandler.rst b/docs/source/telegram.ext.paidmediapurchasedhandler.rst new file mode 100644 index 00000000000..19bfbeea31e --- /dev/null +++ b/docs/source/telegram.ext.paidmediapurchasedhandler.rst @@ -0,0 +1,6 @@ +PaidMediaPurchasedHandler +========================= + +.. autoclass:: telegram.ext.PaidMediaPurchasedHandler + :members: + :show-inheritance: diff --git a/docs/source/telegram.paidmediapurchased.rst b/docs/source/telegram.paidmediapurchased.rst new file mode 100644 index 00000000000..80568ae405c --- /dev/null +++ b/docs/source/telegram.paidmediapurchased.rst @@ -0,0 +1,6 @@ +PaidMediaPurchased +================== + +.. autoclass:: telegram.PaidMediaPurchased + :members: + :show-inheritance: diff --git a/telegram/__init__.py b/telegram/__init__.py index 7b5803a3e9f..0ff15a7a9a4 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -180,6 +180,7 @@ "PaidMediaInfo", "PaidMediaPhoto", "PaidMediaPreview", + "PaidMediaPurchased", "PaidMediaVideo", "PassportData", "PassportElementError", @@ -419,7 +420,14 @@ MessageOriginUser, ) from ._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated -from ._paidmedia import PaidMedia, PaidMediaInfo, PaidMediaPhoto, PaidMediaPreview, PaidMediaVideo +from ._paidmedia import ( + PaidMedia, + PaidMediaInfo, + PaidMediaPhoto, + PaidMediaPreview, + PaidMediaPurchased, + PaidMediaVideo, +) from ._passport.credentials import ( Credentials, DataCredentials, diff --git a/telegram/_bot.py b/telegram/_bot.py index b79df08ff17..62f25125c3a 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -9193,6 +9193,7 @@ async def send_paid_media( reply_parameters: Optional["ReplyParameters"] = None, reply_markup: Optional[ReplyMarkup] = None, business_connection_id: Optional[str] = None, + payload: Optional[str] = None, *, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, reply_to_message_id: Optional[int] = None, @@ -9211,9 +9212,15 @@ async def send_paid_media( Telegram Star proceeds from this media will be credited to the chat's balance. Otherwise, they will be credited to the bot's balance. star_count (:obj:`int`): The number of Telegram Stars that must be paid to buy access - to the media. + to the media; :tg-const:`telegram.constants.InvoiceLimit.MIN_STAR_COUNT` - + :tg-const:`telegram.constants.InvoiceLimit.MAX_STAR_COUNT`. media (Sequence[:class:`telegram.InputPaidMedia`]): A list describing the media to be sent; up to :tg-const:`telegram.constants.MediaGroupLimit.MAX_MEDIA_LENGTH` items. + payload (:obj:`str`, optional): Bot-defined paid media payload, + 0-:tg-const:`telegram.constants.InvoiceLimit.MAX_PAYLOAD_LENGTH` bytes. This will + not be displayed to the user, use it for your internal processes. + + .. versionadded:: NEXT.VERSION caption (:obj:`str`, optional): Caption of the media to be sent, 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters. parse_mode (:obj:`str`, optional): |parse_mode| @@ -9252,6 +9259,7 @@ async def send_paid_media( "star_count": star_count, "media": media, "show_caption_above_media": show_caption_above_media, + "payload": payload, } return await self._send_message( diff --git a/telegram/_chat.py b/telegram/_chat.py index 6eb78978596..8c5f705248e 100644 --- a/telegram/_chat.py +++ b/telegram/_chat.py @@ -3350,6 +3350,7 @@ async def send_paid_media( reply_parameters: Optional["ReplyParameters"] = None, reply_markup: Optional[ReplyMarkup] = None, business_connection_id: Optional[str] = None, + payload: Optional[str] = None, *, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, reply_to_message_id: Optional[int] = None, @@ -3391,6 +3392,7 @@ async def send_paid_media( pool_timeout=pool_timeout, api_kwargs=api_kwargs, business_connection_id=business_connection_id, + payload=payload, ) diff --git a/telegram/_chatboost.py b/telegram/_chatboost.py index 7b972eec6d8..c39537442e5 100644 --- a/telegram/_chatboost.py +++ b/telegram/_chatboost.py @@ -187,15 +187,22 @@ def __init__(self, user: User, *, api_kwargs: Optional[JSONDict] = None): class ChatBoostSourceGiveaway(ChatBoostSource): """ - The boost was obtained by the creation of a Telegram Premium giveaway. This boosts the chat 4 - times for the duration of the corresponding Telegram Premium subscription. + The boost was obtained by the creation of a Telegram Premium giveaway or a Telegram Star. + This boosts the chat 4 times for the duration of the corresponding Telegram Premium + subscription for Telegram Premium giveaways and :attr:`prize_star_count` / 500 times for + one year for Telegram Star giveaways. .. versionadded:: 20.8 Args: giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway; the message could have been deleted already. May be 0 if the message isn't sent yet. - user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any. + user (:class:`telegram.User`, optional): User that won the prize in the giveaway if any; + for Telegram Premium giveaways only. + prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but there was no user to win the prize. @@ -205,17 +212,22 @@ class ChatBoostSourceGiveaway(ChatBoostSource): giveaway_message_id (:obj:`int`): Identifier of a message in the chat with the giveaway; the message could have been deleted already. May be 0 if the message isn't sent yet. user (:class:`telegram.User`): Optional. User that won the prize in the giveaway if any. + prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but there was no user to win the prize. """ - __slots__ = ("giveaway_message_id", "is_unclaimed", "user") + __slots__ = ("giveaway_message_id", "is_unclaimed", "prize_star_count", "user") def __init__( self, giveaway_message_id: int, user: Optional[User] = None, is_unclaimed: Optional[bool] = None, + prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -224,6 +236,7 @@ def __init__( with self._unfrozen(): self.giveaway_message_id: int = giveaway_message_id self.user: Optional[User] = user + self.prize_star_count: Optional[int] = prize_star_count self.is_unclaimed: Optional[bool] = is_unclaimed diff --git a/telegram/_giveaway.py b/telegram/_giveaway.py index b287433fe0b..a482f4757ed 100644 --- a/telegram/_giveaway.py +++ b/telegram/_giveaway.py @@ -56,8 +56,13 @@ class Giveaway(TelegramObject): country codes indicating the countries from which eligible users for the giveaway must come. If empty, then all users can participate in the giveaway. Users with a phone number that was bought on Fragment can always participate in giveaways. + prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram - Premium subscription won from the giveaway will be active for. + Premium subscription won from the giveaway will be active for; for Telegram Premium + giveaways only. Attributes: chats (Sequence[:class:`telegram.Chat`]): The list of chats which the user must join to @@ -75,8 +80,13 @@ class Giveaway(TelegramObject): country codes indicating the countries from which eligible users for the giveaway must come. If empty, then all users can participate in the giveaway. Users with a phone number that was bought on Fragment can always participate in giveaways. + prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram - Premium subscription won from the giveaway will be active for. + Premium subscription won from the giveaway will be active for; for Telegram Premium + giveaways only. """ __slots__ = ( @@ -86,6 +96,7 @@ class Giveaway(TelegramObject): "only_new_members", "premium_subscription_month_count", "prize_description", + "prize_star_count", "winner_count", "winners_selection_date", ) @@ -100,6 +111,7 @@ def __init__( prize_description: Optional[str] = None, country_codes: Optional[Sequence[str]] = None, premium_subscription_month_count: Optional[int] = None, + prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -113,6 +125,7 @@ def __init__( self.prize_description: Optional[str] = prize_description self.country_codes: Tuple[str, ...] = parse_sequence_arg(country_codes) self.premium_subscription_month_count: Optional[int] = premium_subscription_month_count + self.prize_star_count: Optional[int] = prize_star_count self._id_attrs = ( self.chats, @@ -145,13 +158,28 @@ def de_json( class GiveawayCreated(TelegramObject): """This object represents a service message about the creation of a scheduled giveaway. - Currently holds no information. + + Args: + prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be + split between giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION + + Attributes: + prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be + split between giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION + """ - __slots__ = () + __slots__ = ("prize_star_count",) - def __init__(self, *, api_kwargs: Optional[JSONDict] = None): + def __init__( + self, prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None + ): super().__init__(api_kwargs=api_kwargs) + self.prize_star_count: Optional[int] = prize_star_count self._freeze() @@ -173,6 +201,10 @@ class GiveawayWinners(TelegramObject): winner_count (:obj:`int`): Total number of winners in the giveaway winners (Sequence[:class:`telegram.User`]): List of up to :tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway + prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION additional_chat_count (:obj:`int`, optional): The number of other chats the user had to join in order to be eligible for the giveaway premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram @@ -194,6 +226,10 @@ class GiveawayWinners(TelegramObject): :tg-const:`telegram.constants.GiveawayLimit.MAX_WINNERS` winners of the giveaway additional_chat_count (:obj:`int`): Optional. The number of other chats the user had to join in order to be eligible for the giveaway + prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between + giveaway winners; for Telegram Star giveaways only. + + .. versionadded:: NEXT.VERSION premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes @@ -211,6 +247,7 @@ class GiveawayWinners(TelegramObject): "only_new_members", "premium_subscription_month_count", "prize_description", + "prize_star_count", "unclaimed_prize_count", "was_refunded", "winner_count", @@ -231,6 +268,7 @@ def __init__( only_new_members: Optional[bool] = None, was_refunded: Optional[bool] = None, prize_description: Optional[str] = None, + prize_star_count: Optional[int] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -247,6 +285,7 @@ def __init__( self.only_new_members: Optional[bool] = only_new_members self.was_refunded: Optional[bool] = was_refunded self.prize_description: Optional[str] = prize_description + self.prize_star_count: Optional[int] = prize_star_count self._id_attrs = ( self.chat, @@ -295,21 +334,29 @@ class GiveawayCompleted(TelegramObject): unclaimed_prize_count (:obj:`int`, optional): Number of undistributed prizes giveaway_message (:class:`telegram.Message`, optional): Message with the giveaway that was completed, if it wasn't deleted + is_star_giveaway (:obj:`bool`, optional): :obj:`True`, if the giveaway is a Telegram Star + giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway. + .. versionadded:: NEXT.VERSION Attributes: winner_count (:obj:`int`): Number of winners in the giveaway unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes giveaway_message (:class:`telegram.Message`): Optional. Message with the giveaway that was completed, if it wasn't deleted + is_star_giveaway (:obj:`bool`): Optional. :obj:`True`, if the giveaway is a Telegram Star + giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway. + + .. versionadded:: NEXT.VERSION """ - __slots__ = ("giveaway_message", "unclaimed_prize_count", "winner_count") + __slots__ = ("giveaway_message", "is_star_giveaway", "unclaimed_prize_count", "winner_count") def __init__( self, winner_count: int, unclaimed_prize_count: Optional[int] = None, giveaway_message: Optional["Message"] = None, + is_star_giveaway: Optional[bool] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -318,6 +365,7 @@ def __init__( self.winner_count: int = winner_count self.unclaimed_prize_count: Optional[int] = unclaimed_prize_count self.giveaway_message: Optional[Message] = giveaway_message + self.is_star_giveaway: Optional[bool] = is_star_giveaway self._id_attrs = ( self.winner_count, diff --git a/telegram/_paidmedia.py b/telegram/_paidmedia.py index fe78cca28e0..57126b13001 100644 --- a/telegram/_paidmedia.py +++ b/telegram/_paidmedia.py @@ -24,6 +24,7 @@ from telegram._files.photosize import PhotoSize from telegram._files.video import Video from telegram._telegramobject import TelegramObject +from telegram._user import User from telegram._utils import enum from telegram._utils.argumentparsing import parse_sequence_arg from telegram._utils.types import JSONDict @@ -288,3 +289,52 @@ def de_json( data["paid_media"] = PaidMedia.de_list(data.get("paid_media"), bot=bot) return super().de_json(data=data, bot=bot) + + +class PaidMediaPurchased(TelegramObject): + """This object contains information about a paid media purchase. + + Objects of this class are comparable in terms of equality. Two objects of this class are + considered equal, if their :attr:`from_user` and :attr:`paid_media_payload` are equal. + + Note: + In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. + + .. versionadded:: NEXT.VERSION + + Args: + from_user (:class:`telegram.User`): User who purchased the media. + paid_media_payload (:obj:`str`): Bot-specified paid media payload. + + Attributes: + from_user (:class:`telegram.User`): User who purchased the media. + paid_media_payload (:obj:`str`): Bot-specified paid media payload. + """ + + __slots__ = ("from_user", "paid_media_payload") + + def __init__( + self, + from_user: "User", + paid_media_payload: str, + *, + api_kwargs: Optional[JSONDict] = None, + ) -> None: + super().__init__(api_kwargs=api_kwargs) + self.from_user: User = from_user + self.paid_media_payload: str = paid_media_payload + + self._id_attrs = (self.from_user, self.paid_media_payload) + self._freeze() + + @classmethod + def de_json( + cls, data: Optional[JSONDict], bot: Optional["Bot"] = None + ) -> Optional["PaidMediaPurchased"]: + data = cls._parse_data(data) + + if not data: + return None + + data["from_user"] = User.de_json(data=data.pop("from"), bot=bot) + return super().de_json(data=data, bot=bot) diff --git a/telegram/_payment/stars.py b/telegram/_payment/stars.py index 94f621d00e8..2a3f1dca280 100644 --- a/telegram/_payment/stars.py +++ b/telegram/_payment/stars.py @@ -328,6 +328,9 @@ class TransactionPartnerUser(TransactionPartner): media bought by the user. .. versionadded:: 21.5 + paid_media_payload (:obj:`str`, optional): Optional. Bot-specified paid media payload. + + .. versionadded:: NEXT.VERSION Attributes: type (:obj:`str`): The type of the transaction partner, @@ -338,19 +341,20 @@ class TransactionPartnerUser(TransactionPartner): media bought by the user. .. versionadded:: 21.5 + paid_media_payload (:obj:`str`): Optional. Optional. Bot-specified paid media payload. + + .. versionadded:: NEXT.VERSION + """ - __slots__ = ( - "invoice_payload", - "paid_media", - "user", - ) + __slots__ = ("invoice_payload", "paid_media", "paid_media_payload", "user") def __init__( self, user: "User", invoice_payload: Optional[str] = None, paid_media: Optional[Sequence[PaidMedia]] = None, + paid_media_payload: Optional[str] = None, *, api_kwargs: Optional[JSONDict] = None, ) -> None: @@ -360,6 +364,7 @@ def __init__( self.user: User = user self.invoice_payload: Optional[str] = invoice_payload self.paid_media: Optional[Tuple[PaidMedia, ...]] = parse_sequence_arg(paid_media) + self.paid_media_payload: Optional[str] = paid_media_payload self._id_attrs = ( self.type, self.user, diff --git a/telegram/_update.py b/telegram/_update.py index 579cb008580..be4f2ec5812 100644 --- a/telegram/_update.py +++ b/telegram/_update.py @@ -30,6 +30,7 @@ from telegram._inline.inlinequery import InlineQuery from telegram._message import Message from telegram._messagereactionupdated import MessageReactionCountUpdated, MessageReactionUpdated +from telegram._paidmedia import PaidMediaPurchased from telegram._payment.precheckoutquery import PreCheckoutQuery from telegram._payment.shippingquery import ShippingQuery from telegram._poll import Poll, PollAnswer @@ -156,6 +157,11 @@ class Update(TelegramObject): .. versionadded:: 21.1 + purchased_paid_media (:class:`telegram.PaidMediaPurchased`, optional): A user purchased + paid media with a non-empty payload sent by the bot in a non-channel chat. + + .. versionadded:: NEXT.VERSION + Attributes: update_id (:obj:`int`): The update's unique identifier. Update identifiers start from a @@ -263,6 +269,11 @@ class Update(TelegramObject): were deleted from a connected business account. .. versionadded:: 21.1 + + purchased_paid_media (:class:`telegram.PaidMediaPurchased`): Optional. A user purchased + paid media with a non-empty payload sent by the bot in a non-channel chat. + + .. versionadded:: NEXT.VERSION """ __slots__ = ( @@ -290,6 +301,7 @@ class Update(TelegramObject): "poll", "poll_answer", "pre_checkout_query", + "purchased_paid_media", "removed_chat_boost", "shipping_query", "update_id", @@ -383,6 +395,13 @@ class Update(TelegramObject): """:const:`telegram.constants.UpdateType.DELETED_BUSINESS_MESSAGES` .. versionadded:: 21.1""" + + PURCHASED_PAID_MEDIA: Final[str] = constants.UpdateType.PURCHASED_PAID_MEDIA + """:const:`telegram.constants.UpdateType.PURCHASED_PAID_MEDIA` + + .. versionadded:: NEXT.VERSION + """ + ALL_TYPES: Final[List[str]] = list(constants.UpdateType) """List[:obj:`str`]: A list of all available update types. @@ -413,6 +432,7 @@ def __init__( business_message: Optional[Message] = None, edited_business_message: Optional[Message] = None, deleted_business_messages: Optional[BusinessMessagesDeleted] = None, + purchased_paid_media: Optional[PaidMediaPurchased] = None, *, api_kwargs: Optional[JSONDict] = None, ): @@ -444,6 +464,7 @@ def __init__( self.deleted_business_messages: Optional[BusinessMessagesDeleted] = ( deleted_business_messages ) + self.purchased_paid_media: Optional[PaidMediaPurchased] = purchased_paid_media self._effective_user: Optional[User] = None self._effective_sender: Optional[Union[User, Chat]] = None @@ -475,6 +496,9 @@ def effective_user(self) -> Optional["User"]: This property now also considers :attr:`business_connection`, :attr:`business_message` and :attr:`edited_business_message`. + .. versionchanged:: NEXT.VERSION + This property now also considers :attr:`purchased_paid_media`. + Example: * If :attr:`message` is present, this will give :attr:`telegram.Message.from_user`. @@ -531,6 +555,9 @@ def effective_user(self) -> Optional["User"]: elif self.business_connection: user = self.business_connection.user + elif self.purchased_paid_media: + user = self.purchased_paid_media.from_user + self._effective_user = user return user @@ -601,7 +628,8 @@ def effective_chat(self) -> Optional["Chat"]: This is the case, if :attr:`inline_query`, :attr:`chosen_inline_result`, :attr:`callback_query` from inline messages, :attr:`shipping_query`, :attr:`pre_checkout_query`, :attr:`poll`, - :attr:`poll_answer`, or :attr:`business_connection` is present. + :attr:`poll_answer`, :attr:`business_connection`, or :attr:`purchased_paid_media` + is present. .. versionchanged:: 21.1 This property now also considers :attr:`business_message`, @@ -768,5 +796,8 @@ def de_json(cls, data: Optional[JSONDict], bot: Optional["Bot"] = None) -> Optio data["deleted_business_messages"] = BusinessMessagesDeleted.de_json( data.get("deleted_business_messages"), bot ) + data["purchased_paid_media"] = PaidMediaPurchased.de_json( + data.get("purchased_paid_media"), bot + ) return super().de_json(data=data, bot=bot) diff --git a/telegram/constants.py b/telegram/constants.py index 52d69aacaef..4d95368ce9e 100644 --- a/telegram/constants.py +++ b/telegram/constants.py @@ -152,7 +152,7 @@ class _AccentColor(NamedTuple): #: :data:`telegram.__bot_api_version_info__`. #: #: .. versionadded:: 20.0 -BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=9) +BOT_API_VERSION_INFO: Final[_BotAPIVersion] = _BotAPIVersion(major=7, minor=10) #: :obj:`str`: Telegram Bot API #: version supported by this version of `python-telegram-bot`. Also available as #: :data:`telegram.__bot_api_version__`. @@ -552,6 +552,42 @@ class AccentColor(Enum): """ +class BackgroundTypeType(StringEnum): + """This enum contains the available types of :class:`telegram.BackgroundType`. The enum + members of this enumeration are instances of :class:`str` and can be treated as such. + + .. versionadded:: 21.2 + """ + + __slots__ = () + + FILL = "fill" + """:obj:`str`: A :class:`telegram.BackgroundType` with fill background.""" + WALLPAPER = "wallpaper" + """:obj:`str`: A :class:`telegram.BackgroundType` with wallpaper background.""" + PATTERN = "pattern" + """:obj:`str`: A :class:`telegram.BackgroundType` with pattern background.""" + CHAT_THEME = "chat_theme" + """:obj:`str`: A :class:`telegram.BackgroundType` with chat_theme background.""" + + +class BackgroundFillType(StringEnum): + """This enum contains the available types of :class:`telegram.BackgroundFill`. The enum + members of this enumeration are instances of :class:`str` and can be treated as such. + + .. versionadded:: 21.2 + """ + + __slots__ = () + + SOLID = "solid" + """:obj:`str`: A :class:`telegram.BackgroundFill` with solid fill.""" + GRADIENT = "gradient" + """:obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill.""" + FREEFORM_GRADIENT = "freeform_gradient" + """:obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill.""" + + class BotCommandLimit(IntEnum): """This enum contains limitations for :class:`telegram.BotCommand` and :meth:`telegram.Bot.set_my_commands`. @@ -833,6 +869,25 @@ class ChatLimit(IntEnum): """ +class ChatSubscriptionLimit(IntEnum): + """This enum contains limitations for + :paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_period` and + :paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_price`. + The enum members of this enumeration are instances of :class:`int` and can be treated as such. + + .. versionadded:: 21.5 + """ + + __slots__ = () + + SUBSCRIPTION_PERIOD = 2592000 + """:obj:`int`: The number of seconds the subscription will be active.""" + MIN_PRICE = 1 + """:obj:`int`: Amount of stars a user pays, minimum amount the subscription can be set to.""" + MAX_PRICE = 2500 + """:obj:`int`: Amount of stars a user pays, maximum amount the subscription can be set to.""" + + class BackgroundTypeLimit(IntEnum): """This enum contains limitations for :class:`telegram.BackgroundTypeFill`, :class:`telegram.BackgroundTypeWallpaper` and :class:`telegram.BackgroundTypePattern`. @@ -2724,6 +2779,11 @@ class UpdateType(StringEnum): .. versionadded:: 21.1 """ + PURCHASED_PAID_MEDIA = "purchased_paid_media" + """:obj:`str`: Updates with :attr:`telegram.Update.purchased_paid_media`. + + .. versionadded:: NEXT.VERSION + """ class InvoiceLimit(IntEnum): @@ -2795,6 +2855,8 @@ class InvoiceLimit(IntEnum): :meth:`telegram.Bot.send_invoice`. * :paramref:`~telegram.Bot.create_invoice_link.payload` parameter of :meth:`telegram.Bot.create_invoice_link`. + * :paramref:`~telegram.Bot.send_paid_media.payload` parameter of + :meth:`telegram.Bot.send_paid_media`. """ MAX_TIP_AMOUNTS = 4 """:obj:`int`: Maximum length of a :obj:`Sequence` passed as: @@ -2804,6 +2866,20 @@ class InvoiceLimit(IntEnum): * :paramref:`~telegram.Bot.create_invoice_link.suggested_tip_amounts` parameter of :meth:`telegram.Bot.create_invoice_link`. """ + MIN_STAR_COUNT = 1 + """:obj:`int`: Minimum amount of starts that must be paid to buy access to a paid media + passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of + :meth:`telegram.Bot.send_paid_media`. + + .. versionadded:: NEXT.VERSION + """ + MAX_STAR_COUNT = 2500 + """:obj:`int`: Maximum amount of starts that must be paid to buy access to a paid media + passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of + :meth:`telegram.Bot.send_paid_media`. + + .. versionadded:: NEXT.VERSION + """ class UserProfilePhotosLimit(IntEnum): @@ -3066,58 +3142,3 @@ class ReactionEmoji(StringEnum): """:obj:`str`: Woman Shrugging""" POUTING_FACE = "😡" """:obj:`str`: Pouting face""" - - -class BackgroundTypeType(StringEnum): - """This enum contains the available types of :class:`telegram.BackgroundType`. The enum - members of this enumeration are instances of :class:`str` and can be treated as such. - - .. versionadded:: 21.2 - """ - - __slots__ = () - - FILL = "fill" - """:obj:`str`: A :class:`telegram.BackgroundType` with fill background.""" - WALLPAPER = "wallpaper" - """:obj:`str`: A :class:`telegram.BackgroundType` with wallpaper background.""" - PATTERN = "pattern" - """:obj:`str`: A :class:`telegram.BackgroundType` with pattern background.""" - CHAT_THEME = "chat_theme" - """:obj:`str`: A :class:`telegram.BackgroundType` with chat_theme background.""" - - -class BackgroundFillType(StringEnum): - """This enum contains the available types of :class:`telegram.BackgroundFill`. The enum - members of this enumeration are instances of :class:`str` and can be treated as such. - - .. versionadded:: 21.2 - """ - - __slots__ = () - - SOLID = "solid" - """:obj:`str`: A :class:`telegram.BackgroundFill` with solid fill.""" - GRADIENT = "gradient" - """:obj:`str`: A :class:`telegram.BackgroundFill` with gradient fill.""" - FREEFORM_GRADIENT = "freeform_gradient" - """:obj:`str`: A :class:`telegram.BackgroundFill` with freeform_gradient fill.""" - - -class ChatSubscriptionLimit(IntEnum): - """This enum contains limitations for - :paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_period` and - :paramref:`telegram.Bot.create_chat_subscription_invite_link.subscription_price`. - The enum members of this enumeration are instances of :class:`int` and can be treated as such. - - .. versionadded:: 21.5 - """ - - __slots__ = () - - SUBSCRIPTION_PERIOD = 2592000 - """:obj:`int`: The number of seconds the subscription will be active.""" - MIN_PRICE = 1 - """:obj:`int`: Amount of stars a user pays, minimum amount the subscription can be set to.""" - MAX_PRICE = 2500 - """:obj:`int`: Amount of stars a user pays, maximum amount the subscription can be set to.""" diff --git a/telegram/ext/__init__.py b/telegram/ext/__init__.py index 82dbd1c19ad..432f742abf2 100644 --- a/telegram/ext/__init__.py +++ b/telegram/ext/__init__.py @@ -48,6 +48,7 @@ "JobQueue", "MessageHandler", "MessageReactionHandler", + "PaidMediaPurchasedHandler", "PersistenceInput", "PicklePersistence", "PollAnswerHandler", @@ -89,6 +90,7 @@ from ._handlers.inlinequeryhandler import InlineQueryHandler from ._handlers.messagehandler import MessageHandler from ._handlers.messagereactionhandler import MessageReactionHandler +from ._handlers.paidmediapurchasedhandler import PaidMediaPurchasedHandler from ._handlers.pollanswerhandler import PollAnswerHandler from ._handlers.pollhandler import PollHandler from ._handlers.precheckoutqueryhandler import PreCheckoutQueryHandler diff --git a/telegram/ext/_extbot.py b/telegram/ext/_extbot.py index 76b17bad02a..3d91acf0d4f 100644 --- a/telegram/ext/_extbot.py +++ b/telegram/ext/_extbot.py @@ -4235,6 +4235,7 @@ async def send_paid_media( reply_parameters: Optional["ReplyParameters"] = None, reply_markup: Optional[ReplyMarkup] = None, business_connection_id: Optional[str] = None, + payload: Optional[str] = None, *, allow_sending_without_reply: ODVInput[bool] = DEFAULT_NONE, reply_to_message_id: Optional[int] = None, @@ -4265,6 +4266,7 @@ async def send_paid_media( pool_timeout=pool_timeout, api_kwargs=self._merge_api_rl_kwargs(api_kwargs, rate_limit_args), business_connection_id=business_connection_id, + payload=payload, ) async def create_chat_subscription_invite_link( diff --git a/telegram/ext/_handlers/paidmediapurchasedhandler.py b/telegram/ext/_handlers/paidmediapurchasedhandler.py new file mode 100644 index 00000000000..13a7cf1230f --- /dev/null +++ b/telegram/ext/_handlers/paidmediapurchasedhandler.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2024 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +"""This module contains the PaidMediaPurchased class.""" + +from typing import Optional + +from telegram import Update +from telegram._utils.defaultvalue import DEFAULT_TRUE +from telegram._utils.types import SCT, DVType +from telegram.ext._handlers.basehandler import BaseHandler +from telegram.ext._utils._update_parsing import parse_chat_id, parse_username +from telegram.ext._utils.types import CCT, RT, HandlerCallback + + +class PaidMediaPurchasedHandler(BaseHandler[Update, CCT, RT]): + """Handler class to handle Telegram + :attr:`purchased paid media `. + + .. versionadded:: NEXT.VERSION + + Args: + callback (:term:`coroutine function`): The callback function for this handler. Will be + called when :meth:`check_update` has determined that an update should be processed by + this handler. Callback signature:: + + async def callback(update: Update, context: CallbackContext) + user_id (:obj:`int` | Collection[:obj:`int`], optional): Filters requests to allow only + those which are from the specified user ID(s). + + username (:obj:`str` | Collection[:obj:`str`], optional): Filters requests to allow only + those which are from the specified username(s). + + block (:obj:`bool`, optional): Determines whether the return value of the callback should + be awaited before processing the next handler in + :meth:`telegram.ext.Application.process_update`. Defaults to :obj:`True`. + + .. seealso:: :wiki:`Concurrency` + Attributes: + callback (:term:`coroutine function`): The callback function for this handler. + block (:obj:`bool`): Determines whether the return value of the callback should be + awaited before processing the next handler in + :meth:`telegram.ext.Application.process_update`. + """ + + __slots__ = ( + "_user_ids", + "_usernames", + ) + + def __init__( + self: "PaidMediaPurchasedHandler[CCT, RT]", + callback: HandlerCallback[Update, CCT, RT], + user_id: Optional[SCT[int]] = None, + username: Optional[SCT[str]] = None, + block: DVType[bool] = DEFAULT_TRUE, + ): + super().__init__(callback, block=block) + + self._user_ids = parse_chat_id(user_id) + self._usernames = parse_username(username) + + def check_update(self, update: object) -> bool: + """Determines whether an update should be passed to this handler's :attr:`callback`. + + Args: + update (:class:`telegram.Update` | :obj:`object`): Incoming update. + + Returns: + :obj:`bool` + + """ + if not isinstance(update, Update) or not update.purchased_paid_media: + return False + + if not self._user_ids and not self._usernames: + return True + if update.purchased_paid_media.from_user.id in self._user_ids: + return True + return update.purchased_paid_media.from_user.username in self._usernames diff --git a/tests/README.rst b/tests/README.rst index 69591953bc3..c9f3cac63be 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -72,7 +72,7 @@ complete and correct. To run it, export an environment variable first: $ export TEST_OFFICIAL=true -and then run ``pytest tests/test_official.py``. Note: You need py 3.10+ to run this test. +and then run ``pytest tests/test_official/test_official.py``. Note: You need py 3.10+ to run this test. We also have another marker, ``@pytest.mark.dev``, which you can add to tests that you want to run selectively. Use as follows: diff --git a/tests/ext/test_paidmediapurchasedhandler.py b/tests/ext/test_paidmediapurchasedhandler.py new file mode 100644 index 00000000000..959b9c30ce4 --- /dev/null +++ b/tests/ext/test_paidmediapurchasedhandler.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# A library that provides a Python interface to the Telegram Bot API +# Copyright (C) 2015-2024 +# Leandro Toledo de Souza +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser Public License for more details. +# +# You should have received a copy of the GNU Lesser Public License +# along with this program. If not, see [http://www.gnu.org/licenses/]. +import asyncio +import datetime + +import pytest + +from telegram import ( + Bot, + CallbackQuery, + Chat, + ChosenInlineResult, + Message, + PaidMediaPurchased, + PreCheckoutQuery, + ShippingQuery, + Update, + User, +) +from telegram._utils.datetime import UTC +from telegram.ext import CallbackContext, JobQueue, PaidMediaPurchasedHandler +from tests.auxil.slots import mro_slots + +message = Message(1, None, Chat(1, ""), from_user=User(1, "", False), text="Text") + +params = [ + {"message": message}, + {"edited_message": message}, + {"callback_query": CallbackQuery(1, User(1, "", False), "chat", message=message)}, + {"channel_post": message}, + {"edited_channel_post": message}, + {"chosen_inline_result": ChosenInlineResult("id", User(1, "", False), "")}, + {"shipping_query": ShippingQuery("id", User(1, "", False), "", None)}, + {"pre_checkout_query": PreCheckoutQuery("id", User(1, "", False), "", 0, "")}, + {"callback_query": CallbackQuery(1, User(1, "", False), "chat")}, +] + +ids = ( + "message", + "edited_message", + "callback_query", + "channel_post", + "edited_channel_post", + "chosen_inline_result", + "shipping_query", + "pre_checkout_query", + "callback_query_without_message", +) + + +@pytest.fixture(scope="class", params=params, ids=ids) +def false_update(request): + return Update(update_id=2, **request.param) + + +@pytest.fixture(scope="class") +def time(): + return datetime.datetime.now(tz=UTC) + + +@pytest.fixture(scope="class") +def purchased_paid_media(bot): + bc = PaidMediaPurchased( + from_user=User(1, "name", username="user_a", is_bot=False), + paid_media_payload="payload", + ) + bc.set_bot(bot) + return bc + + +@pytest.fixture +def purchased_paid_media_update(bot, purchased_paid_media): + return Update(0, purchased_paid_media=purchased_paid_media) + + +class TestPaidMediaPurchasedHandler: + test_flag = False + + def test_slot_behaviour(self): + action = PaidMediaPurchasedHandler(self.callback) + for attr in action.__slots__: + assert getattr(action, attr, "err") != "err", f"got extra slot '{attr}'" + assert len(mro_slots(action)) == len(set(mro_slots(action))), "duplicate slot" + + @pytest.fixture(autouse=True) + def _reset(self): + self.test_flag = False + + async def callback(self, update, context): + self.test_flag = ( + isinstance(context, CallbackContext) + and isinstance(context.bot, Bot) + and isinstance(update, Update) + and isinstance(context.update_queue, asyncio.Queue) + and isinstance(context.job_queue, JobQueue) + and isinstance(context.user_data, dict) + and isinstance(context.bot_data, dict) + and isinstance( + update.purchased_paid_media, + PaidMediaPurchased, + ) + ) + + def test_with_user_id(self, purchased_paid_media_update): + handler = PaidMediaPurchasedHandler(self.callback, user_id=1) + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, user_id=[1]) + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, user_id=2, username="@user_a") + assert handler.check_update(purchased_paid_media_update) + + handler = PaidMediaPurchasedHandler(self.callback, user_id=2) + assert not handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, user_id=[2]) + assert not handler.check_update(purchased_paid_media_update) + + def test_with_username(self, purchased_paid_media_update): + handler = PaidMediaPurchasedHandler(self.callback, username="user_a") + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username="@user_a") + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username=["user_a"]) + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username=["@user_a"]) + assert handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, user_id=1, username="@user_b") + assert handler.check_update(purchased_paid_media_update) + + handler = PaidMediaPurchasedHandler(self.callback, username="user_b") + assert not handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username="@user_b") + assert not handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username=["user_b"]) + assert not handler.check_update(purchased_paid_media_update) + handler = PaidMediaPurchasedHandler(self.callback, username=["@user_b"]) + assert not handler.check_update(purchased_paid_media_update) + + purchased_paid_media_update.purchased_paid_media.from_user._unfreeze() + purchased_paid_media_update.purchased_paid_media.from_user.username = None + assert not handler.check_update(purchased_paid_media_update) + + def test_other_update_types(self, false_update): + handler = PaidMediaPurchasedHandler(self.callback) + assert not handler.check_update(false_update) + assert not handler.check_update(True) + + async def test_context(self, app, purchased_paid_media_update): + handler = PaidMediaPurchasedHandler(callback=self.callback) + app.add_handler(handler) + + async with app: + await app.process_update(purchased_paid_media_update) + assert self.test_flag diff --git a/tests/test_chat.py b/tests/test_chat.py index adf2c42bc3c..966e820162e 100644 --- a/tests/test_chat.py +++ b/tests/test_chat.py @@ -1299,6 +1299,7 @@ async def make_assertion(*_, **kwargs): and kwargs["media"] == "media" and kwargs["star_count"] == 42 and kwargs["caption"] == "stars" + and kwargs["payload"] == "payload" ) assert check_shortcut_signature(Chat.send_paid_media, Bot.send_paid_media, ["chat_id"], []) @@ -1306,7 +1307,9 @@ async def make_assertion(*_, **kwargs): assert await check_defaults_handling(chat.send_paid_media, chat.get_bot()) monkeypatch.setattr(chat.get_bot(), "send_paid_media", make_assertion) - assert await chat.send_paid_media(media="media", star_count=42, caption="stars") + assert await chat.send_paid_media( + media="media", star_count=42, caption="stars", payload="payload" + ) def test_mention_html(self): chat = Chat(id=1, type="foo") diff --git a/tests/test_chatboost.py b/tests/test_chatboost.py index 62123df73dc..e160d8c8217 100644 --- a/tests/test_chatboost.py +++ b/tests/test_chatboost.py @@ -50,6 +50,7 @@ class ChatBoostDefaults: user = User(1, "user", False) date = to_timestamp(datetime.datetime.utcnow()) default_source = ChatBoostSourcePremium(user) + prize_star_count = 99 @pytest.fixture(scope="module") @@ -91,6 +92,7 @@ def chat_boost_source_giveaway(): user=ChatBoostDefaults.user, giveaway_message_id=ChatBoostDefaults.giveaway_message_id, is_unclaimed=ChatBoostDefaults.is_unclaimed, + prize_star_count=ChatBoostDefaults.prize_star_count, ) diff --git a/tests/test_giveaway.py b/tests/test_giveaway.py index 4aac4150c6a..3ef8bb7a1df 100644 --- a/tests/test_giveaway.py +++ b/tests/test_giveaway.py @@ -48,6 +48,7 @@ def giveaway(): premium_subscription_month_count=( TestGiveawayWithoutRequest.premium_subscription_month_count ), + prize_star_count=TestGiveawayWithoutRequest.prize_star_count, ) @@ -60,6 +61,7 @@ class TestGiveawayWithoutRequest: prize_description = "prize_description" country_codes = ["DE", "US"] premium_subscription_month_count = 3 + prize_star_count = 99 def test_slot_behaviour(self, giveaway): for attr in giveaway.__slots__: @@ -76,6 +78,7 @@ def test_de_json(self, offline_bot): "prize_description": self.prize_description, "country_codes": self.country_codes, "premium_subscription_month_count": self.premium_subscription_month_count, + "prize_star_count": self.prize_star_count, } giveaway = Giveaway.de_json(json_dict, offline_bot) @@ -89,6 +92,7 @@ def test_de_json(self, offline_bot): assert giveaway.prize_description == self.prize_description assert giveaway.country_codes == tuple(self.country_codes) assert giveaway.premium_subscription_month_count == self.premium_subscription_month_count + assert giveaway.prize_star_count == self.prize_star_count assert Giveaway.de_json(None, offline_bot) is None @@ -102,6 +106,7 @@ def test_de_json_localization(self, tz_bot, offline_bot, raw_bot): "prize_description": self.prize_description, "country_codes": self.country_codes, "premium_subscription_month_count": self.premium_subscription_month_count, + "prize_star_count": self.prize_star_count, } giveaway_raw = Giveaway.de_json(json_dict, raw_bot) @@ -133,6 +138,7 @@ def test_to_dict(self, giveaway): giveaway_dict["premium_subscription_month_count"] == self.premium_subscription_month_count ) + assert giveaway_dict["prize_star_count"] == self.prize_star_count def test_equality(self, giveaway): a = giveaway @@ -164,15 +170,40 @@ def test_equality(self, giveaway): assert hash(a) != hash(e) +@pytest.fixture(scope="module") +def giveaway_created(): + return GiveawayCreated( + prize_star_count=TestGiveawayCreatedWithoutRequest.prize_star_count, + ) + + class TestGiveawayCreatedWithoutRequest: - def test_slot_behaviour(self): - giveaway_created = GiveawayCreated() + prize_star_count = 99 + + def test_slot_behaviour(self, giveaway_created): for attr in giveaway_created.__slots__: assert getattr(giveaway_created, attr, "err") != "err", f"got extra slot '{attr}'" assert len(mro_slots(giveaway_created)) == len( set(mro_slots(giveaway_created)) ), "duplicate slot" + def test_de_json(self, bot): + json_dict = { + "prize_star_count": self.prize_star_count, + } + + gac = GiveawayCreated.de_json(json_dict, bot) + assert gac.api_kwargs == {} + assert gac.prize_star_count == self.prize_star_count + + assert Giveaway.de_json(None, bot) is None + + def test_to_dict(self, giveaway_created): + gac_dict = giveaway_created.to_dict() + + assert isinstance(gac_dict, dict) + assert gac_dict["prize_star_count"] == self.prize_star_count + @pytest.fixture(scope="module") def giveaway_winners(): @@ -190,6 +221,7 @@ def giveaway_winners(): additional_chat_count=TestGiveawayWinnersWithoutRequest.additional_chat_count, unclaimed_prize_count=TestGiveawayWinnersWithoutRequest.unclaimed_prize_count, was_refunded=TestGiveawayWinnersWithoutRequest.was_refunded, + prize_star_count=TestGiveawayWinnersWithoutRequest.prize_star_count, ) @@ -205,6 +237,7 @@ class TestGiveawayWinnersWithoutRequest: only_new_members = True was_refunded = True prize_description = "prize_description" + prize_star_count = 99 def test_slot_behaviour(self, giveaway_winners): for attr in giveaway_winners.__slots__: @@ -226,6 +259,7 @@ def test_de_json(self, offline_bot): "only_new_members": self.only_new_members, "was_refunded": self.was_refunded, "prize_description": self.prize_description, + "prize_star_count": self.prize_star_count, } giveaway_winners = GiveawayWinners.de_json(json_dict, offline_bot) @@ -245,6 +279,7 @@ def test_de_json(self, offline_bot): assert giveaway_winners.only_new_members == self.only_new_members assert giveaway_winners.was_refunded == self.was_refunded assert giveaway_winners.prize_description == self.prize_description + assert giveaway_winners.prize_star_count == self.prize_star_count assert GiveawayWinners.de_json(None, offline_bot) is None @@ -291,6 +326,7 @@ def test_to_dict(self, giveaway_winners): assert giveaway_winners_dict["only_new_members"] == self.only_new_members assert giveaway_winners_dict["was_refunded"] == self.was_refunded assert giveaway_winners_dict["prize_description"] == self.prize_description + assert giveaway_winners_dict["prize_star_count"] == self.prize_star_count def test_equality(self, giveaway_winners): a = giveaway_winners @@ -336,12 +372,14 @@ def giveaway_completed(): winner_count=TestGiveawayCompletedWithoutRequest.winner_count, unclaimed_prize_count=TestGiveawayCompletedWithoutRequest.unclaimed_prize_count, giveaway_message=TestGiveawayCompletedWithoutRequest.giveaway_message, + is_star_giveaway=TestGiveawayCompletedWithoutRequest.is_star_giveaway, ) class TestGiveawayCompletedWithoutRequest: winner_count = 42 unclaimed_prize_count = 4 + is_star_giveaway = True giveaway_message = Message( message_id=1, date=dtm.datetime.now(dtm.timezone.utc), @@ -362,6 +400,7 @@ def test_de_json(self, offline_bot): "winner_count": self.winner_count, "unclaimed_prize_count": self.unclaimed_prize_count, "giveaway_message": self.giveaway_message.to_dict(), + "is_star_giveaway": self.is_star_giveaway, } giveaway_completed = GiveawayCompleted.de_json(json_dict, offline_bot) @@ -370,6 +409,7 @@ def test_de_json(self, offline_bot): assert giveaway_completed.winner_count == self.winner_count assert giveaway_completed.unclaimed_prize_count == self.unclaimed_prize_count assert giveaway_completed.giveaway_message == self.giveaway_message + assert giveaway_completed.is_star_giveaway == self.is_star_giveaway assert GiveawayCompleted.de_json(None, offline_bot) is None @@ -380,6 +420,7 @@ def test_to_dict(self, giveaway_completed): assert giveaway_completed_dict["winner_count"] == self.winner_count assert giveaway_completed_dict["unclaimed_prize_count"] == self.unclaimed_prize_count assert giveaway_completed_dict["giveaway_message"] == self.giveaway_message.to_dict() + assert giveaway_completed_dict["is_star_giveaway"] == self.is_star_giveaway def test_equality(self, giveaway_completed): a = giveaway_completed @@ -387,6 +428,7 @@ def test_equality(self, giveaway_completed): winner_count=self.winner_count, unclaimed_prize_count=self.unclaimed_prize_count, giveaway_message=self.giveaway_message, + is_star_giveaway=self.is_star_giveaway, ) c = GiveawayCompleted( winner_count=self.winner_count + 30, diff --git a/tests/test_message.py b/tests/test_message.py index 02d6e5b5f4a..602d1e1f8a8 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -236,7 +236,7 @@ def message(bot): winner_count=5, ) }, - {"giveaway_created": GiveawayCreated()}, + {"giveaway_created": GiveawayCreated(prize_star_count=99)}, { "giveaway_winners": GiveawayWinners( chat=Chat(1, Chat.CHANNEL), diff --git a/tests/test_paidmedia.py b/tests/test_paidmedia.py index 6592125e789..ee2ea9f9636 100644 --- a/tests/test_paidmedia.py +++ b/tests/test_paidmedia.py @@ -27,8 +27,10 @@ PaidMediaInfo, PaidMediaPhoto, PaidMediaPreview, + PaidMediaPurchased, PaidMediaVideo, PhotoSize, + User, Video, ) from telegram.constants import PaidMediaType @@ -122,6 +124,14 @@ def paid_media_info(): ) +@pytest.fixture(scope="module") +def paid_media_purchased(): + return PaidMediaPurchased( + from_user=PaidMediaPurchasedTestBase.from_user, + paid_media_payload=PaidMediaPurchasedTestBase.paid_media_payload, + ) + + class PaidMediaTestBase: width = 640 height = 480 @@ -323,3 +333,54 @@ def test_equality(self): assert pmi1 != pmi3 assert hash(pmi1) != hash(pmi3) + + +class PaidMediaPurchasedTestBase: + from_user = User(1, "user", False) + paid_media_payload = "payload" + + +class TestPaidMediaPurchasedWithoutRequest(PaidMediaPurchasedTestBase): + def test_slot_behaviour(self, paid_media_purchased): + inst = paid_media_purchased + 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 = { + "from": self.from_user.to_dict(), + "paid_media_payload": self.paid_media_payload, + } + pmp = PaidMediaPurchased.de_json(json_dict, bot) + pmp_none = PaidMediaPurchased.de_json(None, bot) + assert pmp.from_user == self.from_user + assert pmp.paid_media_payload == self.paid_media_payload + assert pmp.api_kwargs == {} + assert pmp_none is None + + def test_to_dict(self, paid_media_purchased): + assert paid_media_purchased.to_dict() == { + "from": self.from_user.to_dict(), + "paid_media_payload": self.paid_media_payload, + } + + def test_equality(self): + pmp1 = PaidMediaPurchased( + from_user=self.from_user, + paid_media_payload=self.paid_media_payload, + ) + pmp2 = PaidMediaPurchased( + from_user=self.from_user, + paid_media_payload=self.paid_media_payload, + ) + pmp3 = PaidMediaPurchased( + from_user=User(2, "user", False), + paid_media_payload="other", + ) + + assert pmp1 == pmp2 + assert hash(pmp1) == hash(pmp2) + + assert pmp1 != pmp3 + assert hash(pmp1) != hash(pmp3) diff --git a/tests/test_stars.py b/tests/test_stars.py index 23ddb410916..d812c7cbbba 100644 --- a/tests/test_stars.py +++ b/tests/test_stars.py @@ -74,6 +74,7 @@ def transaction_partner_user(): ] ) ], + paid_media_payload="payload", ) diff --git a/tests/test_update.py b/tests/test_update.py index f2e9dbf610e..e9a87c6ca1e 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -40,6 +40,7 @@ Message, MessageReactionCountUpdated, MessageReactionUpdated, + PaidMediaPurchased, Poll, PollAnswer, PollOption, @@ -143,6 +144,11 @@ User(1, "", False), ) +purchased_paid_media = PaidMediaPurchased( + from_user=User(1, "", False), + paid_media_payload="payload", +) + params = [ {"message": message}, @@ -178,6 +184,7 @@ {"deleted_business_messages": deleted_business_messages}, {"business_message": business_message}, {"edited_business_message": business_message}, + {"purchased_paid_media": purchased_paid_media}, # Must be last to conform with `ids` below! {"callback_query": CallbackQuery(1, User(1, "", False), "chat")}, ] @@ -205,6 +212,7 @@ "deleted_business_messages", "business_message", "edited_business_message", + "purchased_paid_media", ) ids = (*all_types, "callback_query_without_message") @@ -290,6 +298,7 @@ def test_effective_chat(self, update): or update.poll is not None or update.poll_answer is not None or update.business_connection is not None + or update.purchased_paid_media is not None ): assert chat.id == 1 else: @@ -403,6 +412,7 @@ def test_effective_message(self, update): or update.message_reaction_count is not None or update.deleted_business_messages is not None or update.business_connection is not None + or update.purchased_paid_media is not None ): assert eff_message.message_id == message.message_id else: From e314e78d06f78b5fff12cdfa1d8cd4516c78638d Mon Sep 17 00:00:00 2001 From: Bibo-Joshi <22366557+Bibo-Joshi@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:17:08 +0200 Subject: [PATCH 9/9] Bump Version to v21.6 (#4486) --- CHANGES.rst | 31 +++++++++++++++++++ telegram/_bot.py | 2 +- telegram/_chatboost.py | 4 +-- telegram/_giveaway.py | 16 +++++----- telegram/_paidmedia.py | 2 +- telegram/_payment/stars.py | 4 +-- telegram/_update.py | 8 ++--- telegram/_version.py | 2 +- telegram/constants.py | 6 ++-- .../_handlers/paidmediapurchasedhandler.py | 2 +- telegram/request/_httpxrequest.py | 2 +- 11 files changed, 55 insertions(+), 24 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8e5f302dd03..ba37e99a308 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,37 @@ Changelog ========= +Version 21.6 +============ + +*Released 2024-09-19* + +This is the technical changelog for version 21.6. More elaborate release notes can be found in the news channel `@pythontelegrambotchannel `_. + +New Features +------------ + +- Full Support for Bot API 7.10 (:pr:`4461` closes :issue:`4459`, :pr:`4460`, :pr:`4463` by `aelkheir `_, :pr:`4464`) +- Add Parameter ``httpx_kwargs`` to ``HTTPXRequest`` (:pr:`4451` closes :issue:`4424`) + +Minor Changes +------------- + +- Improve Type Completeness (:pr:`4466`) + +Internal Changes +---------------- + +- Update Python 3.13 Test Suite to RC2 (:pr:`4471`) +- Enforce the ``offline_bot`` Fixture in ``Test*WithoutRequest`` (:pr:`4465`) +- Make Tests for ``telegram.ext`` Independent of Networking (:pr:`4454`) +- Rename Testing Base Classes (:pr:`4453`) + +Dependency Updates +------------------ + +- Bump ``pytest`` from 8.3.2 to 8.3.3 (:pr:`4475`) + Version 21.5 ============ diff --git a/telegram/_bot.py b/telegram/_bot.py index 62f25125c3a..513e43d1698 100644 --- a/telegram/_bot.py +++ b/telegram/_bot.py @@ -9220,7 +9220,7 @@ async def send_paid_media( 0-:tg-const:`telegram.constants.InvoiceLimit.MAX_PAYLOAD_LENGTH` bytes. This will not be displayed to the user, use it for your internal processes. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 caption (:obj:`str`, optional): Caption of the media to be sent, 0-:tg-const:`telegram.constants.MessageLimit.CAPTION_LENGTH` characters. parse_mode (:obj:`str`, optional): |parse_mode| diff --git a/telegram/_chatboost.py b/telegram/_chatboost.py index c39537442e5..e5e26d2f472 100644 --- a/telegram/_chatboost.py +++ b/telegram/_chatboost.py @@ -202,7 +202,7 @@ class ChatBoostSourceGiveaway(ChatBoostSource): prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 is_unclaimed (:obj:`bool`, optional): :obj:`True`, if the giveaway was completed, but there was no user to win the prize. @@ -215,7 +215,7 @@ class ChatBoostSourceGiveaway(ChatBoostSource): prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 is_unclaimed (:obj:`bool`): Optional. :obj:`True`, if the giveaway was completed, but there was no user to win the prize. """ diff --git a/telegram/_giveaway.py b/telegram/_giveaway.py index a482f4757ed..1e258b477f1 100644 --- a/telegram/_giveaway.py +++ b/telegram/_giveaway.py @@ -59,7 +59,7 @@ class Giveaway(TelegramObject): prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram Premium subscription won from the giveaway will be active for; for Telegram Premium giveaways only. @@ -83,7 +83,7 @@ class Giveaway(TelegramObject): prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for; for Telegram Premium giveaways only. @@ -163,13 +163,13 @@ class GiveawayCreated(TelegramObject): prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Attributes: prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ @@ -204,7 +204,7 @@ class GiveawayWinners(TelegramObject): prize_star_count (:obj:`int`, optional): The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 additional_chat_count (:obj:`int`, optional): The number of other chats the user had to join in order to be eligible for the giveaway premium_subscription_month_count (:obj:`int`, optional): The number of months the Telegram @@ -229,7 +229,7 @@ class GiveawayWinners(TelegramObject): prize_star_count (:obj:`int`): Optional. The number of Telegram Stars to be split between giveaway winners; for Telegram Star giveaways only. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 premium_subscription_month_count (:obj:`int`): Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes @@ -337,7 +337,7 @@ class GiveawayCompleted(TelegramObject): is_star_giveaway (:obj:`bool`, optional): :obj:`True`, if the giveaway is a Telegram Star giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Attributes: winner_count (:obj:`int`): Number of winners in the giveaway unclaimed_prize_count (:obj:`int`): Optional. Number of undistributed prizes @@ -346,7 +346,7 @@ class GiveawayCompleted(TelegramObject): is_star_giveaway (:obj:`bool`): Optional. :obj:`True`, if the giveaway is a Telegram Star giveaway. Otherwise, currently, the giveaway is a Telegram Premium giveaway. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ __slots__ = ("giveaway_message", "is_star_giveaway", "unclaimed_prize_count", "winner_count") diff --git a/telegram/_paidmedia.py b/telegram/_paidmedia.py index 57126b13001..1c2cc409191 100644 --- a/telegram/_paidmedia.py +++ b/telegram/_paidmedia.py @@ -300,7 +300,7 @@ class PaidMediaPurchased(TelegramObject): Note: In Python :keyword:`from` is a reserved word. Use :paramref:`from_user` instead. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Args: from_user (:class:`telegram.User`): User who purchased the media. diff --git a/telegram/_payment/stars.py b/telegram/_payment/stars.py index 2a3f1dca280..dfeb832e223 100644 --- a/telegram/_payment/stars.py +++ b/telegram/_payment/stars.py @@ -330,7 +330,7 @@ class TransactionPartnerUser(TransactionPartner): .. versionadded:: 21.5 paid_media_payload (:obj:`str`, optional): Optional. Bot-specified paid media payload. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Attributes: type (:obj:`str`): The type of the transaction partner, @@ -343,7 +343,7 @@ class TransactionPartnerUser(TransactionPartner): .. versionadded:: 21.5 paid_media_payload (:obj:`str`): Optional. Optional. Bot-specified paid media payload. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ diff --git a/telegram/_update.py b/telegram/_update.py index be4f2ec5812..5db7b9a5584 100644 --- a/telegram/_update.py +++ b/telegram/_update.py @@ -160,7 +160,7 @@ class Update(TelegramObject): purchased_paid_media (:class:`telegram.PaidMediaPurchased`, optional): A user purchased paid media with a non-empty payload sent by the bot in a non-channel chat. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Attributes: @@ -273,7 +273,7 @@ class Update(TelegramObject): purchased_paid_media (:class:`telegram.PaidMediaPurchased`): Optional. A user purchased paid media with a non-empty payload sent by the bot in a non-channel chat. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ __slots__ = ( @@ -399,7 +399,7 @@ class Update(TelegramObject): PURCHASED_PAID_MEDIA: Final[str] = constants.UpdateType.PURCHASED_PAID_MEDIA """:const:`telegram.constants.UpdateType.PURCHASED_PAID_MEDIA` - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ ALL_TYPES: Final[List[str]] = list(constants.UpdateType) @@ -496,7 +496,7 @@ def effective_user(self) -> Optional["User"]: This property now also considers :attr:`business_connection`, :attr:`business_message` and :attr:`edited_business_message`. - .. versionchanged:: NEXT.VERSION + .. versionchanged:: 21.6 This property now also considers :attr:`purchased_paid_media`. Example: diff --git a/telegram/_version.py b/telegram/_version.py index 20043c8309b..bb946f5359f 100644 --- a/telegram/_version.py +++ b/telegram/_version.py @@ -51,6 +51,6 @@ def __str__(self) -> str: __version_info__: Final[Version] = Version( - major=21, minor=5, micro=0, releaselevel="final", serial=0 + major=21, minor=6, micro=0, releaselevel="final", serial=0 ) __version__: Final[str] = str(__version_info__) diff --git a/telegram/constants.py b/telegram/constants.py index 4d95368ce9e..582de62c495 100644 --- a/telegram/constants.py +++ b/telegram/constants.py @@ -2782,7 +2782,7 @@ class UpdateType(StringEnum): PURCHASED_PAID_MEDIA = "purchased_paid_media" """:obj:`str`: Updates with :attr:`telegram.Update.purchased_paid_media`. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ @@ -2871,14 +2871,14 @@ class InvoiceLimit(IntEnum): passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of :meth:`telegram.Bot.send_paid_media`. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ MAX_STAR_COUNT = 2500 """:obj:`int`: Maximum amount of starts that must be paid to buy access to a paid media passed as :paramref:`~telegram.Bot.send_paid_media.star_count` parameter of :meth:`telegram.Bot.send_paid_media`. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """ diff --git a/telegram/ext/_handlers/paidmediapurchasedhandler.py b/telegram/ext/_handlers/paidmediapurchasedhandler.py index 13a7cf1230f..f74e0dae076 100644 --- a/telegram/ext/_handlers/paidmediapurchasedhandler.py +++ b/telegram/ext/_handlers/paidmediapurchasedhandler.py @@ -32,7 +32,7 @@ class PaidMediaPurchasedHandler(BaseHandler[Update, CCT, RT]): """Handler class to handle Telegram :attr:`purchased paid media `. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 Args: callback (:term:`coroutine function`): The callback function for this handler. Will be diff --git a/telegram/request/_httpxrequest.py b/telegram/request/_httpxrequest.py index d74ed00d870..a2e13582df0 100644 --- a/telegram/request/_httpxrequest.py +++ b/telegram/request/_httpxrequest.py @@ -135,7 +135,7 @@ class HTTPXRequest(BaseRequest): No runtime warnings will be issued about parameters that are overridden in this way. - .. versionadded:: NEXT.VERSION + .. versionadded:: 21.6 """