From 06bdae69c202787d94e4adb64d59fc7c8ff8a7ac Mon Sep 17 00:00:00 2001 From: Kostiantyn Kriuchkov <36363097+Latand@users.noreply.github.com> Date: Tue, 10 Feb 2026 23:22:36 +0200 Subject: [PATCH] Fix review issues from PR #1761 (#1762) * Fix review issues from PR #1761 - Remove stray '-' artifact from GameHighScore docstring - Fix Makefile reformat target scope inconsistency (ruff check --fix) - Add User.get_profile_audios() shortcut method (parallel to get_profile_photos) - Test ChatOwnerLeft with new_owner=None (edge case) - Add VideoQuality type and Video.qualities nesting tests - Add User.get_profile_audios() test Co-Authored-By: Claude Opus 4.6 * Address review comments: use fixture and variables in tests, add changelog Co-Authored-By: Claude Opus 4.6 * Address review follow-ups for PR #1762 --------- Co-authored-by: Claude Opus 4.6 --- .butcher/types/User/aliases.yml | 4 ++ CHANGES/1761.feature.rst | 1 + Makefile | 2 +- aiogram/types/user.py | 34 ++++++++++- tests/test_api/test_types/test_message.py | 13 ++++ tests/test_api/test_types/test_user.py | 6 ++ .../test_api/test_types/test_video_quality.py | 61 +++++++++++++++++++ 7 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 tests/test_api/test_types/test_video_quality.py diff --git a/.butcher/types/User/aliases.yml b/.butcher/types/User/aliases.yml index 85d2188d..51e3e370 100644 --- a/.butcher/types/User/aliases.yml +++ b/.butcher/types/User/aliases.yml @@ -2,3 +2,7 @@ get_profile_photos: method: getUserProfilePhotos fill: user_id: self.id +get_profile_audios: + method: getUserProfileAudios + fill: + user_id: self.id diff --git a/CHANGES/1761.feature.rst b/CHANGES/1761.feature.rst index 5b3fd4bb..2cdf9da4 100644 --- a/CHANGES/1761.feature.rst +++ b/CHANGES/1761.feature.rst @@ -23,6 +23,7 @@ Updated to Bot API 9.4 (February 9, 2026) - Added :class:`aiogram.methods.set_my_profile_photo.SetMyProfilePhoto` method - allows bots to set their profile photo - Added :class:`aiogram.methods.remove_my_profile_photo.RemoveMyProfilePhoto` method - allows bots to remove their profile photo - Added :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` method - retrieves a user's profile audio list +- Added :meth:`aiogram.types.user.User.get_profile_audios` shortcut - creates a prefilled :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` request with :code:`user_id` **New Types:** diff --git a/Makefile b/Makefile index c41fb986..a92db1f8 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ lint: .PHONY: reformat reformat: uv run ruff format $(code_dir) - uv run ruff check --fix $(package_dir) + uv run ruff check --fix $(code_dir) # ================================================================================================= # Tests diff --git a/aiogram/types/user.py b/aiogram/types/user.py index 00da8e5c..7f03504c 100644 --- a/aiogram/types/user.py +++ b/aiogram/types/user.py @@ -7,7 +7,7 @@ from ..utils.link import create_tg_link from .base import TelegramObject if TYPE_CHECKING: - from ..methods import GetUserProfilePhotos + from ..methods import GetUserProfileAudios, GetUserProfilePhotos class User(TelegramObject): @@ -146,3 +146,35 @@ class User(TelegramObject): limit=limit, **kwargs, ).as_(self._bot) + + def get_profile_audios( + self, + offset: int | None = None, + limit: int | None = None, + **kwargs: Any, + ) -> GetUserProfileAudios: + """ + Shortcut for method :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` + will automatically fill method attributes: + + - :code:`user_id` + + Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object. + + Source: https://core.telegram.org/bots/api#getuserprofileaudios + + :param offset: Sequential number of the first audio to be returned. By default, all audios are returned. + :param limit: Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100. + :return: instance of method :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` + """ + # DO NOT EDIT MANUALLY!!! + # This method was auto-generated via `butcher` + + from aiogram.methods import GetUserProfileAudios + + return GetUserProfileAudios( + user_id=self.id, + offset=offset, + limit=limit, + **kwargs, + ).as_(self._bot) diff --git a/tests/test_api/test_types/test_message.py b/tests/test_api/test_types/test_message.py index f3aac34a..c7fad1ab 100644 --- a/tests/test_api/test_types/test_message.py +++ b/tests/test_api/test_types/test_message.py @@ -264,6 +264,13 @@ TEST_MESSAGE_CHAT_OWNER_LEFT = Message( chat=Chat(id=42, type="private"), from_user=User(id=42, is_bot=False, first_name="Test"), ) +TEST_MESSAGE_CHAT_OWNER_LEFT_NO_SUCCESSOR = Message( + message_id=42, + date=datetime.datetime.now(), + chat_owner_left=ChatOwnerLeft(), + chat=Chat(id=42, type="private"), + from_user=User(id=42, is_bot=False, first_name="Test"), +) TEST_MESSAGE_CHAT_OWNER_CHANGED = Message( message_id=42, date=datetime.datetime.now(), @@ -1047,6 +1054,12 @@ class TestMessage: def test_content_type(self, message: Message, content_type: str): assert message.content_type == content_type + def test_chat_owner_left_no_successor(self): + assert ( + TEST_MESSAGE_CHAT_OWNER_LEFT_NO_SUCCESSOR.content_type + == ContentType.CHAT_OWNER_LEFT + ) + def test_as_reply_parameters(self): message = Message( message_id=42, chat=Chat(id=42, type="private"), date=datetime.datetime.now() diff --git a/tests/test_api/test_types/test_user.py b/tests/test_api/test_types/test_user.py index 9f28175b..610fcd9c 100644 --- a/tests/test_api/test_types/test_user.py +++ b/tests/test_api/test_types/test_user.py @@ -56,3 +56,9 @@ class TestUser: method = user.get_profile_photos(description="test") assert method.user_id == user.id + + def test_get_profile_audios(self): + user = User(id=42, is_bot=False, first_name="Test", last_name="User") + + method = user.get_profile_audios(description="test") + assert method.user_id == user.id diff --git a/tests/test_api/test_types/test_video_quality.py b/tests/test_api/test_types/test_video_quality.py new file mode 100644 index 00000000..20144911 --- /dev/null +++ b/tests/test_api/test_types/test_video_quality.py @@ -0,0 +1,61 @@ +import pytest + +from aiogram.types import Video, VideoQuality + + +@pytest.fixture() +def video_quality(): + return VideoQuality( + file_id="abc123", + file_unique_id="unique123", + width=1920, + height=1080, + codec="h264", + ) + + +class TestVideoQuality: + def test_instantiation(self, video_quality: VideoQuality): + assert video_quality.file_id == "abc123" + assert video_quality.file_unique_id == "unique123" + assert video_quality.width == 1920 + assert video_quality.height == 1080 + assert video_quality.codec == "h264" + assert video_quality.file_size is None + + def test_instantiation_with_file_size(self): + file_size = 1048576 + vq = VideoQuality( + file_id="abc123", + file_unique_id="unique123", + width=1920, + height=1080, + codec="h265", + file_size=file_size, + ) + assert vq.file_size == file_size + + def test_video_with_qualities(self, video_quality: VideoQuality): + file_size = 524288 + video = Video( + file_id="video123", + file_unique_id="unique_video123", + width=1920, + height=1080, + duration=120, + qualities=[ + video_quality, + VideoQuality( + file_id="q2", + file_unique_id="uq2", + width=1280, + height=720, + codec="h264", + file_size=file_size, + ), + ], + ) + assert video.qualities is not None + assert len(video.qualities) == 2 + assert video.qualities[0].width == 1920 + assert video.qualities[1].file_size == file_size