mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 07:51:46 -05:00
Fix offline devices being removed in Xbox integration (#181045)
This commit is contained in:
@@ -88,6 +88,27 @@ async def async_unload_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> boo
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_remove_config_entry_device(
|
||||
hass: HomeAssistant,
|
||||
config_entry: XboxConfigEntry,
|
||||
device_entry: dr.AnyDeviceEntry,
|
||||
) -> bool:
|
||||
"""Remove a stale device from a config entry."""
|
||||
|
||||
return not any(
|
||||
identifier
|
||||
for identifier in device_entry.identifiers
|
||||
if identifier[0] == DOMAIN
|
||||
and (
|
||||
(
|
||||
isinstance(device_entry, dr.DeviceEntry)
|
||||
and device_entry.entry_type == dr.DeviceEntryType.SERVICE
|
||||
)
|
||||
or identifier[1] in config_entry.runtime_data.consoles.data
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
async def async_migrate_entry(hass: HomeAssistant, entry: XboxConfigEntry) -> bool:
|
||||
"""Migrate config entry."""
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ from pythonxbox.api.provider.titlehub.models import Title
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import DeviceEntryType
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import DOMAIN
|
||||
@@ -117,18 +115,6 @@ class XboxConsolesCoordinator(XboxBaseCoordinator[dict[str, SmartglassConsole]])
|
||||
"Found %d consoles: %s", len(consoles.result), consoles.model_dump()
|
||||
)
|
||||
|
||||
device_reg = dr.async_get(self.hass)
|
||||
identifiers = {(DOMAIN, console.id) for console in consoles.result}
|
||||
for device in dr.async_entries_for_config_entry(
|
||||
device_reg, self.config_entry.entry_id
|
||||
):
|
||||
if (
|
||||
device.entry_type is not DeviceEntryType.SERVICE
|
||||
and not set(device.identifiers) & identifiers
|
||||
):
|
||||
_LOGGER.debug("Removing stale device %s", device.name)
|
||||
device_reg.async_remove_device(device.id)
|
||||
|
||||
return {console.id: console for console in consoles.result}
|
||||
|
||||
|
||||
|
||||
@@ -23,12 +23,14 @@ from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.config_entry_oauth2_flow import (
|
||||
ImplementationUnavailableError,
|
||||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
async_fire_time_changed,
|
||||
async_load_json_object_fixture,
|
||||
)
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("xbox_live_client")
|
||||
@@ -204,9 +206,11 @@ async def test_dynamic_devices(
|
||||
xbox_live_client: AsyncMock,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
) -> None:
|
||||
"""Test adding of new and removal of stale devices at runtime."""
|
||||
|
||||
assert await async_setup_component(hass, "config", {})
|
||||
client = await hass_ws_client(hass)
|
||||
xbox_live_client.smartglass.get_console_list.return_value = SmartglassConsoleList(
|
||||
**await async_load_json_object_fixture(
|
||||
hass, "smartglass_console_list_empty.json", DOMAIN
|
||||
@@ -225,12 +229,6 @@ async def test_dynamic_devices(
|
||||
)
|
||||
is None
|
||||
)
|
||||
assert (
|
||||
device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "HIJKLMN"), config_entry.entry_id
|
||||
)
|
||||
is None
|
||||
)
|
||||
|
||||
xbox_live_client.smartglass.get_console_list.return_value = SmartglassConsoleList(
|
||||
**await async_load_json_object_fixture(
|
||||
@@ -242,13 +240,15 @@ async def test_dynamic_devices(
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "ABCDEFG"), config_entry.entry_id
|
||||
)
|
||||
assert device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "HIJKLMN"), config_entry.entry_id
|
||||
assert (
|
||||
device := device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "ABCDEFG"), config_entry.entry_id
|
||||
)
|
||||
)
|
||||
|
||||
response = await client.remove_device(device.id)
|
||||
assert not response["success"]
|
||||
|
||||
xbox_live_client.smartglass.get_console_list.return_value = SmartglassConsoleList(
|
||||
**await async_load_json_object_fixture(
|
||||
hass, "smartglass_console_list_empty.json", DOMAIN
|
||||
@@ -259,15 +259,21 @@ async def test_dynamic_devices(
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
response = await client.remove_device(device.id)
|
||||
assert response["success"]
|
||||
|
||||
assert (
|
||||
device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "ABCDEFG"), config_entry.entry_id
|
||||
)
|
||||
is None
|
||||
)
|
||||
|
||||
# Test that service devices cannot be removed
|
||||
assert (
|
||||
device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "HIJKLMN"), config_entry.entry_id
|
||||
account := device_registry.async_get_device_by_identifier(
|
||||
(DOMAIN, "271958441785640"), config_entry.entry_id
|
||||
)
|
||||
is None
|
||||
)
|
||||
response = await client.remove_device(account.id)
|
||||
assert not response["success"]
|
||||
|
||||
Reference in New Issue
Block a user