async def test_get_psplus_status(http_get, authenticated_plugin, psplus_name, psnow_name, backend_response, status): http_get.return_value = backend_response assert [Subscription(psplus_name, end_time=None, owned=status), Subscription(psnow_name, end_time=None, owned=None, \ subscription_discovery=SubscriptionDiscovery.USER_ENABLED)] == \ await authenticated_plugin.get_subscriptions()
async def get_subscriptions(self) -> List[Subscription]: is_plus_active = await self._psn_client.get_psplus_status() return [ Subscription(PLAYSTATION_PLUS, is_plus_active, None), Subscription(PLAYSTATION_NOW, None, None, SubscriptionDiscovery.USER_ENABLED) ]
async def test_get_subscriptions_past_subscriber(api_mock, plugin_with_sub): """ Testcase: Currently no subscriptiion but user was subscriber in the past Expected: Active subscription months + not owned Trove & and owned active month """ api_mock.had_subscription.return_value = True api_mock.get_choice_content_data.return_value = Mock( **{'user_subscription_plan': None}) content_choice_options = [ { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'march_2020_choice', 'isActiveContent': False }, { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'february_2020_choice', 'isActiveContent': False }, ] api_mock.get_subscription_products_with_gamekeys = MagicMock( return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription("Humble Choice 2020-02", owned=True), Subscription("Humble Choice 2020-03", owned=True), Subscription("Humble Choice 2020-05", owned=False), Subscription("Humble Trove", owned=False), ]
async def test_get_subscriptions_current_month_not_unlocked_yet( current_subscription_plan, current_month_owned, trove_owned, api_mock, plugin_with_sub): """ Technically only unlocked choice months are owned (locked are not already payed and can be canceled). But for user convenience plugin marks month as owned if it *is going to* be unloacked (if not cancelled untill last Friday). Without this, Galaxy won't display games until user manualy select current month as owned. This would be annoying as, as new subscription month happen... well every month. --- Test checks also logic for Trove ownership base on subscription status. """ api_mock.had_subscription.return_value = True api_mock.get_choice_content_data.return_value = Mock( user_subscription_plan=current_subscription_plan) content_choice_options = [{ 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'april_2020_choice', 'isActiveContent': False }] api_mock.get_subscription_products_with_gamekeys = MagicMock( return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription( "Humble Choice 2020-04", owned=True ), # came from api - we're sure that choice month was unlocked Subscription("Humble Choice 2020-05", owned=current_month_owned), Subscription("Humble Trove", owned=trove_owned), ]
async def test_get_subscriptions_success(plugin, read, write): request = {"jsonrpc": "2.0", "id": "3", "method": "import_subscriptions"} read.side_effect = [ async_return_value(create_message(request)), async_return_value(b"", 10) ] plugin.get_subscriptions.return_value = async_return_value([ Subscription("1"), Subscription("2", False), Subscription("3", True, 1580899100) ]) await plugin.run() plugin.get_subscriptions.assert_called_with() assert get_messages(write) == [{ "jsonrpc": "2.0", "id": "3", "result": { "subscriptions": [{ "subscription_name": "1" }, { "subscription_name": "2", "owned": False }, { "subscription_name": "3", "owned": True, "end_time": 1580899100 }] } }]
async def test_get_subscriptions_never_subscribed(api_mock, plugin_with_sub): api_mock.had_subscription.return_value = False res = await plugin_with_sub.get_subscriptions() assert res == [ Subscription("Humble Choice 2020-05", owned=False), Subscription("Humble Trove", owned=False), ]
async def get_subscriptions(self) -> List[Subscription]: await self._games_cache.wait_ready(90) if self._games_cache.get_shared_games(): return [ Subscription("Family Sharing", True, None, SubscriptionDiscovery.AUTOMATIC) ] return [ Subscription("Family Sharing", False, None, SubscriptionDiscovery.AUTOMATIC) ]
async def get_subscriptions(self): subscriptions: t.List[Subscription] = [] historical_subscriber = await self._api.had_subscription() active_content_unlocked = False if historical_subscriber: async for product in self._api.get_subscription_products_with_gamekeys( ): if 'contentChoiceData' not in product: break # all Humble Choice months already yielded subscriptions.append( Subscription(self._normalize_subscription_name( product['productMachineName']), owned='gamekey' in product)) if product.get( 'isActiveContent' ): # assuming there is only one "active" month at a time active_content_unlocked = True if not active_content_unlocked: ''' - for not subscribers as potential discovery of current choice games - for subscribers who has not used "Early Unlock" yet: https://support.humblebundle.com/hc/en-us/articles/217300487-Humble-Choice-Early-Unlock-Games ''' active_month = next( filter(lambda m: m.is_active == True, self._subscription_months)) current_plan = await self._get_subscription_plan(active_month.last_url_part) \ if historical_subscriber else None subscriptions.append( Subscription( self._normalize_subscription_name( active_month.machine_name), owned=current_plan is not None and current_plan.tier != Tier.LITE, end_time= None # #117: get_last_friday.timestamp() if user_plan not in [None, Lite] else None )) subscriptions.append( Subscription(subscription_name=TROVE_SUBSCRIPTION_NAME, owned=active_content_unlocked or current_plan is not None)) return subscriptions
async def get_subscriptions(self) -> List[Subscription]: is_plus_active = await self._psn_client.get_psplus_status() return [ Subscription(subscription_name="PlayStation PLUS", end_time=None, owned=is_plus_active) ]
async def get_subscriptions(self, user_id) -> List[Subscription]: subs = {'standard': Subscription(subscription_name='Origin Access Basic', owned=False), 'premium': Subscription(subscription_name='Origin Access Premier', owned=False)} subscription_uri = await self._get_subscription_uri(user_id) if subscription_uri: sub_status = await self._get_subscription_status(subscription_uri) logging.debug(f'sub_status: {sub_status}') try: if sub_status: subs[sub_status['tier']].owned = True subs[sub_status['tier']].end_time = sub_status['end_time'] except (ValueError, KeyError) as e: logging.exception("Unknown subscription tier, error %s", repr(e)) raise UnknownBackendResponse() else: logging.debug('no subscription active') return [subs['standard'], subs['premium']]
async def test_subscription_owned(authenticated_plugin): authenticated_plugin.client.get_subscription = AsyncMock() authenticated_plugin.client.get_subscription.return_value = SUBSCRIPTION_RESPONSE_OK sub_status = await authenticated_plugin.get_subscriptions() exp_result = [Subscription(subscription_name="Uplay+", owned=True, end_time=None, subscription_discovery=SubscriptionDiscovery.AUTOMATIC)] assert sub_status == exp_result
async def get_subscriptions(self): subscriptions: List[Subscription] = [] active_content_unlocked = False current_or_former_subscriber = await self._api.had_subscription() if current_or_former_subscriber: async for product in self._api.get_subscription_products_with_gamekeys( ): subscriptions.append( Subscription(self._normalize_subscription_name( product.product_machine_name), owned=True)) if product.is_active_content: # assuming there is one "active" month at a time active_content_unlocked = True if not active_content_unlocked: ''' - for not subscribers as potential discovery of current choice games - for subscribers who has not used "Early Unlock" yet: https://support.humblebundle.com/hc/en-us/articles/217300487-Humble-Choice-Early-Unlock-Games ''' active_month = next( filter(lambda m: m.is_active == True, self._subscription_months)) current_user_plan = None if current_or_former_subscriber: current_user_plan = await self._get_current_user_subscription_plan( active_month.last_url_part) subscriptions.append( Subscription( self._normalize_subscription_name( active_month.machine_name), owned=bool(current_user_plan), # #116: exclude Lite end_time= None # #117: get_last_friday.timestamp() if user_plan not in [None, Lite] else None )) subscriptions.append( Subscription(subscription_name="Humble Trove", owned=active_content_unlocked or current_user_plan is not None)) return subscriptions
async def get_subscriptions(self) -> List[Subscription]: sub_status = await self.client.get_subscription() sub_status = True if sub_status else False return [ Subscription( subscription_name="Uplay+", end_time=None, owned=sub_status, subscription_discovery=SubscriptionDiscovery.AUTOMATIC) ]
async def get_subscriptions(self) -> List[Subscription]: if not self._owned_games_parsed: await self._games_cache.wait_ready(90) any_shared_game = False async for _ in self._games_cache.get_shared_games(): any_shared_game = True break return [ Subscription("Steam Family Sharing", any_shared_game, None, SubscriptionDiscovery.AUTOMATIC) ]
async def get_subscriptions(self, user_id) -> List[Subscription]: subs = { 'standard': Subscription(subscription_name='EA Play', owned=False), 'premium': Subscription(subscription_name='EA Play Pro', owned=False) } for uri in await self._get_subscription_uris(user_id): user_sub = await self._get_active_subscription(uri) if user_sub: break else: user_sub = None logger.debug(f'user_sub: {user_sub}') try: if user_sub: subs[user_sub.tier].owned = True subs[user_sub.tier].end_time = user_sub.end_time except (ValueError, KeyError) as e: logger.exception("Unknown subscription tier, error %s", repr(e)) raise UnknownBackendResponse() return [subs['standard'], subs['premium']]
async def test_get_subscriptions_humble_choice_and_humble_monthly( api_mock, plugin_with_sub): """ The subscription_products_with_gamekeys API returns firstly Choice months data, then old Humble Monthly subscription data. Expected: Plugin should ignore Humble Montly subscription months. """ api_mock.had_subscription.return_value = True content_choice_options = [ { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'january_2020_choice', 'isActiveContent': True }, { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'december_2019_choice', 'isActiveContent': False }, { 'machine_name': 'december_2019_monthly', 'order_url': '/downloads?key=b6BVmZ4AuvPwfa3S', 'short_human_name': 'December 2019' }, # subscribed { 'machine_name': 'november_2019_monthly', 'order_url': None, 'short_human_name': 'November 2019' }, # not subscribed ] api_mock.get_subscription_products_with_gamekeys = MagicMock( return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription("Humble Choice 2019-12", owned=True), Subscription("Humble Choice 2020-01", owned=True), Subscription("Humble Trove", owned=True), ]
async def test_get_subscriptions_multiple_where_one_paused( api_mock, plugin_with_sub): api_mock.had_subscription.return_value = True content_choice_options = [ { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'may_2020_choice', 'isActiveContent': True }, { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'april_2020_choice', 'isActiveContent': False }, { 'contentChoiceData': Mock(dict), 'productMachineName': 'march_2020_choice', 'isActiveContent': False }, # paused month { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'february_2020_choice', 'isActiveContent': False }, { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'january_2020_choice', 'isActiveContent': False }, { 'contentChoiceData': Mock(dict), 'gamekey': Mock(str), 'productMachineName': 'december_2019_choice', 'isActiveContent': False }, ] api_mock.get_subscription_products_with_gamekeys = MagicMock( return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription("Humble Choice 2019-12", owned=True), Subscription("Humble Choice 2020-01", owned=True), Subscription("Humble Choice 2020-02", owned=True), Subscription("Humble Choice 2020-03", owned=False), # paused month Subscription("Humble Choice 2020-04", owned=True), Subscription("Humble Choice 2020-05", owned=True), Subscription("Humble Trove", owned=True), ]
async def test_get_subscriptions_current_month_not_unlocked_yet(api_mock, plugin_with_sub): api_mock.had_subscription.return_value = True subscription_plan = { "human_name": "Month-to-Month Classic Plan", "length": 1, "machine_name": "monthly_basic", "pricing|money": { "currency": "USD", "amount": 12 } } api_mock.get_choice_content_data.return_value = Mock(**{'user_subscription_plan': subscription_plan}) content_choice_options = [ Mock(**{'product_machine_name': 'april_2020_choice', 'is_active_content': False}), ] api_mock.get_subscription_products_with_gamekeys = MagicMock(return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription("Humble Choice 2020-04", owned=True), Subscription("Humble Choice 2020-05", owned=True), # as it is going to be unlocked Subscription("Humble Trove", owned=True), ]
async def test_get_subscriptions_subscriber_all_from_api( api_mock, plugin_with_sub): api_mock.had_subscription.return_value = True content_choice_options = [ Mock(**{ 'product_machine_name': 'may_2020_choice', 'is_active_content': True }), Mock( **{ 'product_machine_name': 'april_2020_choice', 'is_active_content': False }), Mock( **{ 'product_machine_name': 'march_2020_choice', 'is_active_content': False }), Mock( **{ 'product_machine_name': 'february_2020_choice', 'is_active_content': False }), Mock( **{ 'product_machine_name': 'january_2020_choice', 'is_active_content': False }), Mock( **{ 'product_machine_name': 'december_2019_choice', 'is_active_content': False }), ] api_mock.get_subscription_products_with_gamekeys = MagicMock( return_value=aiter(content_choice_options)) res = await plugin_with_sub.get_subscriptions() assert sorted(res, key=lambda x: x.subscription_name) == [ Subscription("Humble Choice 2019-12", owned=True), Subscription("Humble Choice 2020-01", owned=True), Subscription("Humble Choice 2020-02", owned=True), Subscription("Humble Choice 2020-03", owned=True), Subscription("Humble Choice 2020-04", owned=True), Subscription("Humble Choice 2020-05", owned=True), Subscription("Humble Trove", owned=True), ]
import pytest from galaxy.api.types import SubscriptionGame, Subscription from galaxy.api.errors import BackendError SUBSCRIPTION_OWNED_ID = 'EA Play Pro' SUBSCRIPTIONS_NOT_OWNED = [ Subscription(subscription_name='EA Play', owned=False, end_time=None), Subscription(subscription_name='EA Play Pro', owned=False, end_time=None) ] SUBSCRIPTIONS_OWNED = [ Subscription(subscription_name='EA Play', owned=False, end_time=None), Subscription(subscription_name='EA Play Pro', owned=True, end_time=1581331712) ] SUBSCRIPTIONS_CONTEXT = { 'EA Play Pro': [ SubscriptionGame( game_title= 'Mass Effect 3 N7 Digital Deluxe Edition - PC - WW (Origin/3PDD)', game_id='DR:230773600', start_time=None, end_time=None), SubscriptionGame( game_title= 'LEGRAND LEGACY: Tale of the Fatebounds - PC - WW - (Origin)', game_id='Origin.OFR.50.0003727', start_time=None, end_time=None), SubscriptionGame(game_title='Mable & the Wood - PC - WW - (Origin)',
async def test_get_psplus_status(http_get, authenticated_plugin, psplus_name, backend_response, status): http_get.return_value = backend_response assert [Subscription(psplus_name, end_time=None, owned=status)] == \ await authenticated_plugin.get_subscriptions()
import pytest from galaxy.api.types import SubscriptionGame, Subscription from galaxy.api.errors import BackendError SUBSCRIPTION_OWNED_ID = 'Origin Access Premier' SUBSCRIPTIONS_NOT_OWNED = [ Subscription(subscription_name='Origin Access Basic', owned=False, end_time=None), Subscription(subscription_name='Origin Access Premier', owned=False, end_time=None) ] SUBSCRIPTIONS_OWNED = [ Subscription(subscription_name='Origin Access Basic', owned=False, end_time=None), Subscription(subscription_name='Origin Access Premier', owned=True, end_time=1581331712) ] SUBSCRIPTIONS_CONTEXT = { 'Origin Access Premier': [ SubscriptionGame( game_title= 'Mass Effect 3 N7 Digital Deluxe Edition - PC - WW (Origin/3PDD)', game_id='DR:230773600', start_time=None, end_time=None), SubscriptionGame(
from unittest.mock import Mock import pytest from galaxy.api.types import SubscriptionGame, Subscription from galaxy.api.errors import AuthenticationRequired, BackendError from backend import OriginBackendClient SUBSCRIPTION_OWNED_ID = "EA Play Pro" SUBSCRIPTIONS_NOT_OWNED = [ Subscription(subscription_name="EA Play", owned=False, end_time=None), Subscription(subscription_name="EA Play Pro", owned=False, end_time=None), ] SUBSCRIPTIONS_OWNED = [ Subscription(subscription_name="EA Play", owned=False, end_time=None), Subscription(subscription_name="EA Play Pro", owned=True, end_time=1581331712), ] SUBSCRIPTION_GAMES_BACKEND_RESPONSE = { "game": [ { "displayName": "Mass Effect 3 N7 Digital Deluxe Edition - PC - WW (Origin/3PDD)", "masterTitleIds": {"masterTitleId": ["69317"]}, "basegames": {"basegame": ["DR:230773600"]}, "extracontents": { "extracontent": [ "OFB-EAST:46112", "OFB-MASS:46482", "OFB-MASS:46483", "OFB-MASS:46484", "OFB-MASS:51074",