mirror of
https://github.com/home-assistant/core.git
synced 2026-08-06 13:26:29 +01:00
223 lines
7.1 KiB
Python
223 lines
7.1 KiB
Python
"""Tests for the Device Utils."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
|
from homeassistant.helpers.device import (
|
|
async_device_info_to_link_from_device_id,
|
|
async_device_info_to_link_from_entity,
|
|
async_entity_id_to_device,
|
|
async_entity_id_to_device_id,
|
|
async_remove_stale_devices_links_keep_current_device,
|
|
async_remove_stale_devices_links_keep_entity_device,
|
|
)
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
async def test_entity_id_to_device_device_id(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""Test returning an entity's device / device ID."""
|
|
config_entry = MockConfigEntry(domain="my")
|
|
config_entry.add_to_hass(hass)
|
|
|
|
device = device_registry.async_get_or_create(
|
|
identifiers={("test", "current_device")},
|
|
connections={("mac", "30:31:32:33:34:00")},
|
|
config_entry_id=config_entry.entry_id,
|
|
)
|
|
assert device is not None
|
|
|
|
# Entity registry
|
|
entity = entity_registry.async_get_or_create(
|
|
"sensor",
|
|
"test",
|
|
"source",
|
|
config_entry=config_entry,
|
|
device_id=device.id,
|
|
)
|
|
await hass.async_block_till_done()
|
|
assert entity_registry.async_get("sensor.test_source") is not None
|
|
|
|
device_id = async_entity_id_to_device_id(
|
|
hass,
|
|
entity_id_or_uuid=entity.entity_id,
|
|
)
|
|
assert device_id == device.id
|
|
assert (
|
|
async_entity_id_to_device(
|
|
hass,
|
|
entity_id_or_uuid=entity.entity_id,
|
|
)
|
|
== device
|
|
)
|
|
|
|
assert (
|
|
async_entity_id_to_device_id(
|
|
hass,
|
|
entity_id_or_uuid="unknown.entity_id",
|
|
)
|
|
is None
|
|
)
|
|
assert (
|
|
async_entity_id_to_device(
|
|
hass,
|
|
entity_id_or_uuid="unknown.entity_id",
|
|
)
|
|
is None
|
|
)
|
|
|
|
device_id = async_entity_id_to_device_id(
|
|
hass,
|
|
entity_id_or_uuid=entity.id,
|
|
)
|
|
assert device_id == device.id
|
|
assert (
|
|
async_entity_id_to_device(
|
|
hass,
|
|
entity_id_or_uuid=entity.id,
|
|
)
|
|
== device
|
|
)
|
|
|
|
with pytest.raises(vol.Invalid):
|
|
async_entity_id_to_device_id(
|
|
hass,
|
|
entity_id_or_uuid="unknown_uuid",
|
|
)
|
|
|
|
with pytest.raises(vol.Invalid):
|
|
async_entity_id_to_device(
|
|
hass,
|
|
entity_id_or_uuid="unknown_uuid",
|
|
)
|
|
|
|
|
|
async def test_device_info_to_link(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""The link helpers are deprecated and always return None.
|
|
|
|
A device_info carrying another device's identifiers implicitly added the caller's
|
|
config entry to that device, which a single-config-entry device can't represent - it
|
|
would silently fork a duplicate instead. Entities still attach to another config
|
|
entry's device by setting entity.device_entry.
|
|
"""
|
|
config_entry = MockConfigEntry(domain="my")
|
|
config_entry.add_to_hass(hass)
|
|
|
|
device = device_registry.async_get_or_create(
|
|
identifiers={("test", "my_device")},
|
|
connections={("mac", "30:31:32:33:34:00")},
|
|
config_entry_id=config_entry.entry_id,
|
|
)
|
|
|
|
# Source entity registry
|
|
source_entity = entity_registry.async_get_or_create(
|
|
"sensor",
|
|
"test",
|
|
"source",
|
|
config_entry=config_entry,
|
|
device_id=device.id,
|
|
)
|
|
await hass.async_block_till_done()
|
|
assert entity_registry.async_get("sensor.test_source") is not None
|
|
|
|
# No link device_info is returned, even for an existing entity and device
|
|
with patch("homeassistant.helpers.device.report_usage") as report_usage:
|
|
assert (
|
|
async_device_info_to_link_from_entity(
|
|
hass, entity_id_or_uuid=source_entity.entity_id
|
|
)
|
|
is None
|
|
)
|
|
assert (
|
|
async_device_info_to_link_from_device_id(hass, device_id=device.id) is None
|
|
)
|
|
assert report_usage.call_count == 2
|
|
|
|
# With a non-existent entity id
|
|
assert (
|
|
async_device_info_to_link_from_entity(hass, entity_id_or_uuid="sensor.invalid")
|
|
is None
|
|
)
|
|
|
|
# With a non-existent device id
|
|
assert async_device_info_to_link_from_device_id(hass, device_id="abcdefghi") is None
|
|
|
|
# With a None device id
|
|
assert async_device_info_to_link_from_device_id(hass, device_id=None) is None
|
|
|
|
|
|
async def test_remove_stale_devices_links_deprecated_noop(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
) -> None:
|
|
"""The stale-device-link helpers are deprecated and do nothing.
|
|
|
|
A device belongs to a single config entry, so a helper no longer adds its config
|
|
entry to another device and there is no stale config entry link to remove. The
|
|
helpers leave the devices and entities untouched and only report the deprecated
|
|
usage; helpers set entity.device_entry and clean up devices with
|
|
async_remove_helper_devices instead.
|
|
"""
|
|
helper_config_entry = MockConfigEntry(domain="helper_integration")
|
|
helper_config_entry.add_to_hass(hass)
|
|
host_config_entry = MockConfigEntry(domain="host_integration")
|
|
host_config_entry.add_to_hass(hass)
|
|
|
|
# A device owned by another config entry, plus one owned by the helper config entry
|
|
current_device = device_registry.async_get_or_create(
|
|
identifiers={("test", "current_device")},
|
|
config_entry_id=host_config_entry.entry_id,
|
|
)
|
|
stale_device = device_registry.async_get_or_create(
|
|
identifiers={("test", "stale_device")},
|
|
config_entry_id=helper_config_entry.entry_id,
|
|
)
|
|
source_entity = entity_registry.async_get_or_create(
|
|
"sensor",
|
|
"host_integration",
|
|
"source",
|
|
config_entry=host_config_entry,
|
|
device_id=current_device.id,
|
|
)
|
|
# Helper entity left on a device owned by the helper config entry
|
|
helper_entity = entity_registry.async_get_or_create(
|
|
"sensor",
|
|
"helper_integration",
|
|
"helper",
|
|
config_entry=helper_config_entry,
|
|
device_id=stale_device.id,
|
|
)
|
|
|
|
with patch("homeassistant.helpers.device.report_usage") as report_usage:
|
|
async_remove_stale_devices_links_keep_current_device(
|
|
hass,
|
|
entry_id=helper_config_entry.entry_id,
|
|
current_device_id=current_device.id,
|
|
)
|
|
async_remove_stale_devices_links_keep_entity_device(
|
|
hass,
|
|
entry_id=helper_config_entry.entry_id,
|
|
source_entity_id_or_uuid=source_entity.entity_id,
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
# Both helpers reported the deprecated usage and changed nothing
|
|
assert report_usage.call_count == 2
|
|
assert device_registry.async_get(current_device.id) is not None
|
|
assert device_registry.async_get(stale_device.id) is not None
|
|
helper_entity_entry = entity_registry.async_get(helper_entity.entity_id)
|
|
assert helper_entity_entry.device_id == stale_device.id
|