diff --git a/.butcher/enums/ButtonStyle.yml b/.butcher/enums/ButtonStyle.yml
index 7922d310..ce910386 100644
--- a/.butcher/enums/ButtonStyle.yml
+++ b/.butcher/enums/ButtonStyle.yml
@@ -2,7 +2,7 @@ name: ButtonStyle
description: |
This object represents a button style (inline- or reply-keyboard).
- Source: https://core.telegram.org/bots/api#chat
+ Source: https://core.telegram.org/bots/api#inlinekeyboardbutton
parse:
entity: InlineKeyboardButton
attribute: style
diff --git a/.butcher/types/GameHighScore/entity.json b/.butcher/types/GameHighScore/entity.json
index 21a8a5e7..ce3f52d2 100644
--- a/.butcher/types/GameHighScore/entity.json
+++ b/.butcher/types/GameHighScore/entity.json
@@ -7,9 +7,9 @@
"object": {
"anchor": "gamehighscore",
"name": "GameHighScore",
- "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ\n-",
- "html_description": "
This object represents one row of the high scores table for a game.
And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »
\n-
",
- "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**\n\n-",
+ "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ",
+ "html_description": "This object represents one row of the high scores table for a game.
And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »
",
+ "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**",
"annotations": [
{
"type": "Integer",
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/enums/button_style.py b/aiogram/enums/button_style.py
index 6aeffd58..8358c89c 100644
--- a/aiogram/enums/button_style.py
+++ b/aiogram/enums/button_style.py
@@ -5,7 +5,7 @@ class ButtonStyle(str, Enum):
"""
This object represents a button style (inline- or reply-keyboard).
- Source: https://core.telegram.org/bots/api#chat
+ Source: https://core.telegram.org/bots/api#inlinekeyboardbutton
"""
DANGER = "danger"
diff --git a/aiogram/types/game_high_score.py b/aiogram/types/game_high_score.py
index e8fdcf40..5364be6e 100644
--- a/aiogram/types/game_high_score.py
+++ b/aiogram/types/game_high_score.py
@@ -15,8 +15,6 @@ class GameHighScore(TelegramObject):
If you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**
- -
-
Source: https://core.telegram.org/bots/api#gamehighscore
"""
diff --git a/aiogram/types/user.py b/aiogram/types/user.py
index 00da8e5c..ea42b85e 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,32 @@ 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`
+ """
+ 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..db1afc91 100644
--- a/tests/test_api/test_types/test_message.py
+++ b/tests/test_api/test_types/test_message.py
@@ -258,9 +258,7 @@ TEST_MESSAGE_LEFT_CHAT_MEMBER = Message(
TEST_MESSAGE_CHAT_OWNER_LEFT = Message(
message_id=42,
date=datetime.datetime.now(),
- chat_owner_left=ChatOwnerLeft(
- new_owner=User(id=43, is_bot=False, first_name="NewOwner"),
- ),
+ chat_owner_left=ChatOwnerLeft(),
chat=Chat(id=42, type="private"),
from_user=User(id=42, is_bot=False, first_name="Test"),
)
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..18927152
--- /dev/null
+++ b/tests/test_api/test_types/test_video_quality.py
@@ -0,0 +1,59 @@
+from aiogram.types import Video, VideoQuality
+
+
+class TestVideoQuality:
+ def test_instantiation(self):
+ vq = VideoQuality(
+ file_id="abc123",
+ file_unique_id="unique123",
+ width=1920,
+ height=1080,
+ codec="h264",
+ )
+ assert vq.file_id == "abc123"
+ assert vq.file_unique_id == "unique123"
+ assert vq.width == 1920
+ assert vq.height == 1080
+ assert vq.codec == "h264"
+ assert vq.file_size is None
+
+ def test_instantiation_with_file_size(self):
+ vq = VideoQuality(
+ file_id="abc123",
+ file_unique_id="unique123",
+ width=1920,
+ height=1080,
+ codec="h265",
+ file_size=1048576,
+ )
+ assert vq.file_size == 1048576
+
+ def test_video_with_qualities(self):
+ video = Video(
+ file_id="video123",
+ file_unique_id="unique_video123",
+ width=1920,
+ height=1080,
+ duration=120,
+ qualities=[
+ VideoQuality(
+ file_id="q1",
+ file_unique_id="uq1",
+ width=1920,
+ height=1080,
+ codec="h264",
+ ),
+ VideoQuality(
+ file_id="q2",
+ file_unique_id="uq2",
+ width=1280,
+ height=720,
+ codec="h264",
+ file_size=524288,
+ ),
+ ],
+ )
+ assert video.qualities is not None
+ assert len(video.qualities) == 2
+ assert video.qualities[0].width == 1920
+ assert video.qualities[1].file_size == 524288