mirror of
https://github.com/home-assistant/core.git
synced 2026-02-15 07:36:16 +00:00
Increase test coverage in Xbox integration (#162876)
This commit is contained in:
@@ -168,36 +168,40 @@ class XboxConsoleStatusCoordinator(XboxBaseCoordinator[dict[str, ConsoleData]]):
|
||||
_LOGGER.debug("%s status: %s", console.name, status.model_dump())
|
||||
|
||||
# Setup focus app
|
||||
app_details: Product | None = None
|
||||
if (current_state := self.data.get(console.id)) is not None:
|
||||
app_details = current_state.app_details
|
||||
app_details = (
|
||||
current_state.app_details
|
||||
if (current_state := self.data.get(console.id)) is not None
|
||||
and status.focus_app_aumid
|
||||
else None
|
||||
)
|
||||
|
||||
if status.focus_app_aumid:
|
||||
if (
|
||||
not current_state
|
||||
or status.focus_app_aumid != current_state.status.focus_app_aumid
|
||||
):
|
||||
app_id = status.focus_app_aumid.split("!")[0]
|
||||
id_type = AlternateIdType.PACKAGE_FAMILY_NAME
|
||||
if app_id in SYSTEM_PFN_ID_MAP:
|
||||
id_type = AlternateIdType.LEGACY_XBOX_PRODUCT_ID
|
||||
app_id = SYSTEM_PFN_ID_MAP[app_id][id_type]
|
||||
|
||||
catalog_result = (
|
||||
await self.client.catalog.get_product_from_alternate_id(
|
||||
app_id, id_type
|
||||
)
|
||||
if status.focus_app_aumid and (
|
||||
not current_state
|
||||
or status.focus_app_aumid != current_state.status.focus_app_aumid
|
||||
):
|
||||
catalog_result = (
|
||||
await self.client.catalog.get_product_from_alternate_id(
|
||||
*self._resolve_app_id(status.focus_app_aumid)
|
||||
)
|
||||
)
|
||||
|
||||
if catalog_result.products:
|
||||
app_details = catalog_result.products[0]
|
||||
else:
|
||||
app_details = None
|
||||
if catalog_result.products:
|
||||
app_details = catalog_result.products[0]
|
||||
|
||||
data[console.id] = ConsoleData(status=status, app_details=app_details)
|
||||
|
||||
return data
|
||||
|
||||
def _resolve_app_id(self, focus_app_aumid: str) -> tuple[str, AlternateIdType]:
|
||||
app_id = focus_app_aumid.split("!", maxsplit=1)[0]
|
||||
id_type = AlternateIdType.PACKAGE_FAMILY_NAME
|
||||
|
||||
if app_id in SYSTEM_PFN_ID_MAP:
|
||||
id_type = AlternateIdType.LEGACY_XBOX_PRODUCT_ID
|
||||
app_id = SYSTEM_PFN_ID_MAP[app_id][id_type]
|
||||
|
||||
return app_id, id_type
|
||||
|
||||
|
||||
class XboxPresenceCoordinator(XboxBaseCoordinator[XboxData]):
|
||||
"""Update list of Xbox consoles."""
|
||||
|
||||
@@ -148,10 +148,12 @@ class XboxMediaPlayer(XboxConsoleBaseEntity, MediaPlayerEntity):
|
||||
@property
|
||||
def media_content_type(self) -> MediaType:
|
||||
"""Media content type."""
|
||||
app_details = self.data.app_details
|
||||
if app_details and app_details.product_family == "Games":
|
||||
return MediaType.GAME
|
||||
return MediaType.APP
|
||||
|
||||
return (
|
||||
MediaType.GAME
|
||||
if self.data.app_details and self.data.app_details.product_family == "Games"
|
||||
else MediaType.APP
|
||||
)
|
||||
|
||||
@property
|
||||
def media_content_id(self) -> str | None:
|
||||
@@ -161,11 +163,13 @@ class XboxMediaPlayer(XboxConsoleBaseEntity, MediaPlayerEntity):
|
||||
@property
|
||||
def media_title(self) -> str | None:
|
||||
"""Title of current playing media."""
|
||||
if not (app_details := self.data.app_details):
|
||||
return None
|
||||
return (
|
||||
app_details.localized_properties[0].product_title
|
||||
or app_details.localized_properties[0].short_title
|
||||
(
|
||||
app_details.localized_properties[0].product_title
|
||||
or app_details.localized_properties[0].short_title
|
||||
)
|
||||
if (app_details := self.data.app_details)
|
||||
else None
|
||||
)
|
||||
|
||||
@property
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"BigIds": ["9WZDNCRFJ3TJ"],
|
||||
"HasMorePages": false,
|
||||
"Products": [
|
||||
{
|
||||
"LocalizedProperties": [
|
||||
{
|
||||
"Images": [
|
||||
{
|
||||
"FileId": "2000000000037288315",
|
||||
"EISListingIdentifier": null,
|
||||
"BackgroundColor": "",
|
||||
"Caption": "",
|
||||
"FileSizeInBytes": 2514491,
|
||||
"ForegroundColor": "",
|
||||
"Height": 1080,
|
||||
"ImagePositionInfo": "",
|
||||
"ImagePurpose": "FeaturePromotionalSquareArt",
|
||||
"UnscaledImageSHA256Hash": "i7GhC2HdYXf69+X/mLHtm8B36zR1gEOfuG2g2bXAAnY=",
|
||||
"Uri": "//store-images.s-microsoft.com/image/apps.45451.65457035095819016.56f55216-1bb9-40aa-8796-068cf3075fc1.3abf2cc3-00cc-417d-a93d-97110cdfb261",
|
||||
"Width": 1080
|
||||
}
|
||||
],
|
||||
"ProductTitle": "Blue Dragon"
|
||||
}
|
||||
],
|
||||
"MarketProperties": [],
|
||||
"ProductBSchema": "ProductGame;1",
|
||||
"ProductId": "C2HGK9J5367F",
|
||||
"PartD": "",
|
||||
"ProductFamily": "Games",
|
||||
"ProductKind": "Game",
|
||||
"DisplaySkuAvailabilities": []
|
||||
}
|
||||
],
|
||||
"TotalResultCount": 1
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"BigIds": ["9VWGNH0VBZJX"],
|
||||
"HasMorePages": false,
|
||||
"Products": [
|
||||
{
|
||||
"LastModifiedDate": "2014-10-21T17:30:01.0000000+00:00",
|
||||
"LocalizedProperties": [
|
||||
{
|
||||
"Images": [
|
||||
{
|
||||
"FileSizeInBytes": 0,
|
||||
"Height": 1080,
|
||||
"ImagePositionInfo": "Xbox",
|
||||
"ImagePurpose": "FeaturePromotionalSquareArt",
|
||||
"SortOrder": "0",
|
||||
"Uri": "https://images-eds-ssl.xboxlive.com/image?url=8Oaj9Ryq1G1_p3lLnXlsaZgGzAie6Mnu24_PawYuDYIoH77pJ.X5Z.MqQPibUVTcbx57bBxf63xu2Ef8acP3S7Uz80NbHc5nza..4R00GT1V5G760cdfX7Hl0uIHdHCbkzTikdvNE0TedhKgQfQy.2gjOGbd8kXZXzy4VzeJiNPLhLq2QUQbo8q3sVoSPaw73J4BxM7gaNX8V8qLcWtO5sn6vgbTso51OaEIn4zeAiw-",
|
||||
"Width": 1080
|
||||
}
|
||||
],
|
||||
"Language": "en-US",
|
||||
"PublisherName": "Microsoft",
|
||||
"SearchTitles": [
|
||||
{ "SearchTitleString": "TV", "SearchTitleType": "SearchHint" }
|
||||
],
|
||||
"ShortTitle": "TV",
|
||||
"SortTitle": "TV",
|
||||
"Videos": [],
|
||||
"VoiceTitle": "TV",
|
||||
"ProductDescription": "",
|
||||
"ProductTitle": "TV",
|
||||
"Markets": []
|
||||
}
|
||||
],
|
||||
"MarketProperties": [],
|
||||
"ProductASchema": "Product;3",
|
||||
"ProductBSchema": "ProductUnifiedApp;3",
|
||||
"ProductId": "9VWGNH0VBZJX",
|
||||
"Properties": {
|
||||
"AllowedUrls": [],
|
||||
"Categories": ["Video"],
|
||||
"PublisherId": "",
|
||||
"SkuDisplayGroups": [],
|
||||
"RevisionId": "2014-10-21T17:30:01.0000000+00:00"
|
||||
},
|
||||
"AlternateIds": [
|
||||
{
|
||||
"IdType": "LegacyXboxProductId",
|
||||
"Value": "71e7df12-89e0-4dc7-a5ff-a182fc2df94f"
|
||||
},
|
||||
{ "IdType": "XboxTitleId", "Value": "371594669" }
|
||||
],
|
||||
"DomainDataVersion": "",
|
||||
"IngestionSource": "Bingbox App",
|
||||
"IsMicrosoftProduct": false,
|
||||
"ProductType": "Application",
|
||||
"ValidationData": null,
|
||||
"MerchandizingTags": null,
|
||||
"SandboxId": "RETAIL",
|
||||
"ProductFamily": "Apps",
|
||||
"SchemaVersion": "1",
|
||||
"IsSandboxedProduct": true,
|
||||
"ProductKind": "Application",
|
||||
"ProductPolicies": {},
|
||||
"DisplaySkuAvailabilities": []
|
||||
}
|
||||
],
|
||||
"TotalResultCount": 2
|
||||
}
|
||||
@@ -118,7 +118,7 @@
|
||||
},
|
||||
{
|
||||
"xuid": "2533274913657542",
|
||||
"isFavorite": true,
|
||||
"isFavorite": false,
|
||||
"isFollowingCaller": true,
|
||||
"isFollowedByCaller": true,
|
||||
"isIdentityShared": false,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"status": {
|
||||
"errorCode": "OK",
|
||||
"errorMessage": null
|
||||
},
|
||||
"powerState": "On",
|
||||
"playbackState": "Stopped",
|
||||
"loginState": null,
|
||||
"focusAppAumid": "",
|
||||
"isTvConfigured": true,
|
||||
"digitalAssistantRemoteControlEnabled": true,
|
||||
"consoleStreamingEnabled": false,
|
||||
"remoteManagementEnabled": true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"status": {
|
||||
"errorCode": "OK",
|
||||
"errorMessage": null
|
||||
},
|
||||
"powerState": "On",
|
||||
"playbackState": "Stopped",
|
||||
"loginState": null,
|
||||
"focusAppAumid": "Microsoft.Xbox.LiveTV_8wekyb3d8bbwe!Microsoft.Xbox.LiveTV.Application",
|
||||
"isTvConfigured": true,
|
||||
"digitalAssistantRemoteControlEnabled": true,
|
||||
"consoleStreamingEnabled": false,
|
||||
"remoteManagementEnabled": true
|
||||
}
|
||||
@@ -9588,7 +9588,7 @@
|
||||
'gamertag': '**REDACTED**',
|
||||
'is_broadcasting': False,
|
||||
'is_cloaked': None,
|
||||
'is_favorite': True,
|
||||
'is_favorite': False,
|
||||
'is_followed_by_caller': True,
|
||||
'is_following_caller': True,
|
||||
'is_friend': True,
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
'title': 'Installed Applications',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[media_player.xone-entry]
|
||||
# name: test_media_players[app][media_player.xone-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@@ -161,7 +161,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[media_player.xone-state]
|
||||
# name: test_media_players[app][media_player.xone-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://store-images.s-microsoft.com/image/apps.9815.9007199266246365.7dc5d343-fe4a-40c3-93dd-c78e77f97331.45eebdef-f725-4799-bbf8-9ad8391a8279',
|
||||
@@ -180,7 +180,7 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[media_player.xonex-entry]
|
||||
# name: test_media_players[app][media_player.xonex-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@@ -217,7 +217,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[media_player.xonex-state]
|
||||
# name: test_media_players[app][media_player.xonex-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://store-images.s-microsoft.com/image/apps.9815.9007199266246365.7dc5d343-fe4a-40c3-93dd-c78e77f97331.45eebdef-f725-4799-bbf8-9ad8391a8279',
|
||||
@@ -236,3 +236,221 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[idle][media_player.xone-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'media_player',
|
||||
'entity_category': None,
|
||||
'entity_id': 'media_player.xone',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
'translation_key': 'xbox',
|
||||
'unique_id': 'HIJKLMN',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[idle][media_player.xone-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture_local': None,
|
||||
'friendly_name': 'XONE',
|
||||
'media_content_type': <MediaType.APP: 'app'>,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'media_player.xone',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[idle][media_player.xonex-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'media_player',
|
||||
'entity_category': None,
|
||||
'entity_id': 'media_player.xonex',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
'translation_key': 'xbox',
|
||||
'unique_id': 'ABCDEFG',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[idle][media_player.xonex-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture_local': None,
|
||||
'friendly_name': 'XONEX',
|
||||
'media_content_type': <MediaType.APP: 'app'>,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'media_player.xonex',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[livetvapp][media_player.xone-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'media_player',
|
||||
'entity_category': None,
|
||||
'entity_id': 'media_player.xone',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
'translation_key': 'xbox',
|
||||
'unique_id': 'HIJKLMN',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[livetvapp][media_player.xone-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://images-eds-ssl.xboxlive.com/image?url=8Oaj9Ryq1G1_p3lLnXlsaZgGzAie6Mnu24_PawYuDYIoH77pJ.X5Z.MqQPibUVTcbx57bBxf63xu2Ef8acP3S7Uz80NbHc5nza..4R00GT1V5G760cdfX7Hl0uIHdHCbkzTikdvNE0TedhKgQfQy.2gjOGbd8kXZXzy4VzeJiNPLhLq2QUQbo8q3sVoSPaw73J4BxM7gaNX8V8qLcWtO5sn6vgbTso51OaEIn4zeAiw-',
|
||||
'entity_picture_local': '/api/media_player_proxy/media_player.xone?token=mock_token&cache=cf419ddd9fb966d6',
|
||||
'friendly_name': 'XONE',
|
||||
'media_content_id': '9VWGNH0VBZJX',
|
||||
'media_content_type': <MediaType.APP: 'app'>,
|
||||
'media_title': 'TV',
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'media_player.xone',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[livetvapp][media_player.xonex-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'media_player',
|
||||
'entity_category': None,
|
||||
'entity_id': 'media_player.xonex',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'xbox',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
'translation_key': 'xbox',
|
||||
'unique_id': 'ABCDEFG',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_media_players[livetvapp][media_player.xonex-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'entity_picture': 'https://images-eds-ssl.xboxlive.com/image?url=8Oaj9Ryq1G1_p3lLnXlsaZgGzAie6Mnu24_PawYuDYIoH77pJ.X5Z.MqQPibUVTcbx57bBxf63xu2Ef8acP3S7Uz80NbHc5nza..4R00GT1V5G760cdfX7Hl0uIHdHCbkzTikdvNE0TedhKgQfQy.2gjOGbd8kXZXzy4VzeJiNPLhLq2QUQbo8q3sVoSPaw73J4BxM7gaNX8V8qLcWtO5sn6vgbTso51OaEIn4zeAiw-',
|
||||
'entity_picture_local': '/api/media_player_proxy/media_player.xonex?token=mock_token&cache=cf419ddd9fb966d6',
|
||||
'friendly_name': 'XONEX',
|
||||
'media_content_id': '9VWGNH0VBZJX',
|
||||
'media_content_type': <MediaType.APP: 'app'>,
|
||||
'media_title': 'TV',
|
||||
'supported_features': <MediaPlayerEntityFeature: 149385>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'media_player.xonex',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
from http import HTTPStatus
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from httpx import HTTPStatusError, RequestError, TimeoutException
|
||||
import pytest
|
||||
from pythonxbox.api.provider.people.models import PeopleResponse
|
||||
|
||||
@@ -22,7 +23,10 @@ from homeassistant.config_entries import (
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from homeassistant.helpers import config_entry_oauth2_flow, device_registry as dr
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
ImplementationUnavailableError,
|
||||
)
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
from homeassistant.helpers.service_info.ssdp import SsdpServiceInfo
|
||||
|
||||
@@ -576,7 +580,10 @@ async def test_add_friend_flow_config_entry_not_loaded(
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client", "authentication_manager")
|
||||
async def test_unique_id_and_friends_migration(hass: HomeAssistant) -> None:
|
||||
async def test_unique_id_and_friends_migration(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test config entry unique_id migration and favorite to subentry migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@@ -601,6 +608,17 @@ async def test_unique_id_and_friends_migration(hass: HomeAssistant) -> None:
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
device_own = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
identifiers={(DOMAIN, "xbox_live")},
|
||||
)
|
||||
|
||||
device_friend = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
identifiers={(DOMAIN, "2533274838782903")},
|
||||
)
|
||||
assert device_friend.config_entries_subentries[config_entry.entry_id] == {None}
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -611,14 +629,111 @@ async def test_unique_id_and_friends_migration(hass: HomeAssistant) -> None:
|
||||
assert config_entry.title == "GSR Ae"
|
||||
|
||||
# Assert favorite friends migrated to subentries
|
||||
assert len(config_entry.subentries) == 2
|
||||
assert len(config_entry.subentries) == 1
|
||||
subentries = list(config_entry.subentries.values())
|
||||
assert subentries[0].unique_id == "2533274838782903"
|
||||
assert subentries[0].title == "Ikken Hissatsuu"
|
||||
assert subentries[0].subentry_type == "friend"
|
||||
assert subentries[1].unique_id == "2533274913657542"
|
||||
assert subentries[1].title == "erics273"
|
||||
assert subentries[1].subentry_type == "friend"
|
||||
|
||||
## Assert devices have been migrated
|
||||
assert (device_own := device_registry.async_get(device_own.id))
|
||||
assert device_own.identifiers == {(DOMAIN, "271958441785640")}
|
||||
|
||||
assert (device_friend := device_registry.async_get(device_friend.id))
|
||||
assert device_friend.config_entries_subentries[config_entry.entry_id] == {
|
||||
subentries[0].subentry_id
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("provider", "method"),
|
||||
[
|
||||
("people", "get_friends_by_xuid"),
|
||||
("people", "get_friends_own"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
[
|
||||
TimeoutException(""),
|
||||
RequestError("", request=Mock()),
|
||||
HTTPStatusError("", request=Mock(), response=Mock()),
|
||||
],
|
||||
)
|
||||
@pytest.mark.usefixtures("authentication_manager")
|
||||
async def test_migration_exceptions(
|
||||
hass: HomeAssistant,
|
||||
xbox_live_client: AsyncMock,
|
||||
provider: str,
|
||||
method: str,
|
||||
exception: Exception,
|
||||
) -> None:
|
||||
"""Test exceptions during migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home Assistant Cloud",
|
||||
data={
|
||||
"auth_implementation": "cloud",
|
||||
"token": {
|
||||
"access_token": "1234567890",
|
||||
"expires_at": 1760697327.7298331,
|
||||
"expires_in": 3600,
|
||||
"refresh_token": "0987654321",
|
||||
"scope": "XboxLive.signin XboxLive.offline_access",
|
||||
"service": "xbox",
|
||||
"token_type": "bearer",
|
||||
"user_id": "AAAAAAAAAAAAAAAAAAAAA",
|
||||
},
|
||||
},
|
||||
unique_id=DOMAIN,
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
|
||||
provider = getattr(xbox_live_client, provider)
|
||||
getattr(provider, method).side_effect = exception
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is config_entries.ConfigEntryState.MIGRATION_ERROR
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client", "authentication_manager")
|
||||
async def test_migration_implementation_unavailable(hass: HomeAssistant) -> None:
|
||||
"""Test implementation unavailable exception during migration."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="Home Assistant Cloud",
|
||||
data={
|
||||
"auth_implementation": "cloud",
|
||||
"token": {
|
||||
"access_token": "1234567890",
|
||||
"expires_at": 1760697327.7298331,
|
||||
"expires_in": 3600,
|
||||
"refresh_token": "0987654321",
|
||||
"scope": "XboxLive.signin XboxLive.offline_access",
|
||||
"service": "xbox",
|
||||
"token_type": "bearer",
|
||||
"user_id": "AAAAAAAAAAAAAAAAAAAAA",
|
||||
},
|
||||
},
|
||||
unique_id=DOMAIN,
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"homeassistant.components.xbox.async_get_config_entry_implementation",
|
||||
side_effect=ImplementationUnavailableError,
|
||||
):
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert config_entry.state is config_entries.ConfigEntryState.MIGRATION_ERROR
|
||||
|
||||
|
||||
@pytest.mark.usefixtures(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Tests for the Xbox integration."""
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from httpx import ConnectTimeout, HTTPStatusError, ProtocolError
|
||||
@@ -42,7 +42,11 @@ async def test_entry_setup_unload(
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
[ConnectTimeout, HTTPStatusError, ProtocolError],
|
||||
[
|
||||
ConnectTimeout(""),
|
||||
HTTPStatusError("", request=Mock(), response=Mock()),
|
||||
ProtocolError(""),
|
||||
],
|
||||
)
|
||||
async def test_config_entry_not_ready(
|
||||
hass: HomeAssistant,
|
||||
@@ -78,7 +82,14 @@ async def test_config_implementation_not_available(
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
@pytest.mark.parametrize("exception", [ConnectTimeout, HTTPStatusError, ProtocolError])
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
[
|
||||
ConnectTimeout(""),
|
||||
HTTPStatusError("", request=Mock(), response=Mock()),
|
||||
ProtocolError(""),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("provider", "method"),
|
||||
[
|
||||
|
||||
@@ -7,6 +7,7 @@ from unittest.mock import patch
|
||||
|
||||
from httpx import HTTPStatusError, RequestError, TimeoutException
|
||||
import pytest
|
||||
from pythonxbox.api.provider.catalog.models import CatalogResponse
|
||||
from pythonxbox.api.provider.smartglass.models import (
|
||||
SmartglassConsoleStatus,
|
||||
VolumeDirection,
|
||||
@@ -67,15 +68,37 @@ def mock_token() -> Generator[MagicMock]:
|
||||
yield token
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@pytest.mark.parametrize(
|
||||
("fixture_status", "fixture_catalog"),
|
||||
[
|
||||
("smartglass_console_status.json", "catalog_product_lookup.json"),
|
||||
("smartglass_console_status_idle.json", "catalog_product_lookup.json"),
|
||||
("smartglass_console_status_livetv.json", "catalog_product_lookup_livetv.json"),
|
||||
],
|
||||
ids=["app", "idle", "livetvapp"],
|
||||
)
|
||||
async def test_media_players(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
xbox_live_client: AsyncMock,
|
||||
fixture_status: str,
|
||||
fixture_catalog: str | None,
|
||||
) -> None:
|
||||
"""Test setup of the Xbox media player platform."""
|
||||
|
||||
xbox_live_client.smartglass.get_console_status.return_value = (
|
||||
SmartglassConsoleStatus(
|
||||
**await async_load_json_object_fixture(hass, fixture_status, DOMAIN) # pyright: ignore[reportArgumentType]
|
||||
)
|
||||
)
|
||||
xbox_live_client.catalog.get_product_from_alternate_id.return_value = (
|
||||
CatalogResponse(
|
||||
**await async_load_json_object_fixture(hass, fixture_catalog, DOMAIN) # pyright: ignore[reportArgumentType]
|
||||
)
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
@@ -237,11 +260,11 @@ async def test_media_player_actions(
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
("exception", "translation_key"),
|
||||
[
|
||||
TimeoutException(""),
|
||||
RequestError("", request=Mock()),
|
||||
HTTPStatusError("", request=Mock(), response=Mock()),
|
||||
(TimeoutException(""), "timeout_exception"),
|
||||
(RequestError("", request=Mock()), "request_exception"),
|
||||
(HTTPStatusError("", request=Mock(), response=Mock()), "request_exception"),
|
||||
],
|
||||
)
|
||||
async def test_media_player_action_exceptions(
|
||||
@@ -252,6 +275,7 @@ async def test_media_player_action_exceptions(
|
||||
service_args: dict[str, Any],
|
||||
call_method: str,
|
||||
exception: Exception,
|
||||
translation_key: str,
|
||||
) -> None:
|
||||
"""Test media player action exceptions."""
|
||||
|
||||
@@ -271,13 +295,14 @@ async def test_media_player_action_exceptions(
|
||||
|
||||
getattr(xbox_live_client.smartglass, call_method).side_effect = exception
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
with pytest.raises(HomeAssistantError) as e:
|
||||
await hass.services.async_call(
|
||||
MEDIA_PLAYER_DOMAIN,
|
||||
service,
|
||||
target={ATTR_ENTITY_ID: "media_player.xone", **service_args},
|
||||
blocking=True,
|
||||
)
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
|
||||
async def test_media_player_turn_on_failed(
|
||||
@@ -299,10 +324,11 @@ async def test_media_player_turn_on_failed(
|
||||
),
|
||||
)
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
with pytest.raises(HomeAssistantError) as e:
|
||||
await hass.services.async_call(
|
||||
MEDIA_PLAYER_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
target={ATTR_ENTITY_ID: "media_player.xone"},
|
||||
blocking=True,
|
||||
)
|
||||
assert e.value.translation_key == "turn_on_failed"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Tests for the Xbox media source platform."""
|
||||
|
||||
import httpx
|
||||
from httpx import HTTPStatusError, RequestError, Response, TimeoutException
|
||||
import pytest
|
||||
from pythonxbox.api.provider.people.models import PeopleResponse
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
@@ -173,14 +173,30 @@ async def test_browse_media_accounts(
|
||||
"titlehub",
|
||||
"get_title_info",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_gameclips",
|
||||
"gameclips",
|
||||
"get_recent_community_clips_by_title_id",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_screenshots",
|
||||
"screenshots",
|
||||
"get_recent_community_screenshots_by_title_id",
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
("exception", "translation_key"),
|
||||
[
|
||||
httpx.HTTPStatusError("", request=MagicMock(), response=httpx.Response(500)),
|
||||
httpx.RequestError(""),
|
||||
httpx.TimeoutException(""),
|
||||
(
|
||||
HTTPStatusError("", request=MagicMock(), response=Response(500)),
|
||||
"request_exception",
|
||||
),
|
||||
(
|
||||
RequestError(""),
|
||||
"request_exception",
|
||||
),
|
||||
(TimeoutException(""), "timeout_exception"),
|
||||
],
|
||||
)
|
||||
async def test_browse_media_exceptions(
|
||||
@@ -191,6 +207,7 @@ async def test_browse_media_exceptions(
|
||||
provider: str,
|
||||
method: str,
|
||||
exception: Exception,
|
||||
translation_key: str,
|
||||
) -> None:
|
||||
"""Test browsing media exceptions."""
|
||||
|
||||
@@ -203,8 +220,9 @@ async def test_browse_media_exceptions(
|
||||
provider = getattr(xbox_live_client, provider)
|
||||
getattr(provider, method).side_effect = exception
|
||||
|
||||
with pytest.raises(BrowseError):
|
||||
with pytest.raises(BrowseError) as e:
|
||||
await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}{media_content_id}")
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@@ -239,8 +257,9 @@ async def test_browse_media_not_configured_exception(
|
||||
|
||||
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
|
||||
with pytest.raises(BrowseError, match="The Xbox integration is not configured"):
|
||||
with pytest.raises(BrowseError) as e:
|
||||
await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}")
|
||||
assert e.value.translation_key == "xbox_not_configured"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@@ -256,8 +275,9 @@ async def test_browse_media_account_not_configured_exception(
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
with pytest.raises(BrowseError):
|
||||
with pytest.raises(BrowseError) as e:
|
||||
await async_browse_media(hass, f"{URI_SCHEME}{DOMAIN}/2533274838782903")
|
||||
assert e.value.translation_key == "account_not_configured"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -278,8 +298,24 @@ async def test_browse_media_account_not_configured_exception(
|
||||
"https://store-images.s-microsoft.com/image/apps.35725.65457035095819016.56f55216-1bb9-40aa-8796-068cf3075fc1.c4bf34f8-ad40-4af3-914e-a85e75a76bed",
|
||||
"image/png",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_screenshots/504a78e5-be24-4020-a245-77cb528e91ea",
|
||||
"https://screenshotscontent-d5002.media.xboxlive.com/xuid-2535422966774043-private/504a78e5-be24-4020-a245-77cb528e91ea.PNG?skoid=296fcea0-0bf0-4a22-abf7-16b3524eba1b&sktid=68cd85cc-e0b3-43c8-ba3c-67686dbf8a67&skt=2025-11-06T10%3A21%3A06Z&ske=2025-11-07T10%3A21%3A06Z&sks=b&skv=2025-05-05&sv=2025-05-05&st=2025-11-06T10%3A35%3A59Z&se=2125-11-06T10%3A50%3A59Z&sr=b&sp=r&sig=TqUUNeuAzHawaXBTFfSVuUzuXbGOMgrDu0Q2VBTFd5U%3D",
|
||||
"image/png",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_gameclips/6fa2731a-8b58-4aa6-848c-4bf15734358b",
|
||||
"https://gameclipscontent-d3021.media.xboxlive.com/xuid-2535458333395495-private/6fa2731a-8b58-4aa6-848c-4bf15734358b.MP4?skoid=2938738c-0e58-4f21-9b82-98081ade42e2&sktid=68cd85cc-e0b3-43c8-ba3c-67686dbf8a67&skt=2025-11-06T08%3A20%3A51Z&ske=2025-11-07T08%3A20%3A51Z&sks=b&skv=2025-05-05&sv=2025-05-05&st=2025-11-06T10%3A05%3A41Z&se=2125-11-06T10%3A20%3A41Z&sr=b&sp=r&sig=s%2FWDtmE2cnAwl9iJJFcch3knbRlkxkALoinHQwCnNP0%3D&__gda__=1762438393_eb8a56c3f482d00099045aa892a2aa05",
|
||||
"video/mp4",
|
||||
),
|
||||
],
|
||||
ids=[
|
||||
"screenshot",
|
||||
"gameclips",
|
||||
"game_media",
|
||||
"community_screenshots",
|
||||
"community_gameclips",
|
||||
],
|
||||
ids=["screenshot", "gameclips", "game_media"],
|
||||
)
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
async def test_resolve_media(
|
||||
@@ -319,6 +355,16 @@ async def test_resolve_media(
|
||||
"gameclips",
|
||||
"get_recent_clips_by_xuid",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_screenshots/504a78e5-be24-4020-a245-77cb528e91ea",
|
||||
"screenshots",
|
||||
"get_recent_community_screenshots_by_title_id",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/community_gameclips/6fa2731a-8b58-4aa6-848c-4bf15734358b",
|
||||
"gameclips",
|
||||
"get_recent_community_clips_by_title_id",
|
||||
),
|
||||
(
|
||||
"/271958441785640/1297287135/game_media/0",
|
||||
"titlehub",
|
||||
@@ -327,11 +373,14 @@ async def test_resolve_media(
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
("exception", "translation_key"),
|
||||
[
|
||||
httpx.HTTPStatusError("", request=MagicMock(), response=httpx.Response(500)),
|
||||
httpx.RequestError(""),
|
||||
httpx.TimeoutException(""),
|
||||
(
|
||||
HTTPStatusError("", request=MagicMock(), response=Response(500)),
|
||||
"request_exception",
|
||||
),
|
||||
(RequestError(""), "request_exception"),
|
||||
(TimeoutException(""), "timeout_exception"),
|
||||
],
|
||||
)
|
||||
async def test_resolve_media_exceptions(
|
||||
@@ -342,6 +391,7 @@ async def test_resolve_media_exceptions(
|
||||
provider: str,
|
||||
method: str,
|
||||
exception: Exception,
|
||||
translation_key: str,
|
||||
) -> None:
|
||||
"""Test resolve media exceptions."""
|
||||
|
||||
@@ -354,12 +404,13 @@ async def test_resolve_media_exceptions(
|
||||
provider = getattr(xbox_live_client, provider)
|
||||
getattr(provider, method).side_effect = exception
|
||||
|
||||
with pytest.raises(Unresolvable):
|
||||
with pytest.raises(Unresolvable) as e:
|
||||
await async_resolve_media(
|
||||
hass,
|
||||
f"{URI_SCHEME}{DOMAIN}{media_content_id}",
|
||||
None,
|
||||
)
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("media_type"), ["screenshots", "gameclips", "game_media"])
|
||||
@@ -377,12 +428,13 @@ async def test_resolve_media_not_found_exceptions(
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
with pytest.raises(Unresolvable, match="The requested media could not be found"):
|
||||
with pytest.raises(Unresolvable) as e:
|
||||
await async_resolve_media(
|
||||
hass,
|
||||
f"{URI_SCHEME}{DOMAIN}/271958441785640/1297287135/{media_type}/12345",
|
||||
None,
|
||||
)
|
||||
assert e.value.translation_key == "media_not_found"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@@ -416,12 +468,13 @@ async def test_resolve_media_not_configured(
|
||||
|
||||
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
||||
|
||||
with pytest.raises(Unresolvable, match="The Xbox integration is not configured"):
|
||||
with pytest.raises(Unresolvable) as e:
|
||||
await async_resolve_media(
|
||||
hass,
|
||||
f"{URI_SCHEME}{DOMAIN}/2533274838782903",
|
||||
None,
|
||||
)
|
||||
assert e.value.translation_key == "xbox_not_configured"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@@ -437,9 +490,10 @@ async def test_resolve_media_account_not_configured(
|
||||
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
with pytest.raises(Unresolvable, match="The Xbox account is not configured"):
|
||||
with pytest.raises(Unresolvable) as e:
|
||||
await async_resolve_media(
|
||||
hass,
|
||||
f"{URI_SCHEME}{DOMAIN}/2533274838782903",
|
||||
None,
|
||||
)
|
||||
assert e.value.translation_key == "account_not_configured"
|
||||
|
||||
@@ -248,9 +248,7 @@ async def test_send_command_exceptions(
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
getattr(xbox_live_client.smartglass, call_method).side_effect = exception
|
||||
with pytest.raises(
|
||||
HomeAssistantError, check=lambda e: e.translation_key == translation_key
|
||||
):
|
||||
with pytest.raises(HomeAssistantError) as e:
|
||||
await hass.services.async_call(
|
||||
REMOTE_DOMAIN,
|
||||
SERVICE_SEND_COMMAND,
|
||||
@@ -258,6 +256,7 @@ async def test_send_command_exceptions(
|
||||
target={ATTR_ENTITY_ID: "remote.xone"},
|
||||
blocking=True,
|
||||
)
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -290,15 +289,14 @@ async def test_turn_on_exceptions(
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
xbox_live_client.smartglass.wake_up.side_effect = exception
|
||||
with pytest.raises(
|
||||
HomeAssistantError, check=lambda e: e.translation_key == translation_key
|
||||
):
|
||||
with pytest.raises(HomeAssistantError) as e:
|
||||
await hass.services.async_call(
|
||||
REMOTE_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
target={ATTR_ENTITY_ID: "remote.xone"},
|
||||
blocking=True,
|
||||
)
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -325,12 +323,11 @@ async def test_turn_off_exceptions(
|
||||
assert config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
xbox_live_client.smartglass.turn_off.side_effect = exception
|
||||
with pytest.raises(
|
||||
HomeAssistantError, check=lambda e: e.translation_key == translation_key
|
||||
):
|
||||
with pytest.raises(HomeAssistantError) as e:
|
||||
await hass.services.async_call(
|
||||
REMOTE_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
target={ATTR_ENTITY_ID: "remote.xone"},
|
||||
blocking=True,
|
||||
)
|
||||
assert e.value.translation_key == translation_key
|
||||
|
||||
Reference in New Issue
Block a user