mirror of
https://github.com/home-assistant/core.git
synced 2026-08-28 02:24:46 -05:00
Add cleanup of unused devices in NINA (#176834)
This commit is contained in:
@@ -13,7 +13,11 @@ from homeassistant.config_entries import (
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import section
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
)
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.typing import VolDictType
|
||||
|
||||
@@ -245,6 +249,7 @@ class OptionsFlowHandler(OptionsFlowWithReload):
|
||||
)
|
||||
|
||||
await self.remove_unused_entities(user_input)
|
||||
await self.remove_unused_devices(user_input)
|
||||
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.config_entry, data=user_input
|
||||
@@ -264,6 +269,20 @@ class OptionsFlowHandler(OptionsFlowWithReload):
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def remove_unused_devices(self, user_input: dict[str, Any]) -> None:
|
||||
"""Remove devices from regions that are not selected."""
|
||||
device_registry = dr.async_get(self.hass)
|
||||
|
||||
removed_regions = set(self.data[CONF_REGIONS]) - set(user_input[CONF_REGIONS])
|
||||
|
||||
for region in removed_regions:
|
||||
if device := device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, region)}
|
||||
):
|
||||
device_registry.async_update_device(
|
||||
device.id, remove_config_entry_id=self.config_entry.entry_id
|
||||
)
|
||||
|
||||
async def remove_unused_entities(self, user_input: dict[str, Any]) -> None:
|
||||
"""Remove entities which are not used anymore."""
|
||||
entity_registry = er.async_get(self.hass)
|
||||
|
||||
@@ -14,6 +14,7 @@ from .const import (
|
||||
DUMMY_CONFIG_ENTRY,
|
||||
DUMMY_CONFIG_ENTRY_AREA_FILTERS,
|
||||
DUMMY_CONFIG_ENTRY_DEFAULT_FILTERS,
|
||||
DUMMY_CONFIG_ENTRY_MULTIPLE_REGIONS,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
@@ -80,6 +81,22 @@ def mock_config_entry_area_filter(hass: HomeAssistant) -> MockConfigEntry:
|
||||
return config_entry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry_multiple_regions(hass: HomeAssistant) -> MockConfigEntry:
|
||||
"""Provide a common mock config entry with an area filter."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="NINA",
|
||||
data=deepcopy(DUMMY_CONFIG_ENTRY_MULTIPLE_REGIONS),
|
||||
version=1,
|
||||
minor_version=3,
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
return config_entry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_nina_class(nina_region_codes: dict[str, str]) -> Generator[AsyncMock]:
|
||||
"""Fixture to mock the NINA class."""
|
||||
|
||||
@@ -55,3 +55,12 @@ DUMMY_CONFIG_ENTRY_AREA_FILTERS: dict[str, Any] = {
|
||||
CONF_AREA_FILTER: ".*nagold.*",
|
||||
},
|
||||
}
|
||||
|
||||
DUMMY_CONFIG_ENTRY_MULTIPLE_REGIONS: dict[str, Any] = {
|
||||
CONF_MESSAGE_SLOTS: 5,
|
||||
CONF_REGIONS: {"083350000000": "Aach, Stadt", "010590000000": "Test, Stadt"},
|
||||
CONF_FILTERS: {
|
||||
CONF_HEADLINE_FILTER: "/(?!)/",
|
||||
CONF_AREA_FILTER: ".*nagold.*",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ from homeassistant.components.nina.const import (
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from . import setup_platform
|
||||
from .const import DUMMY_USER_INPUT
|
||||
@@ -327,3 +327,52 @@ async def test_options_flow_entity_removal(
|
||||
)
|
||||
|
||||
assert len(entries) == new_slot_count * entities_per_slot
|
||||
|
||||
|
||||
async def test_options_flow_device_removal(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_config_entry_multiple_regions: MockConfigEntry,
|
||||
mock_nina_class: AsyncMock,
|
||||
nina_warnings: list[Warning],
|
||||
) -> None:
|
||||
"""Test if old devices are removed."""
|
||||
await setup_platform(
|
||||
hass, mock_config_entry_multiple_regions, mock_nina_class, nina_warnings
|
||||
)
|
||||
|
||||
old_devices = dr.async_entries_for_config_entry(
|
||||
device_registry, mock_config_entry_multiple_regions.entry_id
|
||||
)
|
||||
|
||||
assert len(old_devices) == len(
|
||||
mock_config_entry_multiple_regions.data.get(CONF_REGIONS, [])
|
||||
)
|
||||
|
||||
result = await hass.config_entries.options.async_init(
|
||||
mock_config_entry_multiple_regions.entry_id
|
||||
)
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_MESSAGE_SLOTS: 5,
|
||||
CONST_REGION_A_TO_D: ["095760000000_0"],
|
||||
CONST_REGION_E_TO_H: [],
|
||||
CONST_REGION_I_TO_L: [],
|
||||
CONST_REGION_M_TO_Q: [],
|
||||
CONST_REGION_R_TO_U: [],
|
||||
CONST_REGION_V_TO_Z: [],
|
||||
CONF_FILTERS: {},
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
|
||||
devices = dr.async_entries_for_config_entry(
|
||||
device_registry, mock_config_entry_multiple_regions.entry_id
|
||||
)
|
||||
|
||||
assert not any(
|
||||
old_device.id in (device.id for device in devices) for old_device in old_devices
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user