mirror of
https://github.com/home-assistant/core.git
synced 2026-01-14 02:58:14 +00:00
Compare commits
4 Commits
sensor_gro
...
gj-2025100
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fde352b814 | ||
|
|
dace68bd7b | ||
|
|
b72db367cf | ||
|
|
6d76ecf992 |
@@ -3,7 +3,6 @@
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .hub import PulseHub
|
||||
|
||||
@@ -19,8 +18,6 @@ async def async_setup_entry(
|
||||
) -> bool:
|
||||
"""Set up Rollease Acmeda Automate hub from a config entry."""
|
||||
|
||||
await _migrate_unique_ids(hass, config_entry)
|
||||
|
||||
hub = PulseHub(hass, config_entry)
|
||||
|
||||
if not await hub.async_setup():
|
||||
@@ -32,19 +29,6 @@ async def async_setup_entry(
|
||||
return True
|
||||
|
||||
|
||||
async def _migrate_unique_ids(hass: HomeAssistant, entry: AcmedaConfigEntry) -> None:
|
||||
"""Migrate pre-config flow unique ids."""
|
||||
entity_registry = er.async_get(hass)
|
||||
registry_entries = er.async_entries_for_config_entry(
|
||||
entity_registry, entry.entry_id
|
||||
)
|
||||
for reg_entry in registry_entries:
|
||||
if isinstance(reg_entry.unique_id, int): # type: ignore[unreachable]
|
||||
entity_registry.async_update_entity( # type: ignore[unreachable]
|
||||
reg_entry.entity_id, new_unique_id=str(reg_entry.unique_id)
|
||||
)
|
||||
|
||||
|
||||
async def async_unload_entry(
|
||||
hass: HomeAssistant, config_entry: AcmedaConfigEntry
|
||||
) -> bool:
|
||||
|
||||
@@ -34,7 +34,7 @@ from homeassistant.components.climate import (
|
||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||
@@ -105,7 +105,6 @@ async def async_setup_entry(
|
||||
heat_away_temp = entry.options.get(CONF_HEAT_AWAY_TEMPERATURE)
|
||||
|
||||
data = entry.runtime_data
|
||||
_async_migrate_unique_id(hass, data.devices)
|
||||
async_add_entities(
|
||||
[
|
||||
HoneywellUSThermostat(data, device, cool_away_temp, heat_away_temp)
|
||||
@@ -115,21 +114,6 @@ async def async_setup_entry(
|
||||
remove_stale_devices(hass, entry, data.devices)
|
||||
|
||||
|
||||
def _async_migrate_unique_id(
|
||||
hass: HomeAssistant, devices: dict[str, SomeComfortDevice]
|
||||
) -> None:
|
||||
"""Migrate entities to string."""
|
||||
entity_registry = er.async_get(hass)
|
||||
for device in devices.values():
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
"climate", DOMAIN, device.deviceid
|
||||
)
|
||||
if entity_id is not None:
|
||||
entity_registry.async_update_entity(
|
||||
entity_id, new_unique_id=str(device.deviceid)
|
||||
)
|
||||
|
||||
|
||||
def remove_stale_devices(
|
||||
hass: HomeAssistant,
|
||||
config_entry: HoneywellConfigEntry,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""The Hunter Douglas PowerView integration."""
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from aiopvapi.resources.model import PowerviewData
|
||||
from aiopvapi.rooms import Rooms
|
||||
@@ -11,7 +10,7 @@ from aiopvapi.shades import Shades
|
||||
from homeassistant.const import CONF_API_VERSION, CONF_HOST, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from .const import DOMAIN, HUB_EXCEPTIONS, MANUFACTURER
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
@@ -138,7 +137,6 @@ async def async_migrate_entry(hass: HomeAssistant, entry: PowerviewConfigEntry)
|
||||
if entry.minor_version == 1:
|
||||
if entry.unique_id is None:
|
||||
await _async_add_missing_entry_unique_id(hass, entry)
|
||||
await _migrate_unique_ids(hass, entry)
|
||||
hass.config_entries.async_update_entry(entry, minor_version=2)
|
||||
|
||||
_LOGGER.debug("Migrated to version %s.%s", entry.version, entry.minor_version)
|
||||
@@ -156,29 +154,3 @@ async def _async_add_missing_entry_unique_id(
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, unique_id=api.device_info.serial_number
|
||||
)
|
||||
|
||||
|
||||
async def _migrate_unique_ids(hass: HomeAssistant, entry: PowerviewConfigEntry) -> None:
|
||||
"""Migrate int based unique ids to str."""
|
||||
entity_registry = er.async_get(hass)
|
||||
registry_entries = er.async_entries_for_config_entry(
|
||||
entity_registry, entry.entry_id
|
||||
)
|
||||
if TYPE_CHECKING:
|
||||
assert entry.unique_id
|
||||
for reg_entry in registry_entries:
|
||||
if isinstance(reg_entry.unique_id, int) or (
|
||||
isinstance(reg_entry.unique_id, str)
|
||||
and not reg_entry.unique_id.startswith(entry.unique_id)
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Migrating %s: %s to %s_%s",
|
||||
reg_entry.entity_id,
|
||||
reg_entry.unique_id,
|
||||
entry.unique_id,
|
||||
reg_entry.unique_id,
|
||||
)
|
||||
entity_registry.async_update_entity(
|
||||
reg_entry.entity_id,
|
||||
new_unique_id=f"{entry.unique_id}_{reg_entry.unique_id}",
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ class NexiaEntity(CoordinatorEntity[NexiaDataUpdateCoordinator]):
|
||||
def __init__(self, coordinator: NexiaDataUpdateCoordinator, unique_id: str) -> None:
|
||||
"""Initialize the entity."""
|
||||
super().__init__(coordinator)
|
||||
self._attr_unique_id = unique_id
|
||||
self._attr_unique_id = str(unique_id)
|
||||
|
||||
|
||||
class NexiaThermostatEntity(NexiaEntity):
|
||||
|
||||
@@ -69,7 +69,7 @@ class NukiDeviceEntity[_NukiDeviceT: NukiDevice](NukiEntity[_NukiDeviceT], LockE
|
||||
@property
|
||||
def unique_id(self) -> str | None:
|
||||
"""Return a unique ID."""
|
||||
return self._nuki_device.nuki_id
|
||||
return str(self._nuki_device.nuki_id)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
|
||||
@@ -104,33 +104,6 @@ async def async_migrate_entry(hass: HomeAssistant, entry: RingConfigEntry) -> bo
|
||||
_LOGGER.debug(
|
||||
"Migrating from version %s.%s", entry_version, entry_minor_version
|
||||
)
|
||||
# Migrate non-str unique ids
|
||||
# This step used to run unconditionally from async_setup_entry
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
@callback
|
||||
def _async_str_unique_id_migrator(
|
||||
entity_entry: er.RegistryEntry,
|
||||
) -> dict[str, str] | None:
|
||||
# Old format for camera and light was int
|
||||
unique_id = cast(str | int, entity_entry.unique_id)
|
||||
if isinstance(unique_id, int):
|
||||
new_unique_id = str(unique_id)
|
||||
if existing_entity_id := entity_registry.async_get_entity_id(
|
||||
entity_entry.domain, entity_entry.platform, new_unique_id
|
||||
):
|
||||
_LOGGER.error(
|
||||
"Cannot migrate to unique_id '%s', already exists for '%s', "
|
||||
"You may have to delete unavailable ring entities",
|
||||
new_unique_id,
|
||||
existing_entity_id,
|
||||
)
|
||||
return None
|
||||
_LOGGER.debug("Fixing non string unique id %s", entity_entry.unique_id)
|
||||
return {"new_unique_id": new_unique_id}
|
||||
return None
|
||||
|
||||
await er.async_migrate_entries(hass, entry_id, _async_str_unique_id_migrator)
|
||||
|
||||
# Migrate the hardware id
|
||||
hardware_id = str(uuid.uuid4())
|
||||
|
||||
@@ -733,26 +733,12 @@ def _validate_item(
|
||||
entity_category: EntityCategory | None | UndefinedType = None,
|
||||
hidden_by: RegistryEntryHider | None | UndefinedType = None,
|
||||
old_config_subentry_id: str | None = None,
|
||||
report_non_string_unique_id: bool = True,
|
||||
unique_id: str | Hashable | UndefinedType | Any,
|
||||
) -> None:
|
||||
"""Validate entity registry item."""
|
||||
if unique_id is not UNDEFINED and not isinstance(unique_id, Hashable):
|
||||
if unique_id is not UNDEFINED and not isinstance(unique_id, str):
|
||||
raise TypeError(f"unique_id must be a string, got {unique_id}")
|
||||
if (
|
||||
report_non_string_unique_id
|
||||
and unique_id is not UNDEFINED
|
||||
and not isinstance(unique_id, str)
|
||||
):
|
||||
# In HA Core 2025.10, we should fail if unique_id is not a string
|
||||
report_issue = async_suggest_report_issue(hass, integration_domain=platform)
|
||||
_LOGGER.error(
|
||||
"'%s' from integration %s has a non string unique_id '%s', please %s",
|
||||
domain,
|
||||
platform,
|
||||
unique_id,
|
||||
report_issue,
|
||||
)
|
||||
|
||||
if config_entry_id and config_entry_id is not UNDEFINED:
|
||||
if not hass.config_entries.async_get_entry(config_entry_id):
|
||||
raise ValueError(
|
||||
@@ -1506,7 +1492,6 @@ class EntityRegistry(BaseRegistry):
|
||||
self.hass,
|
||||
domain,
|
||||
entity["platform"],
|
||||
report_non_string_unique_id=False,
|
||||
unique_id=entity["unique_id"],
|
||||
)
|
||||
except (TypeError, ValueError) as err:
|
||||
@@ -1584,7 +1569,6 @@ class EntityRegistry(BaseRegistry):
|
||||
self.hass,
|
||||
domain,
|
||||
entity["platform"],
|
||||
report_non_string_unique_id=False,
|
||||
unique_id=entity["unique_id"],
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
"""Define tests for the Acmeda config flow."""
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.acmeda.const import DOMAIN
|
||||
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_hub_run")
|
||||
async def test_cover_id_migration(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating unique id."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
entity_registry.async_get_or_create(
|
||||
COVER_DOMAIN, DOMAIN, 1234567890123, config_entry=mock_config_entry
|
||||
)
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
entities = er.async_entries_for_config_entry(
|
||||
entity_registry, mock_config_entry.entry_id
|
||||
)
|
||||
assert len(entities) == 1
|
||||
assert entities[0].unique_id == "1234567890123"
|
||||
@@ -1,30 +0,0 @@
|
||||
"""Define tests for the Acmeda config flow."""
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.acmeda.const import DOMAIN
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_hub_run")
|
||||
async def test_sensor_id_migration(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test migrating unique id."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
entity_registry.async_get_or_create(
|
||||
SENSOR_DOMAIN, DOMAIN, 1234567890123, config_entry=mock_config_entry
|
||||
)
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
entities = er.async_entries_for_config_entry(
|
||||
entity_registry, mock_config_entry.entry_id
|
||||
)
|
||||
assert len(entities) == 1
|
||||
assert entities[0].unique_id == "1234567890123"
|
||||
@@ -24,5 +24,5 @@ def config_entry_fixture() -> MockConfigEntry:
|
||||
data=data,
|
||||
options={CONF_TTS_PAUSE_TIME: 0},
|
||||
source=SOURCE_USER,
|
||||
entry_id=1,
|
||||
entry_id="1",
|
||||
)
|
||||
|
||||
@@ -114,7 +114,7 @@ async def test_no_aid_collision(
|
||||
|
||||
for unique_id in range(202):
|
||||
ent = entity_registry.async_get_or_create(
|
||||
"light", "device", unique_id, device_id=device_entry.id
|
||||
"light", "device", str(unique_id), device_id=device_entry.id
|
||||
)
|
||||
hass.states.async_set(ent.entity_id, "on")
|
||||
aid = aid_storage.get_or_allocate_aid_for_entity_id(ent.entity_id)
|
||||
|
||||
@@ -29,7 +29,6 @@ from homeassistant.components.climate import (
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.components.honeywell.climate import (
|
||||
DOMAIN,
|
||||
MODE_PERMANENT_HOLD,
|
||||
MODE_TEMPORARY_HOLD,
|
||||
PRESET_HOLD,
|
||||
@@ -41,7 +40,6 @@ from homeassistant.const import (
|
||||
ATTR_TEMPERATURE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
@@ -1193,26 +1191,6 @@ async def test_async_update_errors(
|
||||
assert state.state == "unavailable"
|
||||
|
||||
|
||||
async def test_unique_id(
|
||||
hass: HomeAssistant,
|
||||
device: MagicMock,
|
||||
config_entry: MagicMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test unique id convert to string."""
|
||||
config_entry.add_to_hass(hass)
|
||||
entity_registry.async_get_or_create(
|
||||
Platform.CLIMATE,
|
||||
DOMAIN,
|
||||
device.deviceid,
|
||||
config_entry=config_entry,
|
||||
suggested_object_id=device.name,
|
||||
)
|
||||
await init_integration(hass, config_entry)
|
||||
entity_entry = entity_registry.async_get(f"climate.{device.name}")
|
||||
assert entity_entry.unique_id == str(device.deviceid)
|
||||
|
||||
|
||||
async def test_preset_mode(
|
||||
hass: HomeAssistant,
|
||||
device: MagicMock,
|
||||
|
||||
@@ -9,7 +9,6 @@ from homeassistant.components.hunterdouglas_powerview.const import DOMAIN
|
||||
from homeassistant.const import CONF_API_VERSION, CONF_HOST, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||
|
||||
@@ -354,54 +353,3 @@ async def test_form_unsupported_device(
|
||||
assert result3["result"].unique_id == MOCK_SERIAL
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_hunterdouglas_hub")
|
||||
@pytest.mark.parametrize("api_version", [1, 2, 3])
|
||||
async def test_migrate_entry(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
api_version: int,
|
||||
) -> None:
|
||||
"""Test migrate to newest version."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={"host": "1.2.3.4"},
|
||||
unique_id=MOCK_SERIAL,
|
||||
version=1,
|
||||
minor_version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
# Add entries with int unique_id
|
||||
entity_registry.async_get_or_create(
|
||||
domain="cover",
|
||||
platform="hunterdouglas_powerview",
|
||||
unique_id=123,
|
||||
config_entry=entry,
|
||||
)
|
||||
# Add entries with a str unique_id not starting with entry.unique_id
|
||||
entity_registry.async_get_or_create(
|
||||
domain="cover",
|
||||
platform="hunterdouglas_powerview",
|
||||
unique_id="old_unique_id",
|
||||
config_entry=entry,
|
||||
)
|
||||
|
||||
assert entry.version == 1
|
||||
assert entry.minor_version == 1
|
||||
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.version == 1
|
||||
assert entry.minor_version == 2
|
||||
|
||||
# Reload the registry entries
|
||||
registry_entries = er.async_entries_for_config_entry(
|
||||
entity_registry, entry.entry_id
|
||||
)
|
||||
|
||||
# Ensure the IDs have been migrated
|
||||
for reg_entry in registry_entries:
|
||||
assert reg_entry.unique_id.startswith(f"{entry.unique_id}_")
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <LockEntityFeature: 1>,
|
||||
'translation_key': 'nuki_lock',
|
||||
'unique_id': 2,
|
||||
'unique_id': '2',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
@@ -79,7 +79,7 @@
|
||||
'suggested_object_id': None,
|
||||
'supported_features': <LockEntityFeature: 1>,
|
||||
'translation_key': 'nuki_lock',
|
||||
'unique_id': 1,
|
||||
'unique_id': '1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
|
||||
@@ -241,7 +241,7 @@ async def test_fix_unique_id_duplicate(
|
||||
(
|
||||
SERIAL_NUMBER,
|
||||
SERIAL_NUMBER,
|
||||
SERIAL_NUMBER,
|
||||
str(SERIAL_NUMBER),
|
||||
str(SERIAL_NUMBER),
|
||||
MAC_ADDRESS_UNIQUE_ID,
|
||||
MAC_ADDRESS_UNIQUE_ID,
|
||||
@@ -257,7 +257,7 @@ async def test_fix_unique_id_duplicate(
|
||||
(
|
||||
SERIAL_NUMBER,
|
||||
SERIAL_NUMBER,
|
||||
SERIAL_NUMBER,
|
||||
str(SERIAL_NUMBER),
|
||||
SERIAL_NUMBER,
|
||||
MAC_ADDRESS_UNIQUE_ID,
|
||||
MAC_ADDRESS_UNIQUE_ID,
|
||||
|
||||
@@ -9,7 +9,6 @@ from ring_doorbell import AuthenticationError, Ring, RingError, RingTimeout
|
||||
from homeassistant.components import ring
|
||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||
from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.ring import DOMAIN
|
||||
from homeassistant.components.ring.const import (
|
||||
CONF_CONFIG_ENTRY_MINOR_VERSION,
|
||||
@@ -282,107 +281,6 @@ async def test_error_on_device_update(
|
||||
assert log_msg not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("domain", "old_unique_id", "new_unique_id"),
|
||||
[
|
||||
pytest.param(LIGHT_DOMAIN, 123456, "123456", id="Light integer"),
|
||||
pytest.param(
|
||||
CAMERA_DOMAIN,
|
||||
654321,
|
||||
"654321-last_recording",
|
||||
id="Camera integer",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_update_unique_id(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
mock_ring_client,
|
||||
domain: str,
|
||||
old_unique_id: int | str,
|
||||
new_unique_id: str,
|
||||
) -> None:
|
||||
"""Test unique_id update of integration."""
|
||||
entry = MockConfigEntry(
|
||||
title="Ring",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_USERNAME: "foo@bar.com",
|
||||
"token": {"access_token": "mock-token"},
|
||||
},
|
||||
unique_id="foo@bar.com",
|
||||
minor_version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
entity = entity_registry.async_get_or_create(
|
||||
domain=domain,
|
||||
platform=DOMAIN,
|
||||
unique_id=old_unique_id,
|
||||
config_entry=entry,
|
||||
)
|
||||
assert entity.unique_id == old_unique_id
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_migrated = entity_registry.async_get(entity.entity_id)
|
||||
assert entity_migrated
|
||||
assert entity_migrated.unique_id == new_unique_id
|
||||
assert (f"Fixing non string unique id {old_unique_id}") in caplog.text
|
||||
assert entry.minor_version == CONF_CONFIG_ENTRY_MINOR_VERSION
|
||||
|
||||
|
||||
async def test_update_unique_id_existing(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
mock_ring_client,
|
||||
) -> None:
|
||||
"""Test unique_id update of integration."""
|
||||
old_unique_id = 123456
|
||||
entry = MockConfigEntry(
|
||||
title="Ring",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_USERNAME: "foo@bar.com",
|
||||
"token": {"access_token": "mock-token"},
|
||||
},
|
||||
unique_id="foo@bar.com",
|
||||
minor_version=1,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
entity = entity_registry.async_get_or_create(
|
||||
domain=CAMERA_DOMAIN,
|
||||
platform=DOMAIN,
|
||||
unique_id=old_unique_id,
|
||||
config_entry=entry,
|
||||
)
|
||||
entity_existing = entity_registry.async_get_or_create(
|
||||
domain=CAMERA_DOMAIN,
|
||||
platform=DOMAIN,
|
||||
unique_id=str(old_unique_id),
|
||||
config_entry=entry,
|
||||
)
|
||||
assert entity.unique_id == old_unique_id
|
||||
assert entity_existing.unique_id == str(old_unique_id)
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
entity_not_migrated = entity_registry.async_get(entity.entity_id)
|
||||
entity_existing = entity_registry.async_get(entity_existing.entity_id)
|
||||
assert entity_not_migrated
|
||||
assert entity_existing
|
||||
assert entity_not_migrated.unique_id == old_unique_id
|
||||
assert (
|
||||
f"Cannot migrate to unique_id '{old_unique_id}', "
|
||||
f"already exists for '{entity_existing.entity_id}', "
|
||||
"You may have to delete unavailable ring entities"
|
||||
) in caplog.text
|
||||
assert entry.minor_version == CONF_CONFIG_ENTRY_MINOR_VERSION
|
||||
|
||||
|
||||
async def test_update_unique_id_camera_update(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
|
||||
@@ -657,24 +657,29 @@ async def test_load_bad_data(
|
||||
await er.async_load(hass)
|
||||
registry = er.async_get(hass)
|
||||
|
||||
assert len(registry.entities) == 1
|
||||
assert set(registry.entities.keys()) == {"test.test1"}
|
||||
assert len(registry.entities) == 0
|
||||
assert set(registry.entities.keys()) == set()
|
||||
|
||||
assert len(registry.deleted_entities) == 1
|
||||
assert set(registry.deleted_entities.keys()) == {("test", "super_platform", 234)}
|
||||
assert len(registry.deleted_entities) == 0
|
||||
assert set(registry.deleted_entities.keys()) == set()
|
||||
|
||||
assert (
|
||||
"'test' from integration super_platform has a non string unique_id '123', "
|
||||
"please create a bug report" not in caplog.text
|
||||
"'test.test1' from integration super_platform could not be loaded:"
|
||||
" 'unique_id must be a string, got 123', please create a bug report"
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
"'test' from integration super_platform has a non string unique_id '234', "
|
||||
"please create a bug report" not in caplog.text
|
||||
"'test.test2' from integration super_platform could not be loaded:"
|
||||
" 'unique_id must be a string, got ['not', 'valid']', please create a bug report"
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
"Entity registry entry 'test.test2' from integration super_platform could not "
|
||||
"be loaded: 'unique_id must be a string, got ['not', 'valid']', please create "
|
||||
"a bug report" in caplog.text
|
||||
"'test.test3' from integration super_platform could not be loaded:"
|
||||
not in caplog.text
|
||||
)
|
||||
assert (
|
||||
"'test.test4' from integration super_platform could not be loaded:"
|
||||
not in caplog.text
|
||||
)
|
||||
|
||||
|
||||
@@ -2902,32 +2907,19 @@ async def test_hidden_by_str_not_allowed(entity_registry: er.EntityRegistry) ->
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id_non_hashable(entity_registry: er.EntityRegistry) -> None:
|
||||
"""Test unique_id which is not hashable."""
|
||||
async def test_unique_id_non_string(entity_registry: er.EntityRegistry) -> None:
|
||||
"""Test unique_id which is not a string."""
|
||||
with pytest.raises(TypeError):
|
||||
entity_registry.async_get_or_create("light", "hue", ["not", "valid"])
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
entity_registry.async_get_or_create("light", "hue", 1234)
|
||||
|
||||
entity_id = entity_registry.async_get_or_create("light", "hue", "1234").entity_id
|
||||
with pytest.raises(TypeError):
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=["not", "valid"])
|
||||
|
||||
|
||||
async def test_unique_id_non_string(
|
||||
entity_registry: er.EntityRegistry, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test unique_id which is not a string."""
|
||||
entity_registry.async_get_or_create("light", "hue", 1234)
|
||||
assert (
|
||||
"'light' from integration hue has a non string unique_id '1234', "
|
||||
"please create a bug report" in caplog.text
|
||||
)
|
||||
|
||||
entity_id = entity_registry.async_get_or_create("light", "hue", "1234").entity_id
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=2345)
|
||||
assert (
|
||||
"'light' from integration hue has a non string unique_id '2345', "
|
||||
"please create a bug report" in caplog.text
|
||||
)
|
||||
with pytest.raises(TypeError):
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=1234)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
Reference in New Issue
Block a user