async def test_choice_month_no_remained_choices(api_mock, plugin, cco, choice_data): """Show only chosen games if no more choices left.""" cco.remained_choices = 0 cco.content_choices_made = ['c'] cco.content_choices = [ Mock(**{ 'id': 'a', 'title': 'A' }), Mock(**{ 'id': 'b', 'title': 'B' }), Mock(**{ 'id': 'c', 'title': 'C' }), ] cco.extrases = [Mock(**{'machine_name': 'e', 'human_name': 'E'})] api_mock.get_choice_content_data = AsyncMock(return_value=choice_data) ctx = None async for one_month_games in plugin.get_subscription_games( 'Humble Choice 2020-05', ctx): assert one_month_games == [ SubscriptionGame(game_title='C', game_id='c'), SubscriptionGame(game_title='E', game_id='e'), ] assert plugin._choice_games == { # cache 'c': ChoiceGame(id='c', title='C', slug='may-2020', is_extras=False), 'e': ChoiceGame(id='e', title='E', slug='may-2020', is_extras=True), }
async def get_subscription_games(self, subscription_name, context: t.Dict[str, ChoiceMonth]): if subscription_name == "Humble Trove": async for troves in self._get_trove_games(): yield troves return month: ChoiceMonth = context[subscription_name] choice_data = await self._api.get_choice_content_data( month.last_url_part) cco = choice_data.content_choice_options show_all = cco.remained_choices > 0 if month.is_active: start_time = choice_data.active_content_start.timestamp() else: start_time = None # TODO assume first friday of month content_choices = [ SubscriptionGame(ch.title, ch.id, start_time) for ch in cco.content_choices if show_all or ch.id in cco.content_choices_made ] extrases = [ SubscriptionGame(extr.human_name, extr.machine_name, start_time) for extr in cco.extrases ] month_choice_games = content_choices + extrases yield month_choice_games
async def sub_games(): games = [ SubscriptionGame(game_title="game A", game_id="game_A"), SubscriptionGame(game_title="game B", game_id="game_B", start_time=1548495632), SubscriptionGame(game_title="game C", game_id="game_C", end_time=1548495633), SubscriptionGame(game_title="game D", game_id="game_D", start_time=1548495632, end_time=1548495633), ] yield [game for game in games]
def games_parser(data): return [ SubscriptionGame(game_id=item['id'].split('-')[1], game_title=item['attributes']['name']) for item in data['included'] if item['type'] in ['game', 'game-related'] ]
def games_parser(data): return [ SubscriptionGame(game_id=game['id'].split('-')[1], game_title=game['name']) for category in data['categories'] if category_pattern.match(category['name']) for game in category['games'] ]
async def get_subscription_games(self, subscription_name: str, context: Any): games = [] async for game in self._games_cache.get_shared_games(): games.append( SubscriptionGame(game_id=str(game.appid), game_title=game.title)) yield games
async def prepare_subscription_games_context( self, subscription_names: List[str]) -> Any: sub_games_response = await self.client.get_subscription() if sub_games_response: return [ SubscriptionGame(game_title=game['name'], game_id=str(game['uplayGameId'])) for game in sub_games_response["games"] ] return None
def parse(self, response) -> List[SubscriptionGame]: try: games = self._subscription_games(response) except NotFoundSubscriptionPaginator: raise UnknownBackendResponse(f"HTML TAG: {self._SUBSCRIBED_GAMES_PAGINATOR_CSS_CLASS} was not found in response.") else: return [ SubscriptionGame(game_id=game['titleId'], game_title=game['name']) for game in games if game.get('name') and game.get('titleId') and not game['name'].startswith('PlayStation') ]
async def test_get_subscription_games_trove(api_mock, plugin): parsed_from_page = { 'newlyAdded': [ { 'human-name': 'A', 'machine_name': 'a' }, { 'human-name': 'Z', 'machine_name': 'z' }, ] } api_mock.get_montly_trove_data.return_value = parsed_from_page chunks_from_api = [ [ { 'human-name': 'A', 'machine_name': 'a' }, { 'human-name': 'B', 'machine_name': 'b' }, ], [ { 'human-name': 'C', 'machine_name': 'c' }, { 'human-name': 'D', 'machine_name': 'd' }, ], [ { 'human-name': 'E', 'machine_name': 'e' }, ], ] api_mock.get_trove_details = MagicMock(return_value=aiter(chunks_from_api)) ctx = None trove_games = [] async for bunch in plugin.get_subscription_games('Humble Trove', ctx): trove_games.extend(bunch) assert sorted(trove_games, key=lambda x: x.game_id) \ == sorted([ SubscriptionGame(game_title='A', game_id='a'), SubscriptionGame('B', 'b'), SubscriptionGame('C', 'c'), SubscriptionGame('D', 'd'), SubscriptionGame('E', 'e'), SubscriptionGame('Z', 'z'), SubscriptionGame('A', 'a') # don't mind returning 2 times the same item ], key=lambda x: x.game_id)
async def get_games_in_subscription(self, tier): url = f"https://api3.origin.com/ecommerce2/vaultInfo/Origin Membership/tiers/{tier}" headers = { "Accept": "application/vnd.origin.v3+json; x-cache/force-write" } response = await self._http_client.get(url, headers=headers) try: games = await response.json() return [SubscriptionGame(game_title=game['displayName'], game_id=game['offerId']) for game in games['game']] except (ValueError, KeyError) as e: logging.exception("Can not parse backend response while getting subs games: %s, error %s", await response.text(), repr(e)) raise UnknownBackendResponse()
async def get_games_in_subscription(self, tier) -> List[SubscriptionGame]: """ Note: `game_id` of an returned subscription game may not match with `game_id` of the game added to user library! """ url = f"{self._get_api_host()}/ecommerce2/vaultInfo/Origin Membership/tiers/{tier}" headers = { "Accept": "application/vnd.origin.v3+json; x-cache/force-write" } response = await self._http_client.get(url, headers=headers) try: games = await response.json() subscription_suffix = '@subscription' # externalType for compatibility with owned games interface return [ SubscriptionGame(game_title=game['displayName'], game_id=game['offerId'] + subscription_suffix) for game in games['game'] ] except (ValueError, KeyError) as e: logger.exception( "Can not parse backend response while getting subs games: %s, error %s", await response.text(), repr(e)) raise UnknownBackendResponse()
import pytest from tests.async_mock import AsyncMock from galaxy.api.types import Subscription, SubscriptionGame, SubscriptionDiscovery from galaxy.api.errors import BackendError TEST_SUB_GAMES = [ SubscriptionGame(game_title='game_a', game_id='123'), SubscriptionGame(game_title='game_b', game_id='321'), SubscriptionGame(game_title='game_c', game_id='231')] SUBSCRIPTION_RESPONSE_OK = { 'games': [{ 'id': 344, 'name': 'game_a', 'image': 'https://store.ubi.com/dw/image/v2/ABBS_PRD/on/demandware.static/-/Sites-masterCatalog/default/dw4b85c1f8/images/large/5d2628e65cdf9a0bf0481659.jauthenticated_plugin?sw=220&sh=440&sm=fit', 'gameId': 5, 'packageId': 14653, 'uplayGameId': 123, 'ownership': 1, 'hasSavefilesAlert': True, 'releaseDate': '2019-04-16', 'brand': 'ANNO' }, { 'id': 297, 'name': 'game_b', 'image': 'https://ubistatic2-a.akamaihd.net/webservicesteam/uplayplusvault/PROD/covers/Anno_2205.jauthenticated_plugin', 'gameId': 7, 'packageId': 14654, 'uplayGameId': 321,
async def prepare_subscription_games_context( self, subscription_names: List[str]) -> Any: return [ SubscriptionGame(game_id=str(game['id']), game_title=game['title']) for game in self._games_cache.get_shared_games() ]
}, "offerId": "Origin.OFR.50.0003802", "itemId": "Origin.ITM.50.0003254", } ] }, "offerId": "Origin.OFR.50.0003802", "gameEditionTypeFacetKeyRankDesc": "3000", }, ] } SUBSCRIPTION_GAMES = [ SubscriptionGame( game_title="Mass Effect 3 N7 Digital Deluxe Edition - PC - WW (Origin/3PDD)", game_id="DR:230773600@subscription", start_time=None, end_time=None, ), SubscriptionGame( game_title="LEGRAND LEGACY: Tale of the Fatebounds - PC - WW - (Origin)", game_id="Origin.OFR.50.0003727@subscription", start_time=None, end_time=None, ), SubscriptionGame( game_title="Mable & the Wood - PC - WW - (Origin)", game_id="Origin.OFR.50.0003777@subscription", start_time=None, end_time=None, ), SubscriptionGame(
'NPWR08661_00': 1498935916.0, 'NPWR05818_00': 1494083469.0, 'NPWR08983_00': 1490903238.0, 'NPWR11556_00': 1490374318.0, 'NPWR04914_00': 1489329259.0 } USER_ACCOUNTS_DATA = { 'language': 'en_US', 'legalCountry': 'US', 'dateOfBirth': '2003-02-12', 'region': 'SCEA' } PSPLUS_GAMES = [ SubscriptionGame(game_title='BioShock: The Collection', game_id='CUSA03979_00'), SubscriptionGame(game_title='The Sims™ 4', game_id='CUSA09209_00'), SubscriptionGame(game_title='Firewall Zero Hour™', game_id='CUSA09831_00') ] PSNOW_GAMES = [ SubscriptionGame(game_title='ABZÛ', game_id='CUSA03349_00'), SubscriptionGame(game_title='ADR1FT', game_id='CUSA02572_00'), SubscriptionGame(game_title='Back to Bed', game_id='CUSA02537_00'), SubscriptionGame(game_title='Watch Dogs 2', game_id='CUSA04459_00') ] BACKEND_PSNOW_GAMES = { "id": "STORE-MSF192018-APOLLOROOT", "timestamp":
def in_galaxy_format(self): return SubscriptionGame(game_title=self.title, game_id=self.id)
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( 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)', game_id='Origin.OFR.50.0003777', start_time=None, end_time=None), SubscriptionGame(game_title='Worms W.M.D - PC - WW - (Origin)', game_id='Origin.OFR.50.0003802', start_time=None,
def in_galaxy_format(self): return SubscriptionGame(game_title=self.human_name, game_id=self.machine_name, start_time=self.date_added)
pytest.param( "<div class=ems-sdk-strand-paginator><a class=ems-sdk-product-tile-link></a></div>", [], id="'a' tag without 'data-telemetry-meta' attr"), pytest.param( '<div class=ems-sdk-strand-paginator>' '<a class=ems-sdk-product-tile-link data-telemetry-meta=""></a>' '</div>', [], id="empty 'data-telemetry-meta' attr"), pytest.param( '<div class=ems-sdk-strand-paginator>' "<a class=ems-sdk-product-tile-link data-telemetry-meta=" "'{\"id\":\"SOME_ID\",\"index\":3,\"name\":\"Firewall Zero Hour™\",\"titleId\":\"CUSA09831_00\"}'>" "</a>" '</div>', [ SubscriptionGame(game_id="CUSA09831_00", game_title="Firewall Zero Hour™") ], id="One correct game"), pytest.param( '<div class=ems-sdk-strand-paginator>' "<a class=ems-sdk-product-tile-link data-telemetry-meta=" "'{\"id\":\"SOME_ID\",\"index\":3,\"titleId\":\"CUSA09831_00\"}'>" "</a>" '</div>', [], id="Incorrect game - without name"), pytest.param( '<div class=ems-sdk-strand-paginator>' "<a class=ems-sdk-product-tile-link data-telemetry-meta=" "'{\"id\":\"SOME_ID\",\"index\":3,\"name\":\"Firewall Zero Hour™\"}'>" "</a>" '</div>', [],
def in_galaxy_format(self): return SubscriptionGame(game_title=self.human_name, game_id=self.machine_name)
'NPWR08661_00': 1498935916.0, 'NPWR05818_00': 1494083469.0, 'NPWR08983_00': 1490903238.0, 'NPWR11556_00': 1490374318.0, 'NPWR04914_00': 1489329259.0 } USER_ACCOUNTS_DATA = { 'language': 'en_US', 'legalCountry': 'US', 'dateOfBirth': '2003-02-12', 'region': 'SCEA' } SUBSCRIPTION_GAMES = [ SubscriptionGame(game_title='BioShock: The Collection', game_id='CUSA03979_00'), SubscriptionGame(game_title='The Sims™ 4', game_id='CUSA09209_00'), SubscriptionGame(game_title='Firewall Zero Hour™', game_id='CUSA09831_00') ] PSN_PLUS_MONTHLY_FREE_GAMES_HTML = """ <div class="ems-sdk-strand-paginator"> <div class="ems-sdk-strand-paginator__body"> <ul class="ems-sdk-product-tile-list psw-grid-x psw-grid-margin-x psw-tablet-l-up-6 psw-tablet-p-up-3 psw-mobile-p-up-2" data-qa="ems-sdk-product-tile-list" style="transform:translateX(0%);flex-wrap:nowrap"> <li class="psw-cell"> <div class="ems-sdk-product-tile" data-qa="ems-sdk-product-tile" data-qa-index="0"> <a class="ems-sdk-product-tile-link" href="/en-us/product/UP4040-CUSA03979_00-CONTROLUEBUNDLE0" data-track-content="web:store:product-tile" data-track-click="web:store:product-tile" data-telemetry-meta="{"id":"UP4040-CUSA03979_00-CONTROLUEBUNDLE0","index":0,"name":"BioShock: The Collection","titleId":"CUSA03979_00"}" title="BioShock: The Collection"> <div class="ems-sdk-product-tile-image" data-qa="ems-sdk-product-tile-image"> <div class="ems-sdk-product-tile-image__container"> <span data-qa="" class="psw-illustration psw-illustration--default-product-image default-product-img"> <svg>