mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
Fix subentry ID is not updated when renaming the entity ID (#157498)
This commit is contained in:
@@ -1553,7 +1553,9 @@ class Entity(
|
||||
# Clear the remove future to handle entity added again after entity id change
|
||||
self.__remove_future = None
|
||||
self._platform_state = EntityPlatformState.NOT_ADDED
|
||||
await self.platform.async_add_entities([self])
|
||||
await self.platform.async_add_entities(
|
||||
[self], config_subentry_id=registry_entry.config_subentry_id
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_unsubscribe_device_updates(self) -> None:
|
||||
|
||||
@@ -1,4 +1,192 @@
|
||||
# serializer version: 1
|
||||
# name: test_change_entity_id_config_entry[None]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'test_domain',
|
||||
'entity_category': None,
|
||||
'entity_id': 'test_domain.test_5678',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'test',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '5678',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[None].1
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'test_domain.test_5678',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[None].2
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'test_domain',
|
||||
'entity_category': None,
|
||||
'entity_id': 'test_domain.test2',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'test',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '5678',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[None].3
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'test_domain.test2',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[mock-subentry-id-1]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'test_domain',
|
||||
'entity_category': None,
|
||||
'entity_id': 'test_domain.test_5678',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'test',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '5678',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[mock-subentry-id-1].1
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'test_domain.test_5678',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[mock-subentry-id-1].2
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'test_domain',
|
||||
'entity_category': None,
|
||||
'entity_id': 'test_domain.test2',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'test',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '5678',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_change_entity_id_config_entry[mock-subentry-id-1].3
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'test_domain.test2',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_entity_description_as_dataclass
|
||||
dict({
|
||||
'device_class': 'test',
|
||||
|
||||
@@ -16,7 +16,7 @@ from pytest_unordered import unordered
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigSubentryData
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
ATTR_DEVICE_CLASS,
|
||||
@@ -1911,6 +1911,70 @@ async def test_change_entity_id(
|
||||
assert ent._platform_state == entity.EntityPlatformState.ADDED
|
||||
|
||||
|
||||
@pytest.mark.parametrize("config_subentry_id", [None, "mock-subentry-id-1"])
|
||||
async def test_change_entity_id_config_entry(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
config_subentry_id: str | None,
|
||||
) -> None:
|
||||
"""Test changing entity id does not effect the config entry."""
|
||||
|
||||
class MockEntity(entity.Entity):
|
||||
_attr_unique_id = "5678"
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Mock setup entry method."""
|
||||
async_add_entities([MockEntity()], config_subentry_id=config_subentry_id)
|
||||
|
||||
platform = MockPlatform(async_setup_entry=async_setup_entry)
|
||||
config_entry = MockConfigEntry(
|
||||
entry_id="super-mock-id",
|
||||
subentries_data=[
|
||||
ConfigSubentryData(
|
||||
data={},
|
||||
subentry_id="mock-subentry-id-1",
|
||||
subentry_type="test",
|
||||
title="Mock title",
|
||||
unique_id="test",
|
||||
),
|
||||
],
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
entity_platform = MockEntityPlatform(
|
||||
hass, platform_name=config_entry.domain, platform=platform
|
||||
)
|
||||
|
||||
assert await entity_platform.async_setup_entry(config_entry)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
ent = entity_registry.async_get(next(iter(hass.states.async_entity_ids())))
|
||||
assert ent == snapshot
|
||||
# The snapshot check asserts on any (sub)entry ID
|
||||
assert ent.config_entry_id == config_entry.entry_id
|
||||
assert ent.config_subentry_id == config_subentry_id
|
||||
|
||||
state = hass.states.async_all()[0]
|
||||
assert state == snapshot
|
||||
|
||||
entity_registry.async_update_entity(
|
||||
ent.entity_id, new_entity_id="test_domain.test2"
|
||||
)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
new_ent = entity_registry.async_get("test_domain.test2")
|
||||
assert new_ent == snapshot
|
||||
# The snapshot check asserts on any (sub)entry ID
|
||||
assert new_ent.config_entry_id == config_entry.entry_id
|
||||
assert new_ent.config_subentry_id == config_subentry_id
|
||||
|
||||
new_state = hass.states.get("test_domain.test2")
|
||||
assert new_state == snapshot
|
||||
|
||||
|
||||
def test_entity_description_as_dataclass(snapshot: SnapshotAssertion) -> None:
|
||||
"""Test EntityDescription behaves like a dataclass."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user