diff --git a/tests/__init__.py b/tests/__init__.py index e44a428..b4d1cf8 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -73,3 +73,4 @@ from .test_vinyl import TestVinyl from .test_shot_type import TestShotType from .test_shot_data import TestShotData from .test_shot import TestShot +from .test_renewable_remainder import TestRenewableRemainder diff --git a/tests/conftest.py b/tests/conftest.py index e775f0a..72dd03c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,8 @@ from yandex_music import Counts, TrackId, CaseForms, Ratings, Icon, Album, Lyric Account, Client, TrackShort, Value, DiscreteScale, PlaylistId, MixLink, Link, PassportPhone, User, Promotion, \ PersonalPlaylistsData, RotorSettings, TrackShortOld, PlayContextsData, Status, Settings, StationResult, Enum, \ TrackWithAds, VideoSupplement, ArtistEvent, ChartItem, Event, AlbumEvent, Day, PlayContext, Plus, Title, Label, \ - GeneratedPlaylist, Video, Vinyl, SearchResult, BlockEntity, Block, PlaylistAbsence, ShotType, ShotData, Shot + GeneratedPlaylist, Video, Vinyl, SearchResult, BlockEntity, Block, PlaylistAbsence, ShotType, ShotData, Shot, \ + RenewableRemainder from . import TestCounts, TestTrackId, TestCaseForms, TestRatings, TestIcon, TestAlbum, TestLyrics, \ TestTrack, TestInvocationInfo, TestPlaylist, TestAutoRenewable, TestStation, TestNormalization, TestMajor, \ TestTrackPosition, TestBest, TestChart, TestPermissions, TestPlus, TestProduct, TestCover, TestPlayCounter, \ @@ -15,7 +16,8 @@ from . import TestCounts, TestTrackId, TestCaseForms, TestRatings, TestIcon, Tes TestUser, TestPassportPhone, TestPromotion, TestTitle, TestPersonalPlaylistsData, TestRotorSettings, \ TestTrackShortOld, TestPager, TestStatus, TestSettings, TestStationResult, TestLabel, TestTrackWithAds, \ TestVideoSupplement, TestEvent, TestDay, TestPlayContext, TestGeneratedPlaylist, TestVideo, TestVinyl, \ - TestSearchResult, TestBlockEntity, TestBlock, TestPlaylistAbsence, TestShot, TestShotData, TestShotType + TestSearchResult, TestBlockEntity, TestBlock, TestPlaylistAbsence, TestShot, TestShotData, TestShotType, \ + TestRenewableRemainder @pytest.fixture(scope='session') @@ -338,6 +340,11 @@ def passport_phone(): return PassportPhone(TestPassportPhone.phone) +@pytest.fixture(scope='session') +def renewable_remainder(): + return RenewableRemainder(TestRenewableRemainder.days) + + @pytest.fixture(scope='session') def user(): return User(TestUser.uid, TestUser.login, TestUser.name, TestUser.sex, TestUser.verified) @@ -362,9 +369,9 @@ def price(): @pytest.fixture(scope='session') -def subscription(auto_renewable): - return Subscription([auto_renewable], TestSubscription.can_start_trial, TestSubscription.mcdonalds, - TestSubscription.end) +def subscription(renewable_remainder, auto_renewable): + return Subscription(renewable_remainder, [auto_renewable], TestSubscription.can_start_trial, + TestSubscription.mcdonalds, TestSubscription.end) @pytest.fixture(scope='session') diff --git a/tests/test_renewable_remainder.py b/tests/test_renewable_remainder.py new file mode 100644 index 0000000..85a994f --- /dev/null +++ b/tests/test_renewable_remainder.py @@ -0,0 +1,34 @@ +from yandex_music import RenewableRemainder + + +class TestRenewableRemainder: + days = 0 + + def test_expected_values(self, renewable_remainder): + assert renewable_remainder.days == self.days + + def test_de_json_none(self, client): + assert RenewableRemainder.de_json({}, client) is None + + def test_de_json_required(self, client): + json_dict = {'days': self.days} + renewable_remainder = RenewableRemainder.de_json(json_dict, client) + + assert renewable_remainder.days == self.days + + def test_de_json_all(self, client): + json_dict = {'days': self.days} + renewable_remainder = RenewableRemainder.de_json(json_dict, client) + + assert renewable_remainder.days == self.days + + def test_equality(self): + a = RenewableRemainder(self.days) + b = RenewableRemainder(10) + c = RenewableRemainder(self.days) + + assert a != b + assert hash(a) != hash(b) + assert a is not b + + assert a == c diff --git a/tests/test_subscription.py b/tests/test_subscription.py index 4cbacb7..f284b44 100644 --- a/tests/test_subscription.py +++ b/tests/test_subscription.py @@ -6,7 +6,8 @@ class TestSubscription: mcdonalds = False end = None - def test_expected_values(self, subscription, auto_renewable): + def test_expected_values(self, subscription, renewable_remainder, auto_renewable): + assert subscription.non_auto_renewable_remainder == renewable_remainder assert subscription.auto_renewable == [auto_renewable] assert subscription.can_start_trial == self.can_start_trial assert subscription.mcdonalds == self.mcdonalds @@ -15,23 +16,29 @@ class TestSubscription: def test_de_json_none(self, client): assert Subscription.de_json({}, client) is None - def test_de_json_required(self, client): - json_dict = {} + def test_de_json_required(self, client, renewable_remainder, auto_renewable): + json_dict = {'non_auto_renewable_remainder': renewable_remainder.to_dict(), + 'auto_renewable': [auto_renewable.to_dict()]} subscription = Subscription.de_json(json_dict, client) - def test_de_json_all(self, client, auto_renewable): + assert subscription.non_auto_renewable_remainder == renewable_remainder + assert subscription.auto_renewable == [auto_renewable] + + def test_de_json_all(self, client, renewable_remainder, auto_renewable): json_dict = {'auto_renewable': [auto_renewable.to_dict()], 'can_start_trial': self.can_start_trial, - 'mcdonalds': self.mcdonalds, 'end': self.end} + 'mcdonalds': self.mcdonalds, 'end': self.end, 'non_auto_renewable_remainder': + renewable_remainder.to_dict()} subscription = Subscription.de_json(json_dict, client) + assert subscription.non_auto_renewable_remainder == renewable_remainder assert subscription.auto_renewable == [auto_renewable] assert subscription.can_start_trial == self.can_start_trial assert subscription.mcdonalds == self.mcdonalds assert subscription.end == self.end - def test_equality(self, auto_renewable): - a = Subscription([auto_renewable]) - b = Subscription(None) + def test_equality(self, renewable_remainder, auto_renewable): + a = Subscription(renewable_remainder, [auto_renewable]) + b = Subscription(renewable_remainder, []) assert a != b != auto_renewable assert hash(a) != hash(b) != hash(auto_renewable) diff --git a/yandex_music/__init__.py b/yandex_music/__init__.py index 404859e..1416049 100644 --- a/yandex_music/__init__.py +++ b/yandex_music/__init__.py @@ -12,6 +12,7 @@ from .account.subscription import Subscription from .account.price import Price from .account.product import Product from .account.auto_renewable import AutoRenewable +from .account.renewable_remainder import RenewableRemainder from .account.passport_phone import PassportPhone from .account.permissions import Permissions @@ -118,4 +119,4 @@ __all__ = ['YandexMusicObject', 'Client', 'Account', 'PassportPhone', 'Invocatio 'Dashboard', 'RotorSettings', 'AdParams', 'Restrictions', 'Value', 'Enum', 'DiscreteScale', 'StationResult', 'Sequence', 'StationTracksResult', 'BriefInfo', 'Description', 'PlaylistId', 'Vinyl', 'Supplement', 'Lyrics', 'VideoSupplement', 'ArtistTracks', 'Pager', 'ArtistAlbums', 'PlaylistAbsence', 'Shot', 'ShotEvent', - 'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings'] + 'ShotType', 'ShotData', 'SimilarTracks', 'UserSettings', 'RenewableRemainder'] diff --git a/yandex_music/account/renewable_remainder.py b/yandex_music/account/renewable_remainder.py new file mode 100644 index 0000000..3442524 --- /dev/null +++ b/yandex_music/account/renewable_remainder.py @@ -0,0 +1,49 @@ +from typing import TYPE_CHECKING, Optional + +from yandex_music import YandexMusicObject + +if TYPE_CHECKING: + from yandex_music import Client + + +class RenewableRemainder(YandexMusicObject): + """Класс, представляющий напоминания о продлении подписки. + + Attributes: + days (:obj:`int`): Количество дней (до окончания подписки, по всей видимости). + client (:obj:`yandex_music.Client`): Клиент Yandex Music. + + Args: + days (:obj:`int`): Количество дней (до окончания подписки, по всей видимости). + client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music. + **kwargs: Произвольные ключевые аргументы полученные от API. + """ + + def __init__(self, + days: int, + client: Optional['Client'] = None, + **kwargs) -> None: + super().handle_unknown_kwargs(self, **kwargs) + + self.days = days + + self.client = client + self._id_attrs = (self.days,) + + @classmethod + def de_json(cls, data: dict, client: 'Client') -> Optional['RenewableRemainder']: + """Десериализация объекта. + + Args: + data (:obj:`dict`): Поля и значения десериализуемого объекта. + client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music. + + Returns: + :obj:`yandex_music.PassportPhone`: Напоминание о продлении подписки. + """ + if not data: + return None + + data = super(RenewableRemainder, cls).de_json(data, client) + + return cls(client=client, **data) diff --git a/yandex_music/account/subscription.py b/yandex_music/account/subscription.py index 031a8f0..d6bc9e3 100644 --- a/yandex_music/account/subscription.py +++ b/yandex_music/account/subscription.py @@ -3,13 +3,14 @@ from typing import TYPE_CHECKING, Optional, List from yandex_music import YandexMusicObject if TYPE_CHECKING: - from yandex_music import Client, AutoRenewable + from yandex_music import Client, AutoRenewable, RenewableRemainder class Subscription(YandexMusicObject): """Класс, представляющий информацию о подписках пользователя. Attributes: + non_auto_renewable_remainder (:obj:yandex_music.RenewableRemainder`): Напоминание о продлении. auto_renewable (:obj:`list` из :obj:`yandex_music.AutoRenewable`): Автопродление. can_start_trial (:obj:`bool`): Есть ли возможность начать пробный период. mcdonalds (:obj:`bool`): mcdonalds TODO. @@ -17,6 +18,7 @@ class Subscription(YandexMusicObject): client (:obj:`yandex_music.Client`): Клиент Yandex Music. Args: + non_auto_renewable_remainder (:obj:yandex_music.RenewableRemainder`): Напоминание о продлении. auto_renewable (:obj:`list` из :obj:`yandex_music.AutoRenewable`, optional): Автопродление. can_start_trial (:obj:`bool`, optional): Есть ли возможность начать пробный период. mcdonalds (:obj:`bool`, optional): mcdonalds TODO. @@ -26,7 +28,8 @@ class Subscription(YandexMusicObject): """ def __init__(self, - auto_renewable: List['AutoRenewable'] = None, + non_auto_renewable_remainder: 'RenewableRemainder', + auto_renewable: List['AutoRenewable'], can_start_trial: Optional[bool] = None, mcdonalds: Optional[bool] = None, end: Optional[str] = None, @@ -34,13 +37,14 @@ class Subscription(YandexMusicObject): **kwargs) -> None: super().handle_unknown_kwargs(self, **kwargs) + self.non_auto_renewable_remainder = non_auto_renewable_remainder self.auto_renewable = auto_renewable self.can_start_trial = can_start_trial self.mcdonalds = mcdonalds self.end = end self.client = client - self._id_attrs = (self.auto_renewable,) + self._id_attrs = (self.non_auto_renewable_remainder, self.auto_renewable) @classmethod def de_json(cls, data: dict, client: 'Client') -> Optional['Subscription']: @@ -57,7 +61,9 @@ class Subscription(YandexMusicObject): return None data = super(Subscription, cls).de_json(data, client) - from yandex_music import AutoRenewable + from yandex_music import AutoRenewable, RenewableRemainder data['auto_renewable'] = AutoRenewable.de_list(data.get('auto_renewable'), client) + data['non_auto_renewable_remainder'] = RenewableRemainder.de_json( + data.get('non_auto_renewable_remainder'), client) return cls(client=client, **data)