diff --git a/changes/unreleased/5304.6rKY3k6kGsCdnZFP8jdsQ2.toml b/changes/unreleased/5304.6rKY3k6kGsCdnZFP8jdsQ2.toml
new file mode 100644
index 00000000000..319572984c9
--- /dev/null
+++ b/changes/unreleased/5304.6rKY3k6kGsCdnZFP8jdsQ2.toml
@@ -0,0 +1,5 @@
+internal = "Make `*WithoutRequest` tests actually not use the network"
+[[pull_requests]]
+uid = "5304"
+author_uids = ["harshil21"]
+closes_threads = ["4829"]
diff --git a/pyproject.toml b/pyproject.toml
index 6a4299d896e..e6828285ca0 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -104,6 +104,8 @@ tests = [
"pytest-asyncio==0.21.2",
# xdist runs tests in parallel
"pytest-xdist==3.8.0",
+ # no_req tests must be fully offline, including during higher-scoped fixture setup
+ "pytest-socket==0.8.0",
# Used for flaky tests (flaky decorator)
"flaky>=3.8.1",
# used in test_official for parsing tg docs
@@ -173,7 +175,7 @@ typing-extensions = false
ignore = ["PLR2004", "PLR0911", "PLR0912", "PLR0913", "PLR0915", "PERF203", "ASYNC240"]
select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET", "RSE",
"G", "ISC", "PT", "ASYNC", "TCH", "SLOT", "PERF", "PYI", "FLY", "AIR", "RUF022",
- "RUF023", "Q", "INP", "W", "YTT", "DTZ", "ARG", "T20", "FURB", "DOC", "TRY",
+ "RUF023", "Q", "INP", "W", "YTT", "DTZ", "ARG", "T20", "FURB", "DOC", "TRY",
"D100", "D101", "D102", "D103", "D300", "D418", "D419", "S"]
# Add "A (flake8-builtins)" after we drop pylint
@@ -212,7 +214,7 @@ exclude-protected = ["_unfrozen"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
-addopts = "--no-success-flaky-report -rX"
+addopts = "--no-flaky-report -rX --allow-unix-socket"
filterwarnings = [
"error",
"ignore::DeprecationWarning",
diff --git a/tests/README.rst b/tests/README.rst
index 54792ceb561..c32634eb245 100644
--- a/tests/README.rst
+++ b/tests/README.rst
@@ -70,6 +70,7 @@ are a few conventions that you should follow:
tooling can help you as well. You can look at the existing tests for examples and inspiration.
- New fixtures should go into ``conftest.py``. New auxiliary functions and classes, used either directly in the tests or in the fixtures, should go into the ``tests/auxil`` directory.
+ Offline fixtures must be prefixed with `offline_*`.
If you have made some API changes, you may want to run ``test_official`` to validate that the changes are
complete and correct. To run it, export an environment variable first:
diff --git a/tests/_files/conftest.py b/tests/_files/conftest.py
index 9e8e5212e11..91324320f46 100644
--- a/tests/_files/conftest.py
+++ b/tests/_files/conftest.py
@@ -20,9 +20,49 @@
import pytest
+from telegram import Animation, Audio, Document, PhotoSize, Sticker, Video
from tests.auxil.files import data_file
from tests.auxil.networking import expect_bad_request
+FILE_ID = "5a3128a4d2a04750b5b58397f3b5e812"
+FILE_UNIQUE_ID = "adc3145fd2e84d95b64d68eaa22aa33e"
+
+
+def _with_bot(file, bot):
+ file.set_bot(bot)
+ return file
+
+
+def _thumbnail(bot, *, width, height, file_size):
+ return _with_bot(
+ PhotoSize(
+ file_id=f"thumbnail-{FILE_ID}",
+ file_unique_id=f"thumbnail-{FILE_UNIQUE_ID}",
+ width=width,
+ height=height,
+ file_size=file_size,
+ ),
+ bot,
+ )
+
+
+@pytest.fixture(scope="session")
+def offline_animation(offline_bot):
+ return _with_bot(
+ Animation(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ width=320,
+ height=180,
+ duration=1,
+ file_name="game.gif.webm",
+ mime_type="video/mp4",
+ file_size=5859,
+ thumbnail=_thumbnail(offline_bot, width=320, height=180, file_size=5859),
+ ),
+ offline_bot,
+ )
+
@pytest.fixture(scope="session")
async def animation(bot, chat_id):
@@ -50,6 +90,22 @@ def animated_sticker_file():
yield f
+@pytest.fixture(scope="session")
+def offline_audio(offline_bot):
+ return _with_bot(
+ Audio(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ duration=3,
+ file_name="telegram.mp3",
+ mime_type="audio/mpeg",
+ file_size=122920,
+ thumbnail=_thumbnail(offline_bot, width=50, height=50, file_size=1427),
+ ),
+ offline_bot,
+ )
+
+
@pytest.fixture(scope="session")
async def audio(bot, chat_id):
with data_file("telegram.mp3").open("rb") as f, data_file("thumb.jpg").open("rb") as thumb:
@@ -62,6 +118,21 @@ def audio_file():
yield f
+@pytest.fixture(scope="session")
+def offline_document(offline_bot):
+ return _with_bot(
+ Document(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ file_name="telegram.png",
+ mime_type="image/png",
+ file_size=12948,
+ thumbnail=_thumbnail(offline_bot, width=300, height=300, file_size=8090),
+ ),
+ offline_bot,
+ )
+
+
@pytest.fixture(scope="session")
async def document(bot, chat_id):
with data_file("telegram.png").open("rb") as f:
@@ -74,6 +145,11 @@ def document_file():
yield f
+@pytest.fixture(scope="session")
+def offline_photo(offline_photolist):
+ return offline_photolist[-1]
+
+
@pytest.fixture(scope="session")
def photo(photolist):
return photolist[-1]
@@ -85,6 +161,32 @@ def photo_file():
yield f
+@pytest.fixture(scope="session")
+def offline_photolist(offline_bot):
+ return (
+ _with_bot(
+ PhotoSize(
+ file_id=f"small-{FILE_ID}",
+ file_unique_id=f"small-{FILE_UNIQUE_ID}",
+ width=90,
+ height=90,
+ file_size=1474,
+ ),
+ offline_bot,
+ ),
+ _with_bot(
+ PhotoSize(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ width=800,
+ height=800,
+ file_size=29176,
+ ),
+ offline_bot,
+ ),
+ )
+
+
@pytest.fixture(scope="session")
async def photolist(bot, chat_id):
async def func():
@@ -96,6 +198,25 @@ async def func():
)
+@pytest.fixture(scope="module")
+def offline_sticker(offline_bot):
+ return _with_bot(
+ Sticker(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ width=510,
+ height=512,
+ is_animated=False,
+ is_video=False,
+ type=Sticker.REGULAR,
+ file_size=39518,
+ thumbnail=_thumbnail(offline_bot, width=319, height=320, file_size=21448),
+ needs_repainting=True,
+ ),
+ offline_bot,
+ )
+
+
@pytest.fixture(scope="module")
async def sticker(bot, chat_id):
with data_file("telegram.webp").open("rb") as f:
@@ -118,15 +239,39 @@ def sticker_set_thumb_file():
yield file
+@pytest.fixture(scope="session")
+def offline_thumb(offline_photolist):
+ return offline_photolist[0]
+
+
@pytest.fixture(scope="session")
def thumb(photolist):
return photolist[0]
+@pytest.fixture(scope="session")
+def offline_video(offline_bot):
+ return _with_bot(
+ Video(
+ file_id=FILE_ID,
+ file_unique_id=FILE_UNIQUE_ID,
+ width=360,
+ height=640,
+ duration=5,
+ file_name="telegram.mp4",
+ mime_type="video/mp4",
+ file_size=326534,
+ thumbnail=_thumbnail(offline_bot, width=180, height=320, file_size=1767),
+ start_timestamp=3,
+ ),
+ offline_bot,
+ )
+
+
@pytest.fixture(scope="session")
async def video(bot, chat_id):
with data_file("telegram.mp4").open("rb") as f:
- return (await bot.send_video(chat_id, video=f, read_timeout=50)).video
+ return (await bot.send_video(chat_id, video=f, start_timestamp=3, read_timeout=50)).video
@pytest.fixture
diff --git a/tests/_files/test_animation.py b/tests/_files/test_animation.py
index df4ae468949..19dee14e0ec 100644
--- a/tests/_files/test_animation.py
+++ b/tests/_files/test_animation.py
@@ -55,69 +55,73 @@ class AnimationTestBase:
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}'"
- assert len(mro_slots(animation)) == len(set(mro_slots(animation))), "duplicate slot"
-
- def test_creation(self, animation):
- assert isinstance(animation, Animation)
- assert isinstance(animation.file_id, str)
- assert isinstance(animation.file_unique_id, str)
- assert animation.file_id
- assert animation.file_unique_id
-
- def test_expected_values(self, animation):
- assert animation.mime_type == self.mime_type
- assert animation.file_name.startswith("game.gif") == self.file_name.startswith("game.gif")
- assert isinstance(animation.thumbnail, PhotoSize)
-
- def test_de_json(self, offline_bot, animation):
+ def test_slot_behaviour(self, offline_animation):
+ for attr in offline_animation.__slots__:
+ assert getattr(offline_animation, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_animation)) == len(set(mro_slots(offline_animation))), (
+ "duplicate slot"
+ )
+
+ def test_creation(self, offline_animation):
+ assert isinstance(offline_animation, Animation)
+ assert isinstance(offline_animation.file_id, str)
+ assert isinstance(offline_animation.file_unique_id, str)
+ assert offline_animation.file_id
+ assert offline_animation.file_unique_id
+
+ def test_expected_values(self, offline_animation):
+ assert offline_animation.mime_type == self.mime_type
+ assert offline_animation.file_name.startswith("game.gif") == self.file_name.startswith(
+ "game.gif"
+ )
+ assert isinstance(offline_animation.thumbnail, PhotoSize)
+
+ def test_de_json(self, offline_bot, offline_animation):
json_dict = {
"file_id": self.animation_file_id,
"file_unique_id": self.animation_file_unique_id,
"width": self.width,
"height": self.height,
"duration": self.duration.total_seconds(),
- "thumbnail": animation.thumbnail.to_dict(),
+ "thumbnail": offline_animation.thumbnail.to_dict(),
"file_name": self.file_name,
"mime_type": self.mime_type,
"file_size": self.file_size,
}
- 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
- assert animation.file_name == self.file_name
- assert animation.mime_type == self.mime_type
- assert animation.file_size == self.file_size
- assert animation._duration == self.duration
-
- def test_to_dict(self, animation):
- animation_dict = animation.to_dict()
+ offline_animation = Animation.de_json(json_dict, offline_bot)
+ assert offline_animation.api_kwargs == {}
+ assert offline_animation.file_id == self.animation_file_id
+ assert offline_animation.file_unique_id == self.animation_file_unique_id
+ assert offline_animation.file_name == self.file_name
+ assert offline_animation.mime_type == self.mime_type
+ assert offline_animation.file_size == self.file_size
+ assert offline_animation._duration == self.duration
+
+ def test_to_dict(self, offline_animation):
+ animation_dict = offline_animation.to_dict()
assert isinstance(animation_dict, dict)
- assert animation_dict["file_id"] == animation.file_id
- assert animation_dict["file_unique_id"] == animation.file_unique_id
- assert animation_dict["width"] == animation.width
- assert animation_dict["height"] == animation.height
+ assert animation_dict["file_id"] == offline_animation.file_id
+ assert animation_dict["file_unique_id"] == offline_animation.file_unique_id
+ assert animation_dict["width"] == offline_animation.width
+ assert animation_dict["height"] == offline_animation.height
assert animation_dict["duration"] == int(self.duration.total_seconds())
assert isinstance(animation_dict["duration"], int)
- assert animation_dict["thumbnail"] == animation.thumbnail.to_dict()
- assert animation_dict["file_name"] == animation.file_name
- assert animation_dict["mime_type"] == animation.mime_type
- assert animation_dict["file_size"] == animation.file_size
+ assert animation_dict["thumbnail"] == offline_animation.thumbnail.to_dict()
+ assert animation_dict["file_name"] == offline_animation.file_name
+ assert animation_dict["mime_type"] == offline_animation.mime_type
+ assert animation_dict["file_size"] == offline_animation.file_size
- def test_time_period_properties(self, PTB_TIMEDELTA, animation):
+ def test_time_period_properties(self, PTB_TIMEDELTA, offline_animation):
if PTB_TIMEDELTA:
- assert animation.duration == self.duration
- assert isinstance(animation.duration, dtm.timedelta)
+ assert offline_animation.duration == self.duration
+ assert isinstance(offline_animation.duration, dtm.timedelta)
else:
- assert animation.duration == int(self.duration.total_seconds())
- assert isinstance(animation.duration, int)
+ assert offline_animation.duration == int(self.duration.total_seconds())
+ assert isinstance(offline_animation.duration, int)
- def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, animation):
- animation.duration
+ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, offline_animation):
+ offline_animation.duration
if PTB_TIMEDELTA:
assert len(recwarn) == 0
@@ -188,23 +192,27 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_send_with_animation(self, monkeypatch, offline_bot, chat_id, animation):
+ async def test_send_with_animation(self, monkeypatch, offline_bot, chat_id, offline_animation):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["animation"] == animation.file_id
+ return request_data.json_parameters["animation"] == offline_animation.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_animation(animation=animation, chat_id=chat_id)
+ assert await offline_bot.send_animation(animation=offline_animation, chat_id=chat_id)
- async def test_get_file_instance_method(self, monkeypatch, animation):
+ async def test_get_file_instance_method(self, monkeypatch, offline_animation):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == animation.file_id
+ return kwargs["file_id"] == offline_animation.file_id
assert check_shortcut_signature(Animation.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(animation.get_file, animation.get_bot(), "get_file")
- assert await check_defaults_handling(animation.get_file, animation.get_bot())
+ assert await check_shortcut_call(
+ offline_animation.get_file, offline_animation.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(
+ offline_animation.get_file, offline_animation.get_bot()
+ )
- monkeypatch.setattr(animation.get_bot(), "get_file", make_assertion)
- assert await animation.get_file()
+ monkeypatch.setattr(offline_animation.get_bot(), "get_file", make_assertion)
+ assert await offline_animation.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -216,7 +224,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_animation_default_quote_parse_mode(
- self, default_bot, chat_id, animation, custom, monkeypatch
+ self, default_bot, chat_id, offline_animation, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -230,7 +238,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(default_bot.request, "post", make_assertion)
await default_bot.send_animation(
- chat_id, animation, reply_parameters=ReplyParameters(**kwargs)
+ chat_id, offline_animation, reply_parameters=ReplyParameters(**kwargs)
)
diff --git a/tests/_files/test_audio.py b/tests/_files/test_audio.py
index dd832966fde..5b3cb46d33e 100644
--- a/tests/_files/test_audio.py
+++ b/tests/_files/test_audio.py
@@ -58,30 +58,32 @@ class AudioTestBase:
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}'"
- assert len(mro_slots(audio)) == len(set(mro_slots(audio))), "duplicate slot"
+ def test_slot_behaviour(self, offline_audio):
+ for attr in offline_audio.__slots__:
+ assert getattr(offline_audio, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_audio)) == len(set(mro_slots(offline_audio))), (
+ "duplicate slot"
+ )
- def test_creation(self, audio):
+ def test_creation(self, offline_audio):
# Make sure file has been uploaded.
- assert isinstance(audio, Audio)
- assert isinstance(audio.file_id, str)
- assert isinstance(audio.file_unique_id, str)
- assert audio.file_id
- assert audio.file_unique_id
-
- def test_expected_values(self, audio):
- assert audio._duration == self.duration
- assert audio.performer is None
- assert audio.title is None
- assert audio.mime_type == self.mime_type
- assert audio.file_size == self.file_size
- assert audio.thumbnail.file_size in [self.thumb_file_size, 1395]
- assert audio.thumbnail.width == self.thumb_width
- assert audio.thumbnail.height == self.thumb_height
-
- def test_de_json(self, offline_bot, audio):
+ assert isinstance(offline_audio, Audio)
+ assert isinstance(offline_audio.file_id, str)
+ assert isinstance(offline_audio.file_unique_id, str)
+ assert offline_audio.file_id
+ assert offline_audio.file_unique_id
+
+ def test_expected_values(self, offline_audio):
+ assert offline_audio._duration == self.duration
+ assert offline_audio.performer is None
+ assert offline_audio.title is None
+ assert offline_audio.mime_type == self.mime_type
+ assert offline_audio.file_size == self.file_size
+ assert offline_audio.thumbnail.file_size in [self.thumb_file_size, 1395]
+ assert offline_audio.thumbnail.width == self.thumb_width
+ assert offline_audio.thumbnail.height == self.thumb_height
+
+ def test_de_json(self, offline_bot, offline_audio):
json_dict = {
"file_id": self.audio_file_id,
"file_unique_id": self.audio_file_unique_id,
@@ -91,7 +93,7 @@ def test_de_json(self, offline_bot, audio):
"file_name": self.file_name,
"mime_type": self.mime_type,
"file_size": self.file_size,
- "thumbnail": audio.thumbnail.to_dict(),
+ "thumbnail": offline_audio.thumbnail.to_dict(),
}
json_audio = Audio.de_json(json_dict, offline_bot)
assert json_audio.api_kwargs == {}
@@ -104,30 +106,30 @@ def test_de_json(self, offline_bot, audio):
assert json_audio.file_name == self.file_name
assert json_audio.mime_type == self.mime_type
assert json_audio.file_size == self.file_size
- assert json_audio.thumbnail == audio.thumbnail
+ assert json_audio.thumbnail == offline_audio.thumbnail
- def test_to_dict(self, audio):
- audio_dict = audio.to_dict()
+ def test_to_dict(self, offline_audio):
+ audio_dict = offline_audio.to_dict()
assert isinstance(audio_dict, dict)
- assert audio_dict["file_id"] == audio.file_id
- assert audio_dict["file_unique_id"] == audio.file_unique_id
+ assert audio_dict["file_id"] == offline_audio.file_id
+ assert audio_dict["file_unique_id"] == offline_audio.file_unique_id
assert audio_dict["duration"] == int(self.duration.total_seconds())
assert isinstance(audio_dict["duration"], int)
- assert audio_dict["mime_type"] == audio.mime_type
- assert audio_dict["file_size"] == audio.file_size
- assert audio_dict["file_name"] == audio.file_name
+ assert audio_dict["mime_type"] == offline_audio.mime_type
+ assert audio_dict["file_size"] == offline_audio.file_size
+ assert audio_dict["file_name"] == offline_audio.file_name
- def test_time_period_properties(self, PTB_TIMEDELTA, audio):
+ def test_time_period_properties(self, PTB_TIMEDELTA, offline_audio):
if PTB_TIMEDELTA:
- assert audio.duration == self.duration
- assert isinstance(audio.duration, dtm.timedelta)
+ assert offline_audio.duration == self.duration
+ assert isinstance(offline_audio.duration, dtm.timedelta)
else:
- assert audio.duration == int(self.duration.total_seconds())
- assert isinstance(audio.duration, int)
+ assert offline_audio.duration == int(self.duration.total_seconds())
+ assert isinstance(offline_audio.duration, int)
- def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, audio):
- audio.duration
+ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, offline_audio):
+ offline_audio.duration
if PTB_TIMEDELTA:
assert len(recwarn) == 0
@@ -136,12 +138,12 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, audio):
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_equality(self, audio):
- a = Audio(audio.file_id, audio.file_unique_id, audio.duration)
- b = Audio("", audio.file_unique_id, audio.duration)
- c = Audio(audio.file_id, audio.file_unique_id, 0)
- d = Audio("", "", audio.duration)
- e = Voice(audio.file_id, audio.file_unique_id, audio.duration)
+ def test_equality(self, offline_audio):
+ a = Audio(offline_audio.file_id, offline_audio.file_unique_id, offline_audio.duration)
+ b = Audio("", offline_audio.file_unique_id, offline_audio.duration)
+ c = Audio(offline_audio.file_id, offline_audio.file_unique_id, 0)
+ d = Audio("", "", offline_audio.duration)
+ e = Voice(offline_audio.file_id, offline_audio.file_unique_id, offline_audio.duration)
assert a == b
assert hash(a) == hash(b)
@@ -156,12 +158,12 @@ def test_equality(self, audio):
assert a != e
assert hash(a) != hash(e)
- async def test_send_with_audio(self, monkeypatch, offline_bot, chat_id, audio):
+ async def test_send_with_audio(self, monkeypatch, offline_bot, chat_id, offline_audio):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["audio"] == audio.file_id
+ return request_data.json_parameters["audio"] == offline_audio.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_audio(audio=audio, chat_id=chat_id)
+ assert await offline_bot.send_audio(audio=offline_audio, chat_id=chat_id)
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):
@@ -197,16 +199,18 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, audio):
+ async def test_get_file_instance_method(self, monkeypatch, offline_audio):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == audio.file_id
+ return kwargs["file_id"] == offline_audio.file_id
assert check_shortcut_signature(Audio.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(audio.get_file, audio.get_bot(), "get_file")
- assert await check_defaults_handling(audio.get_file, audio.get_bot())
+ assert await check_shortcut_call(
+ offline_audio.get_file, offline_audio.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_audio.get_file, offline_audio.get_bot())
- monkeypatch.setattr(audio._bot, "get_file", make_assertion)
- assert await audio.get_file()
+ monkeypatch.setattr(offline_audio._bot, "get_file", make_assertion)
+ assert await offline_audio.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -218,7 +222,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_audio_default_quote_parse_mode(
- self, default_bot, chat_id, audio, custom, monkeypatch
+ self, default_bot, chat_id, offline_audio, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -231,7 +235,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
kwargs["quote_parse_mode"] = custom
monkeypatch.setattr(default_bot.request, "post", make_assertion)
- await default_bot.send_audio(chat_id, audio, reply_parameters=ReplyParameters(**kwargs))
+ await default_bot.send_audio(
+ chat_id, offline_audio, reply_parameters=ReplyParameters(**kwargs)
+ )
class TestAudioWithRequest(AudioTestBase):
diff --git a/tests/_files/test_chatphoto.py b/tests/_files/test_chatphoto.py
index 651d2ced060..85be941ff0f 100644
--- a/tests/_files/test_chatphoto.py
+++ b/tests/_files/test_chatphoto.py
@@ -42,6 +42,18 @@ def chatphoto_file():
yield f
+@pytest.fixture(scope="module")
+def offline_chat_photo(offline_bot):
+ value = ChatPhoto(
+ small_file_id=ChatPhotoTestBase.chatphoto_small_file_id,
+ small_file_unique_id=ChatPhotoTestBase.chatphoto_small_file_unique_id,
+ big_file_id=ChatPhotoTestBase.chatphoto_big_file_id,
+ big_file_unique_id=ChatPhotoTestBase.chatphoto_big_file_unique_id,
+ )
+ value.set_bot(offline_bot)
+ return value
+
+
@pytest.fixture(scope="module")
async def chat_photo(bot, super_group_id):
async def func():
@@ -61,33 +73,35 @@ class ChatPhotoTestBase:
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}'"
- assert len(mro_slots(chat_photo)) == len(set(mro_slots(chat_photo))), "duplicate slot"
+ def test_slot_behaviour(self, offline_chat_photo):
+ for attr in offline_chat_photo.__slots__:
+ assert getattr(offline_chat_photo, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_chat_photo)) == len(set(mro_slots(offline_chat_photo))), (
+ "duplicate slot"
+ )
- def test_de_json(self, offline_bot, chat_photo):
+ def test_de_json(self, offline_bot):
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, 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
- assert chat_photo.small_file_unique_id == self.chatphoto_small_file_unique_id
- assert chat_photo.big_file_unique_id == self.chatphoto_big_file_unique_id
+ offline_chat_photo = ChatPhoto.de_json(json_dict, offline_bot)
+ assert offline_chat_photo.api_kwargs == {}
+ assert offline_chat_photo.small_file_id == self.chatphoto_small_file_id
+ assert offline_chat_photo.big_file_id == self.chatphoto_big_file_id
+ assert offline_chat_photo.small_file_unique_id == self.chatphoto_small_file_unique_id
+ assert offline_chat_photo.big_file_unique_id == self.chatphoto_big_file_unique_id
- async def test_to_dict(self, chat_photo):
- chat_photo_dict = chat_photo.to_dict()
+ async def test_to_dict(self, offline_chat_photo):
+ chat_photo_dict = offline_chat_photo.to_dict()
assert isinstance(chat_photo_dict, dict)
- assert chat_photo_dict["small_file_id"] == chat_photo.small_file_id
- assert chat_photo_dict["big_file_id"] == chat_photo.big_file_id
- assert chat_photo_dict["small_file_unique_id"] == chat_photo.small_file_unique_id
- assert chat_photo_dict["big_file_unique_id"] == chat_photo.big_file_unique_id
+ assert chat_photo_dict["small_file_id"] == offline_chat_photo.small_file_id
+ assert chat_photo_dict["big_file_id"] == offline_chat_photo.big_file_id
+ assert chat_photo_dict["small_file_unique_id"] == offline_chat_photo.small_file_unique_id
+ assert chat_photo_dict["big_file_unique_id"] == offline_chat_photo.big_file_unique_id
def test_equality(self):
a = ChatPhoto(
@@ -122,38 +136,46 @@ def test_equality(self):
assert hash(a) != hash(e)
async def test_send_with_chat_photo(
- self, monkeypatch, offline_bot, super_group_id, chat_photo
+ self, monkeypatch, offline_bot, super_group_id, offline_chat_photo
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.parameters["photo"] == chat_photo.to_dict()
+ return request_data.parameters["photo"] == offline_chat_photo.to_dict()
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- message = await offline_bot.set_chat_photo(photo=chat_photo, chat_id=super_group_id)
+ message = await offline_bot.set_chat_photo(
+ photo=offline_chat_photo, chat_id=super_group_id
+ )
assert message
- async def test_get_small_file_instance_method(self, monkeypatch, chat_photo):
+ async def test_get_small_file_instance_method(self, monkeypatch, offline_chat_photo):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == chat_photo.small_file_id
+ return kwargs["file_id"] == offline_chat_photo.small_file_id
assert check_shortcut_signature(ChatPhoto.get_small_file, Bot.get_file, ["file_id"], [])
assert await check_shortcut_call(
- chat_photo.get_small_file, chat_photo.get_bot(), "get_file"
+ offline_chat_photo.get_small_file, offline_chat_photo.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(
+ offline_chat_photo.get_small_file, offline_chat_photo.get_bot()
)
- assert await check_defaults_handling(chat_photo.get_small_file, chat_photo.get_bot())
- monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion)
- assert await chat_photo.get_small_file()
+ monkeypatch.setattr(offline_chat_photo.get_bot(), "get_file", make_assertion)
+ assert await offline_chat_photo.get_small_file()
- async def test_get_big_file_instance_method(self, monkeypatch, chat_photo):
+ async def test_get_big_file_instance_method(self, monkeypatch, offline_chat_photo):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == chat_photo.big_file_id
+ return kwargs["file_id"] == offline_chat_photo.big_file_id
assert check_shortcut_signature(ChatPhoto.get_big_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(chat_photo.get_big_file, chat_photo.get_bot(), "get_file")
- assert await check_defaults_handling(chat_photo.get_big_file, chat_photo.get_bot())
+ assert await check_shortcut_call(
+ offline_chat_photo.get_big_file, offline_chat_photo.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(
+ offline_chat_photo.get_big_file, offline_chat_photo.get_bot()
+ )
- monkeypatch.setattr(chat_photo.get_bot(), "get_file", make_assertion)
- assert await chat_photo.get_big_file()
+ monkeypatch.setattr(offline_chat_photo.get_bot(), "get_file", make_assertion)
+ assert await offline_chat_photo.get_big_file()
class TestChatPhotoWithRequest:
diff --git a/tests/_files/test_document.py b/tests/_files/test_document.py
index 224e05aa2fa..4ee2029ae47 100644
--- a/tests/_files/test_document.py
+++ b/tests/_files/test_document.py
@@ -51,31 +51,33 @@ class DocumentTestBase:
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}'"
- assert len(mro_slots(document)) == len(set(mro_slots(document))), "duplicate slot"
-
- def test_creation(self, document):
- assert isinstance(document, Document)
- assert isinstance(document.file_id, str)
- assert isinstance(document.file_unique_id, str)
- assert document.file_id
- assert document.file_unique_id
-
- def test_expected_values(self, document):
- assert document.file_size == self.file_size
- assert document.mime_type == self.mime_type
- assert document.file_name == self.file_name
- assert document.thumbnail.file_size in [self.thumb_file_size, 7980]
- assert document.thumbnail.width == self.thumb_width
- assert document.thumbnail.height == self.thumb_height
+ def test_slot_behaviour(self, offline_document):
+ for attr in offline_document.__slots__:
+ assert getattr(offline_document, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_document)) == len(set(mro_slots(offline_document))), (
+ "duplicate slot"
+ )
- def test_de_json(self, offline_bot, document):
+ def test_creation(self, offline_document):
+ assert isinstance(offline_document, Document)
+ assert isinstance(offline_document.file_id, str)
+ assert isinstance(offline_document.file_unique_id, str)
+ assert offline_document.file_id
+ assert offline_document.file_unique_id
+
+ def test_expected_values(self, offline_document):
+ assert offline_document.file_size == self.file_size
+ assert offline_document.mime_type == self.mime_type
+ assert offline_document.file_name == self.file_name
+ assert offline_document.thumbnail.file_size in [self.thumb_file_size, 7980]
+ assert offline_document.thumbnail.width == self.thumb_width
+ assert offline_document.thumbnail.height == self.thumb_height
+
+ def test_de_json(self, offline_bot, offline_document):
json_dict = {
"file_id": self.document_file_id,
"file_unique_id": self.document_file_unique_id,
- "thumbnail": document.thumbnail.to_dict(),
+ "thumbnail": offline_document.thumbnail.to_dict(),
"file_name": self.file_name,
"mime_type": self.mime_type,
"file_size": self.file_size,
@@ -85,26 +87,26 @@ def test_de_json(self, offline_bot, document):
assert test_document.file_id == self.document_file_id
assert test_document.file_unique_id == self.document_file_unique_id
- assert test_document.thumbnail == document.thumbnail
+ assert test_document.thumbnail == offline_document.thumbnail
assert test_document.file_name == self.file_name
assert test_document.mime_type == self.mime_type
assert test_document.file_size == self.file_size
- def test_to_dict(self, document):
- document_dict = document.to_dict()
+ def test_to_dict(self, offline_document):
+ document_dict = offline_document.to_dict()
assert isinstance(document_dict, dict)
- assert document_dict["file_id"] == document.file_id
- assert document_dict["file_unique_id"] == document.file_unique_id
- assert document_dict["file_name"] == document.file_name
- assert document_dict["mime_type"] == document.mime_type
- assert document_dict["file_size"] == document.file_size
-
- def test_equality(self, document):
- a = Document(document.file_id, document.file_unique_id)
- b = Document("", document.file_unique_id)
+ assert document_dict["file_id"] == offline_document.file_id
+ assert document_dict["file_unique_id"] == offline_document.file_unique_id
+ assert document_dict["file_name"] == offline_document.file_name
+ assert document_dict["mime_type"] == offline_document.mime_type
+ assert document_dict["file_size"] == offline_document.file_size
+
+ def test_equality(self, offline_document):
+ a = Document(offline_document.file_id, offline_document.file_unique_id)
+ b = Document("", offline_document.file_unique_id)
d = Document("", "")
- e = Voice(document.file_id, document.file_unique_id, 0)
+ e = Voice(offline_document.file_id, offline_document.file_unique_id, 0)
assert a == b
assert hash(a) == hash(b)
@@ -122,19 +124,19 @@ async def test_error_send_without_required_args(self, offline_bot, chat_id):
@pytest.mark.parametrize("disable_content_type_detection", [True, False, None])
async def test_send_with_document(
- self, monkeypatch, offline_bot, chat_id, document, disable_content_type_detection
+ self, monkeypatch, offline_bot, chat_id, offline_document, disable_content_type_detection
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
data = request_data.parameters
type_detection = (
data.get("disable_content_type_detection") == disable_content_type_detection
)
- return data["document"] == document.file_id and type_detection
+ return data["document"] == offline_document.file_id and type_detection
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
message = await offline_bot.send_document(
- document=document,
+ document=offline_document,
chat_id=chat_id,
disable_content_type_detection=disable_content_type_detection,
)
@@ -151,7 +153,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
indirect=["default_bot"],
)
async def test_send_document_default_quote_parse_mode(
- self, default_bot, chat_id, document, custom, monkeypatch
+ self, default_bot, chat_id, offline_document, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -165,7 +167,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(default_bot.request, "post", make_assertion)
await default_bot.send_document(
- chat_id, document, reply_parameters=ReplyParameters(**kwargs)
+ chat_id, offline_document, reply_parameters=ReplyParameters(**kwargs)
)
@pytest.mark.parametrize("local_mode", [True, False])
@@ -197,16 +199,18 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, document):
+ async def test_get_file_instance_method(self, monkeypatch, offline_document):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == document.file_id
+ return kwargs["file_id"] == offline_document.file_id
assert check_shortcut_signature(Document.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(document.get_file, document.get_bot(), "get_file")
- assert await check_defaults_handling(document.get_file, document.get_bot())
+ assert await check_shortcut_call(
+ offline_document.get_file, offline_document.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_document.get_file, offline_document.get_bot())
- monkeypatch.setattr(document.get_bot(), "get_file", make_assertion)
- assert await document.get_file()
+ monkeypatch.setattr(offline_document.get_bot(), "get_file", make_assertion)
+ assert await offline_document.get_file()
class TestDocumentWithRequest(DocumentTestBase):
diff --git a/tests/_files/test_inputmedia.py b/tests/_files/test_inputmedia.py
index 2cd9c9bc75a..8f39d4dabbe 100644
--- a/tests/_files/test_inputmedia.py
+++ b/tests/_files/test_inputmedia.py
@@ -304,14 +304,14 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, input_media_vi
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_with_video(self, video, PTB_TIMEDELTA):
+ def test_with_video(self, offline_video):
# fixture found in test_video
- input_media_video = InputMediaVideo(video, caption="test 3")
+ input_media_video = InputMediaVideo(offline_video, caption="test 3")
assert input_media_video.type == self.type_
- assert input_media_video.media == video.file_id
- assert input_media_video.width == video.width
- assert input_media_video.height == video.height
- assert input_media_video.duration == video.duration
+ assert input_media_video.media == offline_video.file_id
+ assert input_media_video.width == offline_video.width
+ assert input_media_video.height == offline_video.height
+ assert input_media_video.duration == offline_video.duration
assert input_media_video.caption == "test 3"
def test_with_video_file(self, video_file):
@@ -467,11 +467,11 @@ def test_to_dict(self, input_media_photo):
== input_media_photo.show_caption_above_media
)
- def test_with_photo(self, photo):
+ def test_with_photo(self, offline_photo):
# fixture found in test_photo
- input_media_photo = InputMediaPhoto(photo, caption="test 2")
+ input_media_photo = InputMediaPhoto(offline_photo, caption="test 2")
assert input_media_photo.type == self.type_
- assert input_media_photo.media == photo.file_id
+ assert input_media_photo.media == offline_photo.file_id
assert input_media_photo.caption == "test 2"
def test_with_photo_file(self, photo_file):
@@ -638,11 +638,11 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, input_media_an
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_with_animation(self, animation):
+ def test_with_animation(self, offline_animation):
# fixture found in test_animation
- input_media_animation = InputMediaAnimation(animation, caption="test 2")
+ input_media_animation = InputMediaAnimation(offline_animation, caption="test 2")
assert input_media_animation.type == self.type_
- assert input_media_animation.media == animation.file_id
+ assert input_media_animation.media == offline_animation.file_id
assert input_media_animation.caption == "test 2"
def test_with_animation_file(self, animation_file):
@@ -815,14 +815,14 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, input_media_au
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_with_audio(self, audio):
+ def test_with_audio(self, offline_audio):
# fixture found in test_audio
- input_media_audio = InputMediaAudio(audio, caption="test 3")
+ input_media_audio = InputMediaAudio(offline_audio, caption="test 3")
assert input_media_audio.type == self.type_
- assert input_media_audio.media == audio.file_id
- assert input_media_audio.duration == audio.duration
- assert input_media_audio.performer == audio.performer
- assert input_media_audio.title == audio.title
+ assert input_media_audio.media == offline_audio.file_id
+ assert input_media_audio.duration == offline_audio.duration
+ assert input_media_audio.performer == offline_audio.performer
+ assert input_media_audio.title == offline_audio.title
assert input_media_audio.caption == "test 3"
def test_with_audio_file(self, audio_file):
@@ -1042,10 +1042,10 @@ def test_to_dict(self, input_media_sticker):
assert input_media_sticker_dict["media"] == input_media_sticker.media
assert input_media_sticker_dict["emoji"] == input_media_sticker.emoji
- def test_with_sticker(self, sticker):
- input_media_sticker = InputMediaSticker(sticker, emoji=self.emoji)
+ def test_with_sticker(self, offline_sticker):
+ input_media_sticker = InputMediaSticker(offline_sticker, emoji=self.emoji)
assert input_media_sticker.type == self.type_
- assert input_media_sticker.media == sticker.file_id
+ assert input_media_sticker.media == offline_sticker.file_id
assert input_media_sticker.emoji == self.emoji
def test_with_sticker_file(self, sticker_file):
@@ -1103,11 +1103,11 @@ def test_to_dict(self, input_media_document):
== input_media_document.disable_content_type_detection
)
- def test_with_document(self, document):
+ def test_with_document(self, offline_document):
# fixture found in test_document
- input_media_document = InputMediaDocument(document, caption="test 3")
+ input_media_document = InputMediaDocument(offline_document, caption="test 3")
assert input_media_document.type == self.type_
- assert input_media_document.media == document.file_id
+ assert input_media_document.media == offline_document.file_id
assert input_media_document.caption == "test 3"
def test_with_document_file(self, document_file):
@@ -1218,11 +1218,11 @@ def test_to_dict(self, input_paid_media_photo):
assert input_paid_media_photo_dict["type"] == input_paid_media_photo.type
assert input_paid_media_photo_dict["media"] == input_paid_media_photo.media
- def test_with_photo(self, photo):
+ def test_with_photo(self, offline_photo):
# fixture found in conftest.py
- input_paid_media_photo = InputPaidMediaPhoto(photo)
+ input_paid_media_photo = InputPaidMediaPhoto(offline_photo)
assert input_paid_media_photo.type == self.type_
- assert input_paid_media_photo.media == photo.file_id
+ assert input_paid_media_photo.media == offline_photo.file_id
def test_with_photo_file(self, photo_file):
# fixture found in conftest.py
@@ -1283,12 +1283,12 @@ def test_to_dict(self, input_media_live_photo):
)
assert input_media_live_photo_dict["has_spoiler"] == input_media_live_photo.has_spoiler
- def test_with_photo_and_video(self, video, photo):
+ def test_with_photo_and_video(self, offline_video, offline_photo):
# fixtures found in conftest.py
- input_media_live_photo = InputMediaLivePhoto(video, photo)
+ input_media_live_photo = InputMediaLivePhoto(offline_video, offline_photo)
assert input_media_live_photo.type == self.type_
- assert input_media_live_photo.media == video.file_id
- assert input_media_live_photo.photo == photo.file_id
+ assert input_media_live_photo.media == offline_video.file_id
+ assert input_media_live_photo.photo == offline_photo.file_id
def test_with_photo_and_video_files(self, video_file, photo_file):
# fixture found in conftest.py
@@ -1362,14 +1362,14 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, input_paid_med
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_with_video(self, video):
+ def test_with_video(self, offline_video):
# fixture found in test_video
- input_paid_media_video = InputPaidMediaVideo(video)
+ input_paid_media_video = InputPaidMediaVideo(offline_video)
assert input_paid_media_video.type == self.type_
- assert input_paid_media_video.media == video.file_id
- assert input_paid_media_video.width == video.width
- assert input_paid_media_video.height == video.height
- assert input_paid_media_video.duration == video.duration
+ assert input_paid_media_video.media == offline_video.file_id
+ assert input_paid_media_video.width == offline_video.width
+ assert input_paid_media_video.height == offline_video.height
+ assert input_paid_media_video.duration == offline_video.duration
def test_with_video_file(self, video_file):
# fixture found in test_video
@@ -1406,12 +1406,12 @@ def test_to_dict(self, input_paid_media_live_photo):
assert input_paid_media_live_photo_dict["media"] == input_paid_media_live_photo.media
assert input_paid_media_live_photo_dict["photo"] == input_paid_media_live_photo.photo
- def test_with_photo(self, video, photo):
+ def test_with_photo(self, offline_video, offline_photo):
# fixtures found in conftest.py
- input_paid_media_live_photo = InputPaidMediaLivePhoto(video, photo)
+ input_paid_media_live_photo = InputPaidMediaLivePhoto(offline_video, offline_photo)
assert input_paid_media_live_photo.type == self.type_
- assert input_paid_media_live_photo.media == video.file_id
- assert input_paid_media_live_photo.photo == photo.file_id
+ assert input_paid_media_live_photo.media == offline_video.file_id
+ assert input_paid_media_live_photo.photo == offline_photo.file_id
def test_with_photo_file(self, photo_file):
# fixture found in conftest.py
@@ -1428,20 +1428,64 @@ def test_with_local_files(self):
assert input_paid_media_live_photo.photo == data_file("telegram.jpg").as_uri()
+@pytest.fixture(scope="module")
+def offline_media_group(offline_photo, offline_thumb):
+ return [
+ InputMediaPhoto(offline_photo, caption="*photo* 1", parse_mode="Markdown"),
+ InputMediaPhoto(offline_thumb, caption="photo 2", parse_mode="HTML"),
+ InputMediaPhoto(
+ offline_photo,
+ caption="photo 3",
+ caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)],
+ ),
+ ]
+
+
+@pytest.fixture(scope="module")
+def offline_media_group_no_caption_args(offline_photo, offline_thumb):
+ return [
+ InputMediaPhoto(offline_photo),
+ InputMediaPhoto(offline_thumb),
+ InputMediaPhoto(offline_photo),
+ ]
+
+
+@pytest.fixture(scope="module")
+def offline_media_group_no_caption_only_caption_entities(offline_photo):
+ return [
+ InputMediaPhoto(offline_photo, caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)]),
+ InputMediaPhoto(offline_photo, caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)]),
+ ]
+
+
+@pytest.fixture(scope="module")
+def offline_media_group_no_caption_only_parse_mode(offline_photo, offline_thumb):
+ return [
+ InputMediaPhoto(offline_photo, parse_mode="Markdown"),
+ InputMediaPhoto(offline_thumb, parse_mode="HTML"),
+ ]
+
+
@pytest.fixture(scope="module")
def media_group(photo, thumb):
return [
InputMediaPhoto(photo, caption="*photo* 1", parse_mode="Markdown"),
InputMediaPhoto(thumb, caption="photo 2", parse_mode="HTML"),
InputMediaPhoto(
- photo, caption="photo 3", caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)]
+ photo,
+ caption="photo 3",
+ caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 5)],
),
]
@pytest.fixture(scope="module")
def media_group_no_caption_args(photo, thumb):
- return [InputMediaPhoto(photo), InputMediaPhoto(thumb), InputMediaPhoto(photo)]
+ return [
+ InputMediaPhoto(photo),
+ InputMediaPhoto(thumb),
+ InputMediaPhoto(photo),
+ ]
@pytest.fixture(scope="module")
@@ -1465,14 +1509,14 @@ async def test_send_media_group_throws_error_with_group_caption_and_individual_c
self,
offline_bot,
chat_id,
- media_group,
- media_group_no_caption_only_caption_entities,
- media_group_no_caption_only_parse_mode,
+ offline_media_group,
+ offline_media_group_no_caption_only_caption_entities,
+ offline_media_group_no_caption_only_parse_mode,
):
for group in (
- media_group,
- media_group_no_caption_only_caption_entities,
- media_group_no_caption_only_parse_mode,
+ offline_media_group,
+ offline_media_group_no_caption_only_caption_entities,
+ offline_media_group_no_caption_only_parse_mode,
):
with pytest.raises(
ValueError,
@@ -1558,7 +1602,7 @@ async def make_assertion(
indirect=["default_bot"],
)
async def test_send_media_group_default_quote_parse_mode(
- self, default_bot, chat_id, media_group, custom, monkeypatch
+ self, default_bot, chat_id, offline_media_group, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -1572,7 +1616,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(default_bot.request, "post", make_assertion)
await default_bot.send_media_group(
- chat_id, media_group, reply_parameters=ReplyParameters(**kwargs)
+ chat_id, offline_media_group, reply_parameters=ReplyParameters(**kwargs)
)
diff --git a/tests/_files/test_photo.py b/tests/_files/test_photo.py
index 93e0ac40ea1..6325e793f46 100644
--- a/tests/_files/test_photo.py
+++ b/tests/_files/test_photo.py
@@ -48,39 +48,41 @@ class PhotoTestBase:
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}'"
- assert len(mro_slots(photo)) == len(set(mro_slots(photo))), "duplicate slot"
+ def test_slot_behaviour(self, offline_photo):
+ for attr in offline_photo.__slots__:
+ assert getattr(offline_photo, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_photo)) == len(set(mro_slots(offline_photo))), (
+ "duplicate slot"
+ )
- def test_creation(self, thumb, photo):
+ def test_creation(self, offline_thumb, offline_photo):
# Make sure file has been uploaded.
- assert isinstance(photo, PhotoSize)
- assert isinstance(photo.file_id, str)
- assert isinstance(photo.file_unique_id, str)
- assert photo.file_id
- assert photo.file_unique_id
-
- assert isinstance(thumb, PhotoSize)
- assert isinstance(thumb.file_id, str)
- assert isinstance(thumb.file_unique_id, str)
- assert thumb.file_id
- assert thumb.file_unique_id
-
- def test_expected_values(self, photo, thumb):
- assert photo.width == self.width
- assert photo.height == self.height
- assert photo.file_size in self.file_size
- assert thumb.width == 90
- assert thumb.height == 90
+ assert isinstance(offline_photo, PhotoSize)
+ assert isinstance(offline_photo.file_id, str)
+ assert isinstance(offline_photo.file_unique_id, str)
+ assert offline_photo.file_id
+ assert offline_photo.file_unique_id
+
+ assert isinstance(offline_thumb, PhotoSize)
+ assert isinstance(offline_thumb.file_id, str)
+ assert isinstance(offline_thumb.file_unique_id, str)
+ assert offline_thumb.file_id
+ assert offline_thumb.file_unique_id
+
+ def test_expected_values(self, offline_photo, offline_thumb):
+ assert offline_photo.width == self.width
+ assert offline_photo.height == self.height
+ assert offline_photo.file_size in self.file_size
+ assert offline_thumb.width == 90
+ assert offline_thumb.height == 90
# File sizes don't seem to be consistent, so we use the values that we have observed
# so far
- assert thumb.file_size in [1474, 1475, 1477]
+ assert offline_thumb.file_size in [1474, 1475, 1477]
- def test_de_json(self, offline_bot, photo):
+ def test_de_json(self, offline_bot, offline_photo):
json_dict = {
- "file_id": photo.file_id,
- "file_unique_id": photo.file_unique_id,
+ "file_id": offline_photo.file_id,
+ "file_unique_id": offline_photo.file_unique_id,
"width": self.width,
"height": self.height,
"file_size": self.file_size,
@@ -88,30 +90,30 @@ def test_de_json(self, offline_bot, photo):
json_photo = PhotoSize.de_json(json_dict, offline_bot)
assert json_photo.api_kwargs == {}
- assert json_photo.file_id == photo.file_id
- assert json_photo.file_unique_id == photo.file_unique_id
+ assert json_photo.file_id == offline_photo.file_id
+ assert json_photo.file_unique_id == offline_photo.file_unique_id
assert json_photo.width == self.width
assert json_photo.height == self.height
assert json_photo.file_size == self.file_size
- def test_to_dict(self, photo):
- photo_dict = photo.to_dict()
+ def test_to_dict(self, offline_photo):
+ photo_dict = offline_photo.to_dict()
assert isinstance(photo_dict, dict)
- assert photo_dict["file_id"] == photo.file_id
- assert photo_dict["file_unique_id"] == photo.file_unique_id
- assert photo_dict["width"] == photo.width
- assert photo_dict["height"] == photo.height
- assert photo_dict["file_size"] == photo.file_size
-
- def test_equality(self, photo):
- a = PhotoSize(photo.file_id, photo.file_unique_id, self.width, self.height)
- b = PhotoSize("", photo.file_unique_id, self.width, self.height)
- c = PhotoSize(photo.file_id, photo.file_unique_id, 0, 0)
+ assert photo_dict["file_id"] == offline_photo.file_id
+ assert photo_dict["file_unique_id"] == offline_photo.file_unique_id
+ assert photo_dict["width"] == offline_photo.width
+ assert photo_dict["height"] == offline_photo.height
+ assert photo_dict["file_size"] == offline_photo.file_size
+
+ def test_equality(self, offline_photo):
+ a = PhotoSize(offline_photo.file_id, offline_photo.file_unique_id, self.width, self.height)
+ b = PhotoSize("", offline_photo.file_unique_id, self.width, self.height)
+ c = PhotoSize(offline_photo.file_id, offline_photo.file_unique_id, 0, 0)
d = PhotoSize("", "", self.width, self.height)
e = Sticker(
- photo.file_id,
- photo.file_unique_id,
+ offline_photo.file_id,
+ offline_photo.file_unique_id,
self.width,
self.height,
False,
@@ -168,23 +170,25 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_send_with_photosize(self, monkeypatch, offline_bot, chat_id, photo):
+ async def test_send_with_photosize(self, monkeypatch, offline_bot, chat_id, offline_photo):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["photo"] == photo.file_id
+ return request_data.json_parameters["photo"] == offline_photo.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_photo(photo=photo, chat_id=chat_id)
+ assert await offline_bot.send_photo(photo=offline_photo, chat_id=chat_id)
- async def test_get_file_instance_method(self, monkeypatch, photo):
+ async def test_get_file_instance_method(self, monkeypatch, offline_photo):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == photo.file_id
+ return kwargs["file_id"] == offline_photo.file_id
assert check_shortcut_signature(PhotoSize.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(photo.get_file, photo.get_bot(), "get_file")
- assert await check_defaults_handling(photo.get_file, photo.get_bot())
+ assert await check_shortcut_call(
+ offline_photo.get_file, offline_photo.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_photo.get_file, offline_photo.get_bot())
- monkeypatch.setattr(photo.get_bot(), "get_file", make_assertion)
- assert await photo.get_file()
+ monkeypatch.setattr(offline_photo.get_bot(), "get_file", make_assertion)
+ assert await offline_photo.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -196,7 +200,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_photo_default_quote_parse_mode(
- self, default_bot, chat_id, photo, custom, monkeypatch
+ self, default_bot, chat_id, offline_photo, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -209,7 +213,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
kwargs["quote_parse_mode"] = custom
monkeypatch.setattr(default_bot.request, "post", make_assertion)
- await default_bot.send_photo(chat_id, photo, reply_parameters=ReplyParameters(**kwargs))
+ await default_bot.send_photo(
+ chat_id, offline_photo, reply_parameters=ReplyParameters(**kwargs)
+ )
class TestPhotoWithRequest(PhotoTestBase):
diff --git a/tests/_files/test_sticker.py b/tests/_files/test_sticker.py
index d76ce821e0f..d68597c495f 100644
--- a/tests/_files/test_sticker.py
+++ b/tests/_files/test_sticker.py
@@ -101,56 +101,72 @@ class StickerTestBase:
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}'"
- assert len(mro_slots(sticker)) == len(set(mro_slots(sticker))), "duplicate slot"
+ def test_slot_behaviour(self, offline_sticker):
+ for attr in offline_sticker.__slots__:
+ assert getattr(offline_sticker, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_sticker)) == len(set(mro_slots(offline_sticker))), (
+ "duplicate slot"
+ )
- def test_creation(self, sticker):
+ def test_creation(self, offline_sticker):
# Make sure file has been uploaded.
- assert isinstance(sticker, Sticker)
- assert isinstance(sticker.file_id, str)
- assert isinstance(sticker.file_unique_id, str)
- assert sticker.file_id
- assert sticker.file_unique_id
- assert isinstance(sticker.thumbnail, PhotoSize)
- assert isinstance(sticker.thumbnail.file_id, str)
- assert isinstance(sticker.thumbnail.file_unique_id, str)
- assert sticker.thumbnail.file_id
- assert sticker.thumbnail.file_unique_id
- assert isinstance(sticker.needs_repainting, bool)
-
- def test_expected_values(self, sticker):
- assert sticker.width == self.width
- assert sticker.height == self.height
- assert sticker.is_animated == self.is_animated
- assert sticker.is_video == self.is_video
- assert sticker.file_size == self.file_size
- assert sticker.thumbnail.width == self.thumb_width
- assert sticker.thumbnail.height == self.thumb_height
- assert sticker.thumbnail.file_size == self.thumb_file_size
- assert sticker.type == self.type
- assert sticker.needs_repainting == self.needs_repainting
+ assert isinstance(offline_sticker, Sticker)
+ assert isinstance(offline_sticker.file_id, str)
+ assert isinstance(offline_sticker.file_unique_id, str)
+ assert offline_sticker.file_id
+ assert offline_sticker.file_unique_id
+ assert isinstance(offline_sticker.thumbnail, PhotoSize)
+ assert isinstance(offline_sticker.thumbnail.file_id, str)
+ assert isinstance(offline_sticker.thumbnail.file_unique_id, str)
+ assert offline_sticker.thumbnail.file_id
+ assert offline_sticker.thumbnail.file_unique_id
+ assert isinstance(offline_sticker.needs_repainting, bool)
+
+ def test_expected_values(self, offline_sticker):
+ assert offline_sticker.width == self.width
+ assert offline_sticker.height == self.height
+ assert offline_sticker.is_animated == self.is_animated
+ assert offline_sticker.is_video == self.is_video
+ assert offline_sticker.file_size == self.file_size
+ assert offline_sticker.thumbnail.width == self.thumb_width
+ assert offline_sticker.thumbnail.height == self.thumb_height
+ assert offline_sticker.thumbnail.file_size == self.thumb_file_size
+ assert offline_sticker.type == self.type
+ assert offline_sticker.needs_repainting == self.needs_repainting
# we need to be a premium TG user to send a premium sticker, so the below is not tested
# assert sticker.premium_animation == self.premium_animation
- def test_to_dict(self, sticker):
- sticker_dict = sticker.to_dict()
+ def test_to_dict(self, offline_sticker):
+ sticker_dict = offline_sticker.to_dict()
assert isinstance(sticker_dict, dict)
- assert sticker_dict["file_id"] == sticker.file_id
- assert sticker_dict["file_unique_id"] == sticker.file_unique_id
- assert sticker_dict["width"] == sticker.width
- assert sticker_dict["height"] == sticker.height
- assert sticker_dict["is_animated"] == sticker.is_animated
- assert sticker_dict["is_video"] == sticker.is_video
- assert sticker_dict["file_size"] == sticker.file_size
- assert sticker_dict["thumbnail"] == sticker.thumbnail.to_dict()
- assert sticker_dict["type"] == sticker.type
- assert sticker_dict["needs_repainting"] == sticker.needs_repainting
-
- def test_de_json(self, offline_bot):
- json_dict = self.sticker.to_dict()
+ assert sticker_dict["file_id"] == offline_sticker.file_id
+ assert sticker_dict["file_unique_id"] == offline_sticker.file_unique_id
+ assert sticker_dict["width"] == offline_sticker.width
+ assert sticker_dict["height"] == offline_sticker.height
+ assert sticker_dict["is_animated"] == offline_sticker.is_animated
+ assert sticker_dict["is_video"] == offline_sticker.is_video
+ assert sticker_dict["file_size"] == offline_sticker.file_size
+ assert sticker_dict["thumbnail"] == offline_sticker.thumbnail.to_dict()
+ assert sticker_dict["type"] == offline_sticker.type
+ assert sticker_dict["needs_repainting"] == offline_sticker.needs_repainting
+
+ def test_de_json(self, offline_bot, offline_sticker):
+ json_dict = {
+ "file_id": self.sticker_file_id,
+ "file_unique_id": self.sticker_file_unique_id,
+ "width": self.width,
+ "height": self.height,
+ "is_animated": self.is_animated,
+ "is_video": self.is_video,
+ "thumbnail": offline_sticker.thumbnail.to_dict(),
+ "emoji": self.emoji,
+ "file_size": self.file_size,
+ "premium_animation": self.premium_animation.to_dict(),
+ "type": self.type,
+ "custom_emoji_id": self.custom_emoji_id,
+ "needs_repainting": self.needs_repainting,
+ }
json_sticker = Sticker.de_json(json_dict, offline_bot)
assert json_sticker.api_kwargs == {}
@@ -162,7 +178,7 @@ def test_de_json(self, offline_bot):
assert json_sticker.is_video == self.is_video
assert json_sticker.emoji == self.emoji
assert json_sticker.file_size == self.file_size
- assert json_sticker.thumbnail == self.thumbnail
+ assert json_sticker.thumbnail == offline_sticker.thumbnail
assert json_sticker.premium_animation == self.premium_animation
assert json_sticker.type == self.type
assert json_sticker.custom_emoji_id == self.custom_emoji_id
@@ -196,10 +212,10 @@ def test_type_enum_conversion(self):
== "unknown"
)
- def test_equality(self, sticker):
+ def test_equality(self, offline_sticker):
a = Sticker(
- sticker.file_id,
- sticker.file_unique_id,
+ offline_sticker.file_id,
+ offline_sticker.file_unique_id,
self.width,
self.height,
self.is_animated,
@@ -208,7 +224,7 @@ def test_equality(self, sticker):
)
b = Sticker(
"",
- sticker.file_unique_id,
+ offline_sticker.file_unique_id,
self.width,
self.height,
self.is_animated,
@@ -216,8 +232,8 @@ def test_equality(self, sticker):
self.type,
)
c = Sticker(
- sticker.file_id,
- sticker.file_unique_id,
+ offline_sticker.file_id,
+ offline_sticker.file_unique_id,
0,
0,
False,
@@ -234,8 +250,8 @@ def test_equality(self, sticker):
self.type,
)
e = PhotoSize(
- sticker.file_id,
- sticker.file_unique_id,
+ offline_sticker.file_id,
+ offline_sticker.file_unique_id,
self.width,
self.height,
self.is_animated,
@@ -258,12 +274,12 @@ async def test_error_without_required_args(self, offline_bot, chat_id):
with pytest.raises(TypeError):
await offline_bot.send_sticker(chat_id)
- async def test_send_with_sticker(self, monkeypatch, offline_bot, chat_id, sticker):
+ async def test_send_with_sticker(self, monkeypatch, offline_bot, chat_id, offline_sticker):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_sticker(sticker=sticker, chat_id=chat_id)
+ assert await offline_bot.send_sticker(sticker=offline_sticker, chat_id=chat_id)
@pytest.mark.parametrize("local_mode", [True, False])
async def test_send_sticker_local_files(
@@ -300,7 +316,7 @@ async def make_assertion(_, data, *args, **kwargs):
indirect=["default_bot"],
)
async def test_send_sticker_default_quote_parse_mode(
- self, default_bot, chat_id, sticker, custom, monkeypatch
+ self, default_bot, chat_id, offline_sticker, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -314,7 +330,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(default_bot.request, "post", make_assertion)
await default_bot.send_sticker(
- chat_id, sticker, reply_parameters=ReplyParameters(**kwargs)
+ chat_id, offline_sticker, reply_parameters=ReplyParameters(**kwargs)
)
@@ -520,15 +536,21 @@ 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, offline_bot):
- json_dict = self.sticker_set.to_dict()
- json_dict["contains_masks"] = self.contains_masks
+ def test_de_json(self, offline_bot, offline_sticker):
+ json_dict = {
+ "name": self.name,
+ "title": self.title,
+ "stickers": [x.to_dict() for x in self.stickers],
+ "thumbnail": offline_sticker.thumbnail.to_dict(),
+ "sticker_type": self.sticker_type,
+ "contains_masks": self.contains_masks,
+ }
sticker_set = StickerSet.de_json(json_dict, offline_bot)
assert sticker_set.name == self.name
assert sticker_set.title == self.title
assert sticker_set.stickers == tuple(self.stickers)
- assert sticker_set.thumbnail == self.thumbnail
+ assert sticker_set.thumbnail == offline_sticker.thumbnail
assert sticker_set.sticker_type == self.sticker_type
assert sticker_set.api_kwargs == {"contains_masks": self.contains_masks}
@@ -710,64 +732,76 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, sticker):
+ async def test_get_file_instance_method(self, monkeypatch, offline_sticker):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == sticker.file_id
+ return kwargs["file_id"] == offline_sticker.file_id
assert check_shortcut_signature(Sticker.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(sticker.get_file, sticker.get_bot(), "get_file")
- assert await check_defaults_handling(sticker.get_file, sticker.get_bot())
+ assert await check_shortcut_call(
+ offline_sticker.get_file, offline_sticker.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_sticker.get_file, offline_sticker.get_bot())
- monkeypatch.setattr(sticker.get_bot(), "get_file", make_assertion)
- assert await sticker.get_file()
+ monkeypatch.setattr(offline_sticker.get_bot(), "get_file", make_assertion)
+ assert await offline_sticker.get_file()
- async def test_delete_sticker_from_set_sticker_input(self, offline_bot, sticker, monkeypatch):
+ async def test_delete_sticker_from_set_sticker_input(
+ self, offline_bot, offline_sticker, monkeypatch
+ ):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.delete_sticker_from_set(sticker)
+ assert await offline_bot.delete_sticker_from_set(offline_sticker)
- async def test_replace_sticker_in_set_sticker_input(self, offline_bot, sticker, monkeypatch):
+ async def test_replace_sticker_in_set_sticker_input(
+ self, offline_bot, offline_sticker, monkeypatch
+ ):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["old_sticker"] == sticker.file_id
+ return request_data.json_parameters["old_sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
assert await offline_bot.replace_sticker_in_set(
- user_id=1, name="name", sticker="sticker", old_sticker=sticker
+ user_id=1, name="name", sticker="sticker", old_sticker=offline_sticker
)
- async def test_set_sticker_emoji_list_sticker_input(self, offline_bot, sticker, monkeypatch):
+ async def test_set_sticker_emoji_list_sticker_input(
+ self, offline_bot, offline_sticker, monkeypatch
+ ):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.set_sticker_emoji_list(sticker, ["emoji"])
+ assert await offline_bot.set_sticker_emoji_list(offline_sticker, ["emoji"])
async def test_set_sticker_mask_position_sticker_input(
- self, offline_bot, sticker, monkeypatch
+ self, offline_bot, offline_sticker, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.set_sticker_mask_position(sticker, MaskPosition("eyes", 1, 2, 3))
+ assert await offline_bot.set_sticker_mask_position(
+ offline_sticker, MaskPosition("eyes", 1, 2, 3)
+ )
async def test_set_sticker_position_in_set_sticker_input(
- self, offline_bot, sticker, monkeypatch
+ self, offline_bot, offline_sticker, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.set_sticker_position_in_set(sticker, 1)
+ assert await offline_bot.set_sticker_position_in_set(offline_sticker, 1)
- async def test_set_sticker_keywords_sticker_input(self, offline_bot, sticker, monkeypatch):
+ async def test_set_sticker_keywords_sticker_input(
+ self, offline_bot, offline_sticker, monkeypatch
+ ):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["sticker"] == sticker.file_id
+ return request_data.json_parameters["sticker"] == offline_sticker.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.set_sticker_keywords(sticker, ["keyword"])
+ assert await offline_bot.set_sticker_keywords(offline_sticker, ["keyword"])
class TestStickerSetWithRequest:
diff --git a/tests/_files/test_video.py b/tests/_files/test_video.py
index 4a34e126668..d4f1edb443e 100644
--- a/tests/_files/test_video.py
+++ b/tests/_files/test_video.py
@@ -48,20 +48,6 @@
from tests.auxil.slots import mro_slots
-# Override `video` fixture to provide start_timestamp
-@pytest.fixture(scope="module")
-async def video(bot, chat_id):
- # The `video` object returned here does not have the `qualities` attribute.
- # Tests using actual VideoQuality objects from real Telegram responses
- # are implemented separately in `test_videoquality`.
- with data_file("telegram.mp4").open("rb") as f:
- return (
- await bot.send_video(
- chat_id, video=f, start_timestamp=VideoTestBase.start_timestamp, read_timeout=50
- )
- ).video
-
-
class VideoTestBase:
width = 360
height = 640
@@ -83,32 +69,34 @@ class VideoTestBase:
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}'"
- assert len(mro_slots(video)) == len(set(mro_slots(video))), "duplicate slot"
+ def test_slot_behaviour(self, offline_video):
+ for attr in offline_video.__slots__:
+ assert getattr(offline_video, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_video)) == len(set(mro_slots(offline_video))), (
+ "duplicate slot"
+ )
- def test_creation(self, video):
+ def test_creation(self, offline_video):
# Make sure file has been uploaded.
- assert isinstance(video, Video)
- assert isinstance(video.file_id, str)
- assert isinstance(video.file_unique_id, str)
- assert video.file_id
- assert video.file_unique_id
-
- assert isinstance(video.thumbnail, PhotoSize)
- assert isinstance(video.thumbnail.file_id, str)
- assert isinstance(video.thumbnail.file_unique_id, str)
- assert video.thumbnail.file_id
- assert video.thumbnail.file_unique_id
-
- def test_expected_values(self, video):
- assert video.width == self.width
- assert video.height == self.height
- assert video._duration == self.duration
- assert video.file_size == self.file_size
- assert video.mime_type == self.mime_type
- assert video._start_timestamp == self.start_timestamp
+ assert isinstance(offline_video, Video)
+ assert isinstance(offline_video.file_id, str)
+ assert isinstance(offline_video.file_unique_id, str)
+ assert offline_video.file_id
+ assert offline_video.file_unique_id
+
+ assert isinstance(offline_video.thumbnail, PhotoSize)
+ assert isinstance(offline_video.thumbnail.file_id, str)
+ assert isinstance(offline_video.thumbnail.file_unique_id, str)
+ assert offline_video.thumbnail.file_id
+ assert offline_video.thumbnail.file_unique_id
+
+ def test_expected_values(self, offline_video):
+ assert offline_video.width == self.width
+ assert offline_video.height == self.height
+ assert offline_video._duration == self.duration
+ assert offline_video.file_size == self.file_size
+ assert offline_video.mime_type == self.mime_type
+ assert offline_video._start_timestamp == self.start_timestamp
def test_de_json(self, offline_bot):
json_dict = {
@@ -139,39 +127,39 @@ def test_de_json(self, offline_bot):
assert json_video.cover == self.cover
assert json_video.qualities == self.qualities
- def test_to_dict(self, video):
- video_dict = video.to_dict()
+ def test_to_dict(self, offline_video):
+ video_dict = offline_video.to_dict()
assert isinstance(video_dict, dict)
- assert video_dict["file_id"] == video.file_id
- assert video_dict["file_unique_id"] == video.file_unique_id
- assert video_dict["width"] == video.width
- assert video_dict["height"] == video.height
+ assert video_dict["file_id"] == offline_video.file_id
+ assert video_dict["file_unique_id"] == offline_video.file_unique_id
+ assert video_dict["width"] == offline_video.width
+ assert video_dict["height"] == offline_video.height
assert video_dict["duration"] == int(self.duration.total_seconds())
assert isinstance(video_dict["duration"], int)
- assert video_dict["mime_type"] == video.mime_type
- assert video_dict["file_size"] == video.file_size
- assert video_dict["file_name"] == video.file_name
+ assert video_dict["mime_type"] == offline_video.mime_type
+ assert video_dict["file_size"] == offline_video.file_size
+ assert video_dict["file_name"] == offline_video.file_name
assert video_dict["start_timestamp"] == int(self.start_timestamp.total_seconds())
assert isinstance(video_dict["start_timestamp"], int)
- def test_time_period_properties(self, PTB_TIMEDELTA, video):
+ def test_time_period_properties(self, PTB_TIMEDELTA, offline_video):
if PTB_TIMEDELTA:
- assert video.duration == self.duration
- assert isinstance(video.duration, dtm.timedelta)
+ assert offline_video.duration == self.duration
+ assert isinstance(offline_video.duration, dtm.timedelta)
- assert video.start_timestamp == self.start_timestamp
- assert isinstance(video.start_timestamp, dtm.timedelta)
+ assert offline_video.start_timestamp == self.start_timestamp
+ assert isinstance(offline_video.start_timestamp, dtm.timedelta)
else:
- assert video.duration == int(self.duration.total_seconds())
- assert isinstance(video.duration, int)
+ assert offline_video.duration == int(self.duration.total_seconds())
+ assert isinstance(offline_video.duration, int)
- assert video.start_timestamp == int(self.start_timestamp.total_seconds())
- assert isinstance(video.start_timestamp, int)
+ assert offline_video.start_timestamp == int(self.start_timestamp.total_seconds())
+ assert isinstance(offline_video.start_timestamp, int)
- def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, video):
- video.duration
- video.start_timestamp
+ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, offline_video):
+ offline_video.duration
+ offline_video.start_timestamp
if PTB_TIMEDELTA:
assert len(recwarn) == 0
@@ -181,12 +169,18 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, video):
assert f"`{attr}` will be of type `datetime.timedelta`" in str(recwarn[i].message)
assert recwarn[i].category is PTBDeprecationWarning
- def test_equality(self, video):
- a = Video(video.file_id, video.file_unique_id, self.width, self.height, self.duration)
- b = Video("", video.file_unique_id, self.width, self.height, self.duration)
- c = Video(video.file_id, video.file_unique_id, 0, 0, 0)
+ def test_equality(self, offline_video):
+ a = Video(
+ offline_video.file_id,
+ offline_video.file_unique_id,
+ self.width,
+ self.height,
+ self.duration,
+ )
+ b = Video("", offline_video.file_unique_id, self.width, self.height, self.duration)
+ c = Video(offline_video.file_id, offline_video.file_unique_id, 0, 0, 0)
d = Video("", "", self.width, self.height, self.duration)
- e = Voice(video.file_id, video.file_unique_id, self.duration)
+ e = Voice(offline_video.file_id, offline_video.file_unique_id, self.duration)
assert a == b
assert hash(a) == hash(b)
@@ -205,12 +199,12 @@ async def test_error_without_required_args(self, offline_bot, chat_id):
with pytest.raises(TypeError):
await offline_bot.send_video(chat_id=chat_id)
- async def test_send_with_video(self, monkeypatch, offline_bot, chat_id, video):
+ async def test_send_with_video(self, monkeypatch, offline_bot, chat_id, offline_video):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["video"] == video.file_id
+ return request_data.json_parameters["video"] == offline_video.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_video(chat_id, video=video)
+ assert await offline_bot.send_video(chat_id, video=offline_video)
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):
@@ -247,16 +241,18 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, video):
+ async def test_get_file_instance_method(self, monkeypatch, offline_video):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == video.file_id
+ return kwargs["file_id"] == offline_video.file_id
assert check_shortcut_signature(Video.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(video.get_file, video.get_bot(), "get_file")
- assert await check_defaults_handling(video.get_file, video.get_bot())
+ assert await check_shortcut_call(
+ offline_video.get_file, offline_video.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_video.get_file, offline_video.get_bot())
- monkeypatch.setattr(video.get_bot(), "get_file", make_assertion)
- assert await video.get_file()
+ monkeypatch.setattr(offline_video.get_bot(), "get_file", make_assertion)
+ assert await offline_video.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -268,7 +264,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_video_default_quote_parse_mode(
- self, default_bot, chat_id, video, custom, monkeypatch
+ self, default_bot, chat_id, offline_video, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -281,7 +277,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
kwargs["quote_parse_mode"] = custom
monkeypatch.setattr(default_bot.request, "post", make_assertion)
- await default_bot.send_video(chat_id, video, reply_parameters=ReplyParameters(**kwargs))
+ await default_bot.send_video(
+ chat_id, offline_video, reply_parameters=ReplyParameters(**kwargs)
+ )
class TestVideoWithRequest(VideoTestBase):
diff --git a/tests/_files/test_videonote.py b/tests/_files/test_videonote.py
index c2993021883..21e80b973dc 100644
--- a/tests/_files/test_videonote.py
+++ b/tests/_files/test_videonote.py
@@ -44,6 +44,28 @@ def video_note_file():
yield f
+@pytest.fixture(scope="module")
+def offline_video_note(offline_bot):
+ thumbnail = PhotoSize(
+ "thumbnail-file-id",
+ "thumbnail-file-unique-id",
+ width=VideoNoteTestBase.thumb_width,
+ height=VideoNoteTestBase.thumb_height,
+ file_size=VideoNoteTestBase.thumb_file_size,
+ )
+ thumbnail.set_bot(offline_bot)
+ value = VideoNote(
+ file_id=VideoNoteTestBase.videonote_file_id,
+ file_unique_id=VideoNoteTestBase.videonote_file_unique_id,
+ length=VideoNoteTestBase.length,
+ duration=VideoNoteTestBase.duration,
+ file_size=VideoNoteTestBase.file_size,
+ thumbnail=thumbnail,
+ )
+ value.set_bot(offline_bot)
+ return value
+
+
@pytest.fixture(scope="module")
async def video_note(bot, chat_id):
with data_file("telegram2.mp4").open("rb") as f:
@@ -63,24 +85,26 @@ class VideoNoteTestBase:
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}'"
- assert len(mro_slots(video_note)) == len(set(mro_slots(video_note))), "duplicate slot"
+ def test_slot_behaviour(self, offline_video_note):
+ for attr in offline_video_note.__slots__:
+ assert getattr(offline_video_note, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_video_note)) == len(set(mro_slots(offline_video_note))), (
+ "duplicate slot"
+ )
- def test_creation(self, video_note):
+ def test_creation(self, offline_video_note):
# Make sure file has been uploaded.
- assert isinstance(video_note, VideoNote)
- assert isinstance(video_note.file_id, str)
- assert isinstance(video_note.file_unique_id, str)
- assert video_note.file_id
- assert video_note.file_unique_id
-
- assert isinstance(video_note.thumbnail, PhotoSize)
- assert isinstance(video_note.thumbnail.file_id, str)
- assert isinstance(video_note.thumbnail.file_unique_id, str)
- assert video_note.thumbnail.file_id
- assert video_note.thumbnail.file_unique_id
+ assert isinstance(offline_video_note, VideoNote)
+ assert isinstance(offline_video_note.file_id, str)
+ assert isinstance(offline_video_note.file_unique_id, str)
+ assert offline_video_note.file_id
+ assert offline_video_note.file_unique_id
+
+ assert isinstance(offline_video_note.thumbnail, PhotoSize)
+ assert isinstance(offline_video_note.thumbnail.file_id, str)
+ assert isinstance(offline_video_note.thumbnail.file_unique_id, str)
+ assert offline_video_note.thumbnail.file_id
+ assert offline_video_note.thumbnail.file_unique_id
def test_de_json(self, offline_bot):
json_dict = {
@@ -99,27 +123,27 @@ def test_de_json(self, offline_bot):
assert json_video_note._duration == self.duration
assert json_video_note.file_size == self.file_size
- def test_to_dict(self, video_note):
- video_note_dict = video_note.to_dict()
+ def test_to_dict(self, offline_video_note):
+ video_note_dict = offline_video_note.to_dict()
assert isinstance(video_note_dict, dict)
- assert video_note_dict["file_id"] == video_note.file_id
- assert video_note_dict["file_unique_id"] == video_note.file_unique_id
- assert video_note_dict["length"] == video_note.length
+ assert video_note_dict["file_id"] == offline_video_note.file_id
+ assert video_note_dict["file_unique_id"] == offline_video_note.file_unique_id
+ assert video_note_dict["length"] == offline_video_note.length
assert video_note_dict["duration"] == int(self.duration.total_seconds())
assert isinstance(video_note_dict["duration"], int)
- assert video_note_dict["file_size"] == video_note.file_size
+ assert video_note_dict["file_size"] == offline_video_note.file_size
- def test_time_period_properties(self, PTB_TIMEDELTA, video_note):
+ def test_time_period_properties(self, PTB_TIMEDELTA, offline_video_note):
if PTB_TIMEDELTA:
- assert video_note.duration == self.duration
- assert isinstance(video_note.duration, dtm.timedelta)
+ assert offline_video_note.duration == self.duration
+ assert isinstance(offline_video_note.duration, dtm.timedelta)
else:
- assert video_note.duration == int(self.duration.total_seconds())
- assert isinstance(video_note.duration, int)
+ assert offline_video_note.duration == int(self.duration.total_seconds())
+ assert isinstance(offline_video_note.duration, int)
- def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, video_note):
- video_note.duration
+ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, offline_video_note):
+ offline_video_note.duration
if PTB_TIMEDELTA:
assert len(recwarn) == 0
@@ -128,12 +152,17 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, video_note):
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_equality(self, video_note):
- a = VideoNote(video_note.file_id, video_note.file_unique_id, self.length, self.duration)
- b = VideoNote("", video_note.file_unique_id, self.length, self.duration)
- c = VideoNote(video_note.file_id, video_note.file_unique_id, 0, 0)
+ def test_equality(self, offline_video_note):
+ a = VideoNote(
+ offline_video_note.file_id,
+ offline_video_note.file_unique_id,
+ self.length,
+ self.duration,
+ )
+ b = VideoNote("", offline_video_note.file_unique_id, self.length, self.duration)
+ c = VideoNote(offline_video_note.file_id, offline_video_note.file_unique_id, 0, 0)
d = VideoNote("", "", self.length, self.duration)
- e = Voice(video_note.file_id, video_note.file_unique_id, self.duration)
+ e = Voice(offline_video_note.file_id, offline_video_note.file_unique_id, self.duration)
assert a == b
assert hash(a) == hash(b)
@@ -152,12 +181,14 @@ async def test_error_without_required_args(self, offline_bot, chat_id):
with pytest.raises(TypeError):
await offline_bot.send_video_note(chat_id=chat_id)
- async def test_send_with_video_note(self, monkeypatch, offline_bot, chat_id, video_note):
+ async def test_send_with_video_note(
+ self, monkeypatch, offline_bot, chat_id, offline_video_note
+ ):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["video_note"] == video_note.file_id
+ return request_data.json_parameters["video_note"] == offline_video_note.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_video_note(chat_id, video_note=video_note)
+ assert await offline_bot.send_video_note(chat_id, video_note=offline_video_note)
async def test_send_video_note_custom_filename(
self, offline_bot, chat_id, video_note_file, monkeypatch
@@ -200,16 +231,20 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, video_note):
+ async def test_get_file_instance_method(self, monkeypatch, offline_video_note):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == video_note.file_id
+ return kwargs["file_id"] == offline_video_note.file_id
assert check_shortcut_signature(VideoNote.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(video_note.get_file, video_note.get_bot(), "get_file")
- assert await check_defaults_handling(video_note.get_file, video_note.get_bot())
+ assert await check_shortcut_call(
+ offline_video_note.get_file, offline_video_note.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(
+ offline_video_note.get_file, offline_video_note.get_bot()
+ )
- monkeypatch.setattr(video_note.get_bot(), "get_file", make_assertion)
- assert await video_note.get_file()
+ monkeypatch.setattr(offline_video_note.get_bot(), "get_file", make_assertion)
+ assert await offline_video_note.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -221,7 +256,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_video_note_default_quote_parse_mode(
- self, default_bot, chat_id, video_note, custom, monkeypatch
+ self, default_bot, chat_id, offline_video_note, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -235,7 +270,7 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
monkeypatch.setattr(default_bot.request, "post", make_assertion)
await default_bot.send_video_note(
- chat_id, video_note, reply_parameters=ReplyParameters(**kwargs)
+ chat_id, offline_video_note, reply_parameters=ReplyParameters(**kwargs)
)
diff --git a/tests/_files/test_videoquality.py b/tests/_files/test_videoquality.py
index 766e12f800f..35db3f70863 100644
--- a/tests/_files/test_videoquality.py
+++ b/tests/_files/test_videoquality.py
@@ -29,6 +29,20 @@ def video_quality_message_id():
return 375821
+@pytest.fixture(scope="module")
+def offline_video_quality_list(offline_bot):
+ quality = VideoQuality(
+ file_id="video-quality-file-id",
+ file_unique_id="video-quality-file-unique-id",
+ width=VideoQualityTestBase.width,
+ height=VideoQualityTestBase.height,
+ codec=VideoQualityTestBase.codec,
+ file_size=VideoQualityTestBase.file_size,
+ )
+ quality.set_bot(offline_bot)
+ return (quality,)
+
+
@pytest.fixture(scope="module")
async def video_quality_list(bot, chat_id, channel_id, video_quality_message_id):
return (
@@ -36,6 +50,11 @@ async def video_quality_list(bot, chat_id, channel_id, video_quality_message_id)
).video.qualities
+@pytest.fixture(scope="module")
+def offline_video_quality(offline_video_quality_list):
+ return offline_video_quality_list[-1]
+
+
@pytest.fixture(scope="module")
def video_quality(video_quality_list):
return video_quality_list[-1]
@@ -50,36 +69,36 @@ class VideoQualityTestBase:
class TestVideoQualityWithoutRequest(VideoQualityTestBase):
- def test_qualities_available(self, video_quality_list):
- assert isinstance(video_quality_list, tuple)
+ def test_qualities_available(self, offline_video_quality_list):
+ assert isinstance(offline_video_quality_list, tuple)
# Subsequent tests relie on the forwarded video
# having exactly one video quality.
- assert len(video_quality_list) == 1
-
- def test_slot_behaviour(self, video_quality):
- for attr in video_quality.__slots__:
- assert getattr(video_quality, attr, "err") != "err", f"got extra slot '{attr}'"
- assert len(mro_slots(video_quality)) == len(set(mro_slots(video_quality))), (
- "duplicate slot"
- )
-
- def test_creation(self, video_quality):
- assert isinstance(video_quality, VideoQuality)
- assert isinstance(video_quality.file_id, str)
- assert isinstance(video_quality.file_unique_id, str)
- assert video_quality.file_id
- assert video_quality.file_unique_id
-
- def test_expected_values(self, video_quality):
- assert video_quality.width == self.width
- assert video_quality.height == self.height
- assert video_quality.codec == self.codec
- assert video_quality.file_size == self.file_size
-
- def test_de_json(self, offline_bot, video_quality):
+ assert len(offline_video_quality_list) == 1
+
+ def test_slot_behaviour(self, offline_video_quality):
+ for attr in offline_video_quality.__slots__:
+ assert getattr(offline_video_quality, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_video_quality)) == len(
+ set(mro_slots(offline_video_quality))
+ ), "duplicate slot"
+
+ def test_creation(self, offline_video_quality):
+ assert isinstance(offline_video_quality, VideoQuality)
+ assert isinstance(offline_video_quality.file_id, str)
+ assert isinstance(offline_video_quality.file_unique_id, str)
+ assert offline_video_quality.file_id
+ assert offline_video_quality.file_unique_id
+
+ def test_expected_values(self, offline_video_quality):
+ assert offline_video_quality.width == self.width
+ assert offline_video_quality.height == self.height
+ assert offline_video_quality.codec == self.codec
+ assert offline_video_quality.file_size == self.file_size
+
+ def test_de_json(self, offline_bot, offline_video_quality):
json_dict = {
- "file_id": video_quality.file_id,
- "file_unique_id": video_quality.file_unique_id,
+ "file_id": offline_video_quality.file_id,
+ "file_unique_id": offline_video_quality.file_unique_id,
"width": self.width,
"height": self.height,
"codec": self.codec,
@@ -88,38 +107,42 @@ def test_de_json(self, offline_bot, video_quality):
json_videoquality = VideoQuality.de_json(json_dict, offline_bot)
assert json_videoquality.api_kwargs == {}
- assert json_videoquality.file_id == video_quality.file_id
- assert json_videoquality.file_unique_id == video_quality.file_unique_id
+ assert json_videoquality.file_id == offline_video_quality.file_id
+ assert json_videoquality.file_unique_id == offline_video_quality.file_unique_id
assert json_videoquality.width == self.width
assert json_videoquality.height == self.height
assert json_videoquality.codec == self.codec
assert json_videoquality.file_size == self.file_size
- def test_to_dict(self, video_quality):
- videoquality_dict = video_quality.to_dict()
+ def test_to_dict(self, offline_video_quality):
+ videoquality_dict = offline_video_quality.to_dict()
assert isinstance(videoquality_dict, dict)
- assert videoquality_dict["file_id"] == video_quality.file_id
- assert videoquality_dict["file_unique_id"] == video_quality.file_unique_id
- assert videoquality_dict["width"] == video_quality.width
- assert videoquality_dict["height"] == video_quality.height
- assert videoquality_dict["codec"] == video_quality.codec
- assert videoquality_dict["file_size"] == video_quality.file_size
-
- def test_equality(self, video_quality):
+ assert videoquality_dict["file_id"] == offline_video_quality.file_id
+ assert videoquality_dict["file_unique_id"] == offline_video_quality.file_unique_id
+ assert videoquality_dict["width"] == offline_video_quality.width
+ assert videoquality_dict["height"] == offline_video_quality.height
+ assert videoquality_dict["codec"] == offline_video_quality.codec
+ assert videoquality_dict["file_size"] == offline_video_quality.file_size
+
+ def test_equality(self, offline_video_quality):
a = VideoQuality(
- video_quality.file_id,
- video_quality.file_unique_id,
+ offline_video_quality.file_id,
+ offline_video_quality.file_unique_id,
self.width,
self.height,
self.codec,
)
- b = VideoQuality("", video_quality.file_unique_id, self.width, self.height, self.codec)
- c = VideoQuality(video_quality.file_id, video_quality.file_unique_id, 0, 0, self.codec)
+ b = VideoQuality(
+ "", offline_video_quality.file_unique_id, self.width, self.height, self.codec
+ )
+ c = VideoQuality(
+ offline_video_quality.file_id, offline_video_quality.file_unique_id, 0, 0, self.codec
+ )
d = VideoQuality("", "", self.width, self.height, self.codec)
e = PhotoSize(
- video_quality.file_id,
- video_quality.file_unique_id,
+ offline_video_quality.file_id,
+ offline_video_quality.file_unique_id,
self.width,
self.height,
)
diff --git a/tests/_files/test_voice.py b/tests/_files/test_voice.py
index e1e47759db9..a2662cdc491 100644
--- a/tests/_files/test_voice.py
+++ b/tests/_files/test_voice.py
@@ -45,6 +45,19 @@ def voice_file():
yield f
+@pytest.fixture(scope="module")
+def offline_voice(offline_bot):
+ value = Voice(
+ file_id=VoiceTestBase.voice_file_id,
+ file_unique_id=VoiceTestBase.voice_file_unique_id,
+ duration=VoiceTestBase.duration,
+ mime_type=VoiceTestBase.mime_type,
+ file_size=VoiceTestBase.file_size,
+ )
+ value.set_bot(offline_bot)
+ return value
+
+
@pytest.fixture(scope="module")
async def voice(bot, chat_id):
with data_file("telegram.ogg").open("rb") as f:
@@ -62,23 +75,25 @@ class VoiceTestBase:
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}'"
- assert len(mro_slots(voice)) == len(set(mro_slots(voice))), "duplicate slot"
+ def test_slot_behaviour(self, offline_voice):
+ for attr in offline_voice.__slots__:
+ assert getattr(offline_voice, attr, "err") != "err", f"got extra slot '{attr}'"
+ assert len(mro_slots(offline_voice)) == len(set(mro_slots(offline_voice))), (
+ "duplicate slot"
+ )
- async def test_creation(self, voice):
+ async def test_creation(self, offline_voice):
# Make sure file has been uploaded.
- assert isinstance(voice, Voice)
- assert isinstance(voice.file_id, str)
- assert isinstance(voice.file_unique_id, str)
- assert voice.file_id
- assert voice.file_unique_id
+ assert isinstance(offline_voice, Voice)
+ assert isinstance(offline_voice.file_id, str)
+ assert isinstance(offline_voice.file_unique_id, str)
+ assert offline_voice.file_id
+ assert offline_voice.file_unique_id
- def test_expected_values(self, voice):
- assert voice._duration == self.duration
- assert voice.mime_type == self.mime_type
- assert voice.file_size == self.file_size
+ def test_expected_values(self, offline_voice):
+ assert offline_voice._duration == self.duration
+ assert offline_voice.mime_type == self.mime_type
+ assert offline_voice.file_size == self.file_size
def test_de_json(self, offline_bot):
json_dict = {
@@ -97,27 +112,27 @@ def test_de_json(self, offline_bot):
assert json_voice.mime_type == self.mime_type
assert json_voice.file_size == self.file_size
- def test_to_dict(self, voice):
- voice_dict = voice.to_dict()
+ def test_to_dict(self, offline_voice):
+ voice_dict = offline_voice.to_dict()
assert isinstance(voice_dict, dict)
- assert voice_dict["file_id"] == voice.file_id
- assert voice_dict["file_unique_id"] == voice.file_unique_id
+ assert voice_dict["file_id"] == offline_voice.file_id
+ assert voice_dict["file_unique_id"] == offline_voice.file_unique_id
assert voice_dict["duration"] == int(self.duration.total_seconds())
assert isinstance(voice_dict["duration"], int)
- assert voice_dict["mime_type"] == voice.mime_type
- assert voice_dict["file_size"] == voice.file_size
+ assert voice_dict["mime_type"] == offline_voice.mime_type
+ assert voice_dict["file_size"] == offline_voice.file_size
- def test_time_period_properties(self, PTB_TIMEDELTA, voice):
+ def test_time_period_properties(self, PTB_TIMEDELTA, offline_voice):
if PTB_TIMEDELTA:
- assert voice.duration == self.duration
- assert isinstance(voice.duration, dtm.timedelta)
+ assert offline_voice.duration == self.duration
+ assert isinstance(offline_voice.duration, dtm.timedelta)
else:
- assert voice.duration == int(self.duration.total_seconds())
- assert isinstance(voice.duration, int)
+ assert offline_voice.duration == int(self.duration.total_seconds())
+ assert isinstance(offline_voice.duration, int)
- def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, voice):
- voice.duration
+ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, offline_voice):
+ offline_voice.duration
if PTB_TIMEDELTA:
assert len(recwarn) == 0
@@ -126,12 +141,12 @@ def test_time_period_int_deprecated(self, recwarn, PTB_TIMEDELTA, voice):
assert "`duration` will be of type `datetime.timedelta`" in str(recwarn[0].message)
assert recwarn[0].category is PTBDeprecationWarning
- def test_equality(self, voice):
- a = Voice(voice.file_id, voice.file_unique_id, self.duration)
- b = Voice("", voice.file_unique_id, self.duration)
- c = Voice(voice.file_id, voice.file_unique_id, 0)
+ def test_equality(self, offline_voice):
+ a = Voice(offline_voice.file_id, offline_voice.file_unique_id, self.duration)
+ b = Voice("", offline_voice.file_unique_id, self.duration)
+ c = Voice(offline_voice.file_id, offline_voice.file_unique_id, 0)
d = Voice("", "", self.duration)
- e = Audio(voice.file_id, voice.file_unique_id, self.duration)
+ e = Audio(offline_voice.file_id, offline_voice.file_unique_id, self.duration)
assert a == b
assert hash(a) == hash(b)
@@ -158,12 +173,12 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert await offline_bot.send_voice(chat_id, voice_file, filename="custom_filename")
- async def test_send_with_voice(self, monkeypatch, offline_bot, chat_id, voice):
+ async def test_send_with_voice(self, monkeypatch, offline_bot, chat_id, offline_voice):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
- return request_data.json_parameters["voice"] == voice.file_id
+ return request_data.json_parameters["voice"] == offline_voice.file_id
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
- assert await offline_bot.send_voice(chat_id, voice=voice)
+ assert await offline_bot.send_voice(chat_id, voice=offline_voice)
@pytest.mark.parametrize("local_mode", [True, False])
async def test_send_voice_local_files(
@@ -190,16 +205,18 @@ async def make_assertion(_, data, *args, **kwargs):
finally:
offline_bot._local_mode = False
- async def test_get_file_instance_method(self, monkeypatch, voice):
+ async def test_get_file_instance_method(self, monkeypatch, offline_voice):
async def make_assertion(*_, **kwargs):
- return kwargs["file_id"] == voice.file_id
+ return kwargs["file_id"] == offline_voice.file_id
assert check_shortcut_signature(Voice.get_file, Bot.get_file, ["file_id"], [])
- assert await check_shortcut_call(voice.get_file, voice.get_bot(), "get_file")
- assert await check_defaults_handling(voice.get_file, voice.get_bot())
+ assert await check_shortcut_call(
+ offline_voice.get_file, offline_voice.get_bot(), "get_file"
+ )
+ assert await check_defaults_handling(offline_voice.get_file, offline_voice.get_bot())
- monkeypatch.setattr(voice.get_bot(), "get_file", make_assertion)
- assert await voice.get_file()
+ monkeypatch.setattr(offline_voice.get_bot(), "get_file", make_assertion)
+ assert await offline_voice.get_file()
@pytest.mark.parametrize(
("default_bot", "custom"),
@@ -211,7 +228,7 @@ async def make_assertion(*_, **kwargs):
indirect=["default_bot"],
)
async def test_send_voice_default_quote_parse_mode(
- self, default_bot, chat_id, voice, custom, monkeypatch
+ self, default_bot, chat_id, offline_voice, custom, monkeypatch
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
assert request_data.parameters["reply_parameters"].get("quote_parse_mode") == (
@@ -224,7 +241,9 @@ async def make_assertion(url, request_data: RequestData, *args, **kwargs):
kwargs["quote_parse_mode"] = custom
monkeypatch.setattr(default_bot.request, "post", make_assertion)
- await default_bot.send_voice(chat_id, voice, reply_parameters=ReplyParameters(**kwargs))
+ await default_bot.send_voice(
+ chat_id, offline_voice, reply_parameters=ReplyParameters(**kwargs)
+ )
class TestVoiceWithRequest(VoiceTestBase):
diff --git a/tests/conftest.py b/tests/conftest.py
index ed0c3f64231..583642db929 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -38,9 +38,9 @@
)
from telegram.ext import Defaults
from tests.auxil.build_messages import DATE, make_message
-from tests.auxil.ci_bots import BOT_INFO_PROVIDER, JOB_INDEX
+from tests.auxil.ci_bots import BOT_INFO_PROVIDER
from tests.auxil.constants import PRIVATE_KEY, TEST_TOPIC_ICON_COLOR, TEST_TOPIC_NAME
-from tests.auxil.envvars import GITHUB_ACTIONS, TEST_WITH_OPT_DEPS, env_var_2_bool
+from tests.auxil.envvars import TEST_WITH_OPT_DEPS, env_var_2_bool
from tests.auxil.files import data_file
from tests.auxil.networking import NonchalantHttpxRequest
from tests.auxil.pytest_classes import PytestBot, make_bot
@@ -86,38 +86,11 @@ def pytest_collection_modifyitems(items: list[pytest.Item]):
):
parent.add_marker(pytest.mark.no_req)
-
-if GITHUB_ACTIONS 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."
- )
+ if item.get_closest_marker(name="no_req"):
+ # Applying this marker here instead of through a function-scoped fixture ensures that
+ # external network access is already blocked while higher-scoped fixtures are being
+ # set up. Loopback must remain available because some tests use it
+ item.add_marker(pytest.mark.allow_hosts(["localhost", "127.0.0.1", "::1"]))
@pytest.fixture(scope="module", params=["true", "1", "false", "gibberish", None])
@@ -265,6 +238,11 @@ def class_thumb_file():
yield f
+@pytest.fixture(scope="session")
+def offline_emoji_id():
+ return "5368324170671202286"
+
+
@pytest.fixture(scope="session")
async def emoji_id(bot):
emoji_sticker_list = await bot.get_forum_topic_icon_stickers()
diff --git a/tests/ext/test_application.py b/tests/ext/test_application.py
index c26e8b3f32a..933cc0b0a78 100644
--- a/tests/ext/test_application.py
+++ b/tests/ext/test_application.py
@@ -2329,29 +2329,36 @@ async def test_run_polling_webhook_bootstrap_retries(
"""
def thread_target():
- asyncio.set_event_loop(asyncio.new_event_loop())
- app = (
- ApplicationBuilder().bot(offline_bot).application_class(PytestApplication).build()
- )
+ loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(loop)
+ try:
+ app = (
+ ApplicationBuilder()
+ .bot(offline_bot)
+ .application_class(PytestApplication)
+ .build()
+ )
- async def initialize(*args, **kwargs):
- self.count += 1
- raise exception_class(str(self.count))
+ async def initialize(*args, **kwargs):
+ self.count += 1
+ raise exception_class(str(self.count))
- monkeypatch.setattr(app, "initialize", initialize)
- method = functools.partial(
- getattr(app, method_name),
- bootstrap_retries=retries,
- close_loop=False,
- stop_signals=None,
- )
+ monkeypatch.setattr(app, "initialize", initialize)
+ method = functools.partial(
+ getattr(app, method_name),
+ bootstrap_retries=retries,
+ close_loop=False,
+ stop_signals=None,
+ )
- if exception_class == InvalidToken:
- with pytest.raises(InvalidToken, match="1"):
- method()
- else:
- with pytest.raises(TelegramError, match=str(retries + 1)):
- method()
+ if exception_class == InvalidToken:
+ with pytest.raises(InvalidToken, match="1"):
+ method()
+ else:
+ with pytest.raises(TelegramError, match=str(retries + 1)):
+ method()
+ finally:
+ loop.close()
thread = Thread(target=thread_target)
thread.start()
@@ -2368,42 +2375,46 @@ async def test_run_polling_webhook_infinite_bootstrap_retries(
"""
def thread_target():
- asyncio.set_event_loop(asyncio.new_event_loop())
+ loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(loop)
+ try:
- async def post_init(application):
- application.stop_running()
+ async def post_init(application):
+ application.stop_running()
- app = (
- ApplicationBuilder()
- .bot(offline_bot)
- .application_class(PytestApplication)
- .post_init(post_init)
- .build()
- )
+ app = (
+ ApplicationBuilder()
+ .bot(offline_bot)
+ .application_class(PytestApplication)
+ .post_init(post_init)
+ .build()
+ )
- async def do_pass(*args, **kwargs):
- pass
+ async def do_pass(*args, **kwargs):
+ pass
- monkeypatch.setattr(app.bot, "initialize", do_pass)
- monkeypatch.setattr(app.bot, "delete_webhook", do_pass)
+ monkeypatch.setattr(app.bot, "initialize", do_pass)
+ monkeypatch.setattr(app.bot, "delete_webhook", do_pass)
- original_initialize = app.initialize
+ original_initialize = app.initialize
- async def initialize(*args, **kwargs):
- if self.count >= 3:
- pytest.fail("Should be called only once. Test failed.")
+ async def initialize(*args, **kwargs):
+ if self.count >= 3:
+ pytest.fail("Should be called only once. Test failed.")
- self.count += 1
- if self.count == 1:
- raise TelegramError("Test Exception")
- await original_initialize(*args, **kwargs)
+ self.count += 1
+ if self.count == 1:
+ raise TelegramError("Test Exception")
+ await original_initialize(*args, **kwargs)
- monkeypatch.setattr(app, "initialize", initialize)
- getattr(app, method_name)(
- bootstrap_retries=-1,
- close_loop=False,
- stop_signals=None,
- )
+ monkeypatch.setattr(app, "initialize", initialize)
+ getattr(app, method_name)(
+ bootstrap_retries=-1,
+ close_loop=False,
+ stop_signals=None,
+ )
+ finally:
+ loop.close()
thread = Thread(target=thread_target)
thread.start()
diff --git a/tests/request/test_request.py b/tests/request/test_request.py
index a0d71544aa3..d1b416166b4 100644
--- a/tests/request/test_request.py
+++ b/tests/request/test_request.py
@@ -246,21 +246,22 @@ async def test_chat_migrated(self, monkeypatch, httpx_request: HTTPXRequest):
assert exc_info.value.new_chat_id == 123
- async def test_retry_after(self, monkeypatch, httpx_request: HTTPXRequest, PTB_TIMEDELTA):
+ async def test_retry_after(self, monkeypatch, PTB_TIMEDELTA):
server_response = b'{"ok": "False", "parameters": {"retry_after": 42}}'
- monkeypatch.setattr(
- httpx_request,
- "do_request",
- mocker_factory(response=server_response, return_code=HTTPStatus.BAD_REQUEST),
- )
+ async with HTTPXRequest() as httpx_request:
+ monkeypatch.setattr(
+ HTTPXRequest,
+ "do_request",
+ mocker_factory(response=server_response, return_code=HTTPStatus.BAD_REQUEST),
+ )
- with pytest.raises(
- RetryAfter, match="Retry in " + "0:00:42" if PTB_TIMEDELTA else "42"
- ) as exc_info:
- await httpx_request.post(None, None, None)
+ with pytest.raises(
+ RetryAfter, match="Retry in " + "0:00:42" if PTB_TIMEDELTA else "42"
+ ) as exc_info:
+ await httpx_request.post(None, None, None)
- assert exc_info.value.retry_after == (dtm.timdelta(seconds=42) if PTB_TIMEDELTA else 42)
+ assert exc_info.value.retry_after == (dtm.timedelta(seconds=42) if PTB_TIMEDELTA else 42)
async def test_unknown_request_params(self, monkeypatch, httpx_request: HTTPXRequest):
server_response = b'{"ok": "False", "parameters": {"unknown": "42"}}'
diff --git a/tests/test_bot.py b/tests/test_bot.py
index 58b57d3d469..d093ffa6df9 100644
--- a/tests/test_bot.py
+++ b/tests/test_bot.py
@@ -135,6 +135,11 @@ async def static_message(bot, chat_id):
)
+@pytest.fixture
+def offline_media_message(offline_bot):
+ return make_message("", bot=offline_bot, caption="my caption")
+
+
@pytest.fixture
async def media_message(bot, chat_id):
# mostly used in tests for edit_message and hence can't be reused
@@ -494,7 +499,11 @@ async def test_equality(self):
async with (
make_bot(token=FALLBACKS[0]["token"]) as a,
make_bot(token=FALLBACKS[0]["token"]) as b,
- Bot(token=FALLBACKS[0]["token"]) as c,
+ PytestBot(
+ token=FALLBACKS[0]["token"],
+ request=OfflineRequest(),
+ get_updates_request=OfflineRequest(),
+ ) as c,
make_bot(token=FALLBACKS[1]["token"]) as d,
):
e = Update(123456789)
@@ -539,7 +548,7 @@ async def test_get_me_and_properties_not_initialized(self, attribute):
await bot.shutdown()
async def test_get_me_and_properties(self, offline_bot):
- get_me_bot = await ExtBot(offline_bot.token).get_me()
+ get_me_bot = await offline_bot.get_me()
assert isinstance(get_me_bot, User)
assert get_me_bot.id == offline_bot.id
@@ -563,8 +572,20 @@ def test_bot_deepcopy_error(self, offline_bot):
@pytest.mark.parametrize(
("cls", "logger_name"), [(Bot, "telegram.Bot"), (ExtBot, "telegram.ext.ExtBot")]
)
- async def test_bot_method_logging(self, offline_bot: PytestExtBot, cls, logger_name, caplog):
- instance = cls(offline_bot.token)
+ async def test_bot_method_logging(
+ self, monkeypatch, offline_bot: PytestExtBot, cls, logger_name, caplog
+ ):
+ request = OfflineRequest()
+ instance = cls(
+ offline_bot.token,
+ request=request,
+ get_updates_request=OfflineRequest(),
+ )
+
+ async def post(*args, **kwargs):
+ return offline_bot.bot.to_dict()
+
+ monkeypatch.setattr(request, "post", post)
# Second argument makes sure that we ignore logs from e.g. httpx
with caplog.at_level(logging.DEBUG, logger="telegram"):
await instance.get_me()
@@ -1877,7 +1898,7 @@ async def assertion(url, request_data: RequestData, *args, **kwargs):
@pytest.mark.parametrize("json_keyboard", [True, False])
@pytest.mark.parametrize("caption", ["Test", "", None])
async def test_copy_message(
- self, monkeypatch, offline_bot, chat_id, media_message, json_keyboard, caption
+ self, monkeypatch, offline_bot, chat_id, offline_media_message, json_keyboard, caption
):
keyboard = InlineKeyboardMarkup(
[[InlineKeyboardButton(text="test", callback_data="test2")]]
@@ -1889,11 +1910,11 @@ async def post(url, request_data: RequestData, *args, **kwargs):
[
data["chat_id"] == chat_id,
data["from_chat_id"] == chat_id,
- data["message_id"] == media_message.message_id,
+ data["message_id"] == offline_media_message.message_id,
data.get("caption") == caption,
data["parse_mode"] == ParseMode.HTML,
data["reply_parameters"]
- == ReplyParameters(message_id=media_message.message_id).to_dict(),
+ == ReplyParameters(message_id=offline_media_message.message_id).to_dict(),
(
data["reply_markup"] == keyboard.to_json()
if json_keyboard
@@ -1914,12 +1935,12 @@ async def post(url, request_data: RequestData, *args, **kwargs):
await offline_bot.copy_message(
chat_id,
from_chat_id=chat_id,
- message_id=media_message.message_id,
+ message_id=offline_media_message.message_id,
caption=caption,
video_start_timestamp=999,
caption_entities=[MessageEntity(MessageEntity.BOLD, 0, 4)],
parse_mode=ParseMode.HTML,
- reply_to_message_id=media_message.message_id,
+ reply_to_message_id=offline_media_message.message_id,
reply_markup=keyboard.to_json() if json_keyboard else keyboard,
disable_notification=True,
protect_content=True,
diff --git a/tests/test_forum.py b/tests/test_forum.py
index 73d20c6d786..2a16a17646c 100644
--- a/tests/test_forum.py
+++ b/tests/test_forum.py
@@ -47,6 +47,17 @@ async def forum_topic_object(forum_group_id, emoji_id):
)
+@pytest.fixture(scope="module")
+async def offline_forum_topic_object(forum_group_id, offline_emoji_id):
+ return ForumTopic(
+ message_thread_id=forum_group_id,
+ name=ForumTopicTestBase.TEST_TOPIC_NAME,
+ icon_color=ForumTopicTestBase.TEST_TOPIC_ICON_COLOR,
+ icon_custom_emoji_id=offline_emoji_id,
+ is_name_implicit=ForumTopicTestBase.is_name_implicit,
+ )
+
+
class ForumTopicTestBase:
TEST_TOPIC_NAME = TEST_TOPIC_NAME
TEST_TOPIC_ICON_COLOR = TEST_TOPIC_ICON_COLOR
@@ -54,25 +65,27 @@ class ForumTopicTestBase:
class TestForumTopicWithoutRequest(ForumTopicTestBase):
- def test_slot_behaviour(self, forum_topic_object):
- inst = forum_topic_object
+ def test_slot_behaviour(self, offline_forum_topic_object):
+ inst = offline_forum_topic_object
for attr in inst.__slots__:
assert getattr(inst, attr, "err") != "err", f"got extra slot '{attr}'"
assert len(mro_slots(inst)) == len(set(mro_slots(inst))), "duplicate slot"
- async def test_expected_values(self, emoji_id, forum_group_id, forum_topic_object):
- assert forum_topic_object.message_thread_id == forum_group_id
- assert forum_topic_object.icon_color == self.TEST_TOPIC_ICON_COLOR
- assert forum_topic_object.name == self.TEST_TOPIC_NAME
- assert forum_topic_object.icon_custom_emoji_id == emoji_id
- assert forum_topic_object.is_name_implicit == self.is_name_implicit
+ async def test_expected_values(
+ self, offline_emoji_id, forum_group_id, offline_forum_topic_object
+ ):
+ assert offline_forum_topic_object.message_thread_id == forum_group_id
+ assert offline_forum_topic_object.icon_color == self.TEST_TOPIC_ICON_COLOR
+ assert offline_forum_topic_object.name == self.TEST_TOPIC_NAME
+ assert offline_forum_topic_object.icon_custom_emoji_id == offline_emoji_id
+ assert offline_forum_topic_object.is_name_implicit == self.is_name_implicit
- def test_de_json(self, offline_bot, emoji_id, forum_group_id):
+ def test_de_json(self, offline_bot, offline_emoji_id, forum_group_id):
json_dict = {
"message_thread_id": forum_group_id,
"name": self.TEST_TOPIC_NAME,
"icon_color": self.TEST_TOPIC_ICON_COLOR,
- "icon_custom_emoji_id": emoji_id,
+ "icon_custom_emoji_id": offline_emoji_id,
"is_name_implicit": self.is_name_implicit,
}
topic = ForumTopic.de_json(json_dict, offline_bot)
@@ -81,20 +94,20 @@ def test_de_json(self, offline_bot, emoji_id, forum_group_id):
assert topic.message_thread_id == forum_group_id
assert topic.icon_color == self.TEST_TOPIC_ICON_COLOR
assert topic.name == self.TEST_TOPIC_NAME
- assert topic.icon_custom_emoji_id == emoji_id
+ assert topic.icon_custom_emoji_id == offline_emoji_id
assert topic.is_name_implicit == self.is_name_implicit
- def test_to_dict(self, emoji_id, forum_group_id, forum_topic_object):
- topic_dict = forum_topic_object.to_dict()
+ def test_to_dict(self, offline_emoji_id, forum_group_id, offline_forum_topic_object):
+ topic_dict = offline_forum_topic_object.to_dict()
assert isinstance(topic_dict, dict)
assert topic_dict["message_thread_id"] == forum_group_id
assert topic_dict["name"] == self.TEST_TOPIC_NAME
assert topic_dict["icon_color"] == self.TEST_TOPIC_ICON_COLOR
- assert topic_dict["icon_custom_emoji_id"] == emoji_id
+ assert topic_dict["icon_custom_emoji_id"] == offline_emoji_id
assert topic_dict["is_name_implicit"] == self.is_name_implicit
- def test_equality(self, emoji_id, forum_group_id):
+ def test_equality(self, offline_emoji_id, forum_group_id):
a = ForumTopic(
message_thread_id=forum_group_id,
name=TEST_TOPIC_NAME,
@@ -104,7 +117,7 @@ def test_equality(self, emoji_id, forum_group_id):
message_thread_id=forum_group_id,
name=TEST_TOPIC_NAME,
icon_color=TEST_TOPIC_ICON_COLOR,
- icon_custom_emoji_id=emoji_id,
+ icon_custom_emoji_id=offline_emoji_id,
)
c = ForumTopic(
message_thread_id=forum_group_id,
@@ -347,12 +360,12 @@ def test_to_dict(self, topic_created):
assert action_dict["icon_color"] == self.TEST_TOPIC_ICON_COLOR
assert action_dict["is_name_implicit"] == self.is_name_implicit
- def test_equality(self, emoji_id):
+ def test_equality(self, offline_emoji_id):
a = ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=TEST_TOPIC_ICON_COLOR)
b = ForumTopicCreated(
name=TEST_TOPIC_NAME,
icon_color=TEST_TOPIC_ICON_COLOR,
- icon_custom_emoji_id=emoji_id,
+ icon_custom_emoji_id=offline_emoji_id,
)
c = ForumTopicCreated(name=f"{TEST_TOPIC_NAME}!", icon_color=TEST_TOPIC_ICON_COLOR)
d = ForumTopicCreated(name=TEST_TOPIC_NAME, icon_color=0xFFD67E)
diff --git a/uv.lock b/uv.lock
index a9fa6193c9e..65c2fd91aad 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1485,6 +1485,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" },
]
+[[package]]
+name = "pytest-socket"
+version = "0.8.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "pytest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/59/3c/f9b58e57830e58980dbe8867d0e348f45701d3f3ea065672d448f4366da5/pytest_socket-0.8.0.tar.gz", hash = "sha256:af9bb5f487da72be63573a6194cfac033b6c7a1c1561e150521105970f9e99f2", size = 13912, upload-time = "2026-05-21T16:50:22.552Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3f/e8/4a8568580bae3dcd678599ed8e86a82d505a44df71c1ced4246c1aa14b4b/pytest_socket-0.8.0-py3-none-any.whl", hash = "sha256:81821ba59f07d7600fe2b551d8714f40b068bd46e8b6704c48664e9d60cdacb8", size = 8414, upload-time = "2026-05-21T16:50:21.022Z" },
+]
+
[[package]]
name = "pytest-xdist"
version = "3.8.0"
@@ -1568,6 +1580,7 @@ all = [
{ name = "pytest" },
{ name = "pytest-asyncio" },
{ name = "pytest-cov" },
+ { name = "pytest-socket" },
{ name = "pytest-xdist" },
{ name = "pytz" },
{ name = "ruff" },
@@ -1603,6 +1616,7 @@ tests = [
{ name = "pytest" },
{ name = "pytest-asyncio" },
{ name = "pytest-cov" },
+ { name = "pytest-socket" },
{ name = "pytest-xdist" },
{ name = "pytz" },
{ name = "tzdata" },
@@ -1649,6 +1663,7 @@ all = [
{ name = "pytest", specifier = "==9.1.1" },
{ name = "pytest-asyncio", specifier = "==0.21.2" },
{ name = "pytest-cov" },
+ { name = "pytest-socket", specifier = "==0.8.0" },
{ name = "pytest-xdist", specifier = "==3.8.0" },
{ name = "pytz" },
{ name = "ruff", specifier = "==0.15.22" },
@@ -1684,6 +1699,7 @@ tests = [
{ name = "pytest", specifier = "==9.1.1" },
{ name = "pytest-asyncio", specifier = "==0.21.2" },
{ name = "pytest-cov" },
+ { name = "pytest-socket", specifier = "==0.8.0" },
{ name = "pytest-xdist", specifier = "==3.8.0" },
{ name = "pytz" },
{ name = "tzdata" },