mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 18:27:51 +00:00
Add support for async_remove_config_entry_device to august (#72627)
This commit is contained in:
parent
f4d339119f
commit
06ebc1fa14
@ -21,6 +21,7 @@ from homeassistant.exceptions import (
|
|||||||
ConfigEntryNotReady,
|
ConfigEntryNotReady,
|
||||||
HomeAssistantError,
|
HomeAssistantError,
|
||||||
)
|
)
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
|
||||||
from .activity import ActivityStream
|
from .activity import ActivityStream
|
||||||
from .const import DOMAIN, MIN_TIME_BETWEEN_DETAIL_UPDATES, PLATFORMS
|
from .const import DOMAIN, MIN_TIME_BETWEEN_DETAIL_UPDATES, PLATFORMS
|
||||||
@ -283,12 +284,15 @@ class AugustData(AugustSubscriberMixin):
|
|||||||
device.device_id,
|
device.device_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_device_name(self, device_id):
|
def get_device(self, device_id: str) -> Doorbell | Lock | None:
|
||||||
|
"""Get a device by id."""
|
||||||
|
return self._locks_by_id.get(device_id) or self._doorbells_by_id.get(device_id)
|
||||||
|
|
||||||
|
def _get_device_name(self, device_id: str) -> str | None:
|
||||||
"""Return doorbell or lock name as August has it stored."""
|
"""Return doorbell or lock name as August has it stored."""
|
||||||
if device_id in self._locks_by_id:
|
if device := self.get_device(device_id):
|
||||||
return self._locks_by_id[device_id].device_name
|
return device.device_name
|
||||||
if device_id in self._doorbells_by_id:
|
return None
|
||||||
return self._doorbells_by_id[device_id].device_name
|
|
||||||
|
|
||||||
async def async_lock(self, device_id):
|
async def async_lock(self, device_id):
|
||||||
"""Lock the device."""
|
"""Lock the device."""
|
||||||
@ -403,3 +407,15 @@ def _restore_live_attrs(lock_detail, attrs):
|
|||||||
"""Restore the non-cache attributes after a cached update."""
|
"""Restore the non-cache attributes after a cached update."""
|
||||||
for attr, value in attrs.items():
|
for attr, value in attrs.items():
|
||||||
setattr(lock_detail, attr, value)
|
setattr(lock_detail, attr, value)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_remove_config_entry_device(
|
||||||
|
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry
|
||||||
|
) -> bool:
|
||||||
|
"""Remove august config entry from a device if its no longer present."""
|
||||||
|
data: AugustData = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
return not any(
|
||||||
|
identifier
|
||||||
|
for identifier in device_entry.identifiers
|
||||||
|
if identifier[0] == DOMAIN and data.get_device(identifier[1])
|
||||||
|
)
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
"""Mocks for the august component."""
|
"""Mocks for the august component."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
from typing import Any, Iterable
|
||||||
from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch
|
from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch
|
||||||
|
|
||||||
from yalexs.activity import (
|
from yalexs.activity import (
|
||||||
@ -26,7 +29,9 @@ from yalexs.lock import Lock, LockDetail
|
|||||||
from yalexs.pubnub_async import AugustPubNub
|
from yalexs.pubnub_async import AugustPubNub
|
||||||
|
|
||||||
from homeassistant.components.august.const import CONF_LOGIN_METHOD, DOMAIN
|
from homeassistant.components.august.const import CONF_LOGIN_METHOD, DOMAIN
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, load_fixture
|
from tests.common import MockConfigEntry, load_fixture
|
||||||
|
|
||||||
@ -76,9 +81,13 @@ async def _mock_setup_august(
|
|||||||
|
|
||||||
|
|
||||||
async def _create_august_with_devices(
|
async def _create_august_with_devices(
|
||||||
hass, devices, api_call_side_effects=None, activities=None, pubnub=None
|
hass: HomeAssistant,
|
||||||
):
|
devices: Iterable[LockDetail | DoorbellDetail],
|
||||||
entry, api_instance = await _create_august_api_with_devices(
|
api_call_side_effects: dict[str, Any] | None = None,
|
||||||
|
activities: list[Any] | None = None,
|
||||||
|
pubnub: AugustPubNub | None = None,
|
||||||
|
) -> ConfigEntry:
|
||||||
|
entry, _ = await _create_august_api_with_devices(
|
||||||
hass, devices, api_call_side_effects, activities, pubnub
|
hass, devices, api_call_side_effects, activities, pubnub
|
||||||
)
|
)
|
||||||
return entry
|
return entry
|
||||||
|
@ -17,6 +17,9 @@ from homeassistant.const import (
|
|||||||
STATE_ON,
|
STATE_ON,
|
||||||
)
|
)
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
|
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.august.mocks import (
|
from tests.components.august.mocks import (
|
||||||
@ -318,3 +321,46 @@ async def test_load_unload(hass):
|
|||||||
|
|
||||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
async def remove_device(ws_client, device_id, config_entry_id):
|
||||||
|
"""Remove config entry from a device."""
|
||||||
|
await ws_client.send_json(
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"type": "config/device_registry/remove_config_entry",
|
||||||
|
"config_entry_id": config_entry_id,
|
||||||
|
"device_id": device_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
response = await ws_client.receive_json()
|
||||||
|
return response["success"]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_remove_devices(hass, hass_ws_client):
|
||||||
|
"""Test we can only remove a device that no longer exists."""
|
||||||
|
assert await async_setup_component(hass, "config", {})
|
||||||
|
august_operative_lock = await _mock_operative_august_lock_detail(hass)
|
||||||
|
config_entry = await _create_august_with_devices(hass, [august_operative_lock])
|
||||||
|
registry: EntityRegistry = er.async_get(hass)
|
||||||
|
entity = registry.entities["lock.a6697750d607098bae8d6baa11ef8063_name"]
|
||||||
|
|
||||||
|
device_registry = dr.async_get(hass)
|
||||||
|
device_entry = device_registry.async_get(entity.device_id)
|
||||||
|
assert (
|
||||||
|
await remove_device(
|
||||||
|
await hass_ws_client(hass), device_entry.id, config_entry.entry_id
|
||||||
|
)
|
||||||
|
is False
|
||||||
|
)
|
||||||
|
|
||||||
|
dead_device_entry = device_registry.async_get_or_create(
|
||||||
|
config_entry_id=config_entry.entry_id,
|
||||||
|
identifiers={(DOMAIN, "remove-device-id")},
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
await remove_device(
|
||||||
|
await hass_ws_client(hass), dead_device_entry.id, config_entry.entry_id
|
||||||
|
)
|
||||||
|
is True
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user