mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Enforce RegistryEntryHider in entity registry (#73219)
This commit is contained in:
parent
6bf219550e
commit
4435c641de
@ -369,6 +369,8 @@ class EntityRegistry:
|
||||
|
||||
if disabled_by and not isinstance(disabled_by, RegistryEntryDisabler):
|
||||
raise ValueError("disabled_by must be a RegistryEntryDisabler value")
|
||||
if hidden_by and not isinstance(hidden_by, RegistryEntryHider):
|
||||
raise ValueError("hidden_by must be a RegistryEntryHider value")
|
||||
|
||||
if (
|
||||
disabled_by is None
|
||||
@ -520,6 +522,12 @@ class EntityRegistry:
|
||||
and not isinstance(disabled_by, RegistryEntryDisabler)
|
||||
):
|
||||
raise ValueError("disabled_by must be a RegistryEntryDisabler value")
|
||||
if (
|
||||
hidden_by
|
||||
and hidden_by is not UNDEFINED
|
||||
and not isinstance(hidden_by, RegistryEntryHider)
|
||||
):
|
||||
raise ValueError("hidden_by must be a RegistryEntryHider value")
|
||||
|
||||
from .entity import EntityCategory # pylint: disable=import-outside-toplevel
|
||||
|
||||
@ -729,7 +737,9 @@ class EntityRegistry:
|
||||
if entity["entity_category"]
|
||||
else None,
|
||||
entity_id=entity["entity_id"],
|
||||
hidden_by=entity["hidden_by"],
|
||||
hidden_by=RegistryEntryHider(entity["hidden_by"])
|
||||
if entity["hidden_by"]
|
||||
else None,
|
||||
icon=entity["icon"],
|
||||
id=entity["id"],
|
||||
name=entity["name"],
|
||||
|
@ -348,7 +348,10 @@ async def test_all_options(
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hide_members,hidden_by_initial,hidden_by",
|
||||
((False, "integration", None), (True, None, "integration")),
|
||||
(
|
||||
(False, er.RegistryEntryHider.INTEGRATION, None),
|
||||
(True, None, er.RegistryEntryHider.INTEGRATION),
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"group_type,extra_input",
|
||||
|
@ -1421,12 +1421,12 @@ async def test_setup_and_remove_config_entry(
|
||||
@pytest.mark.parametrize(
|
||||
"hide_members,hidden_by_initial,hidden_by",
|
||||
(
|
||||
(False, "integration", "integration"),
|
||||
(False, er.RegistryEntryHider.INTEGRATION, er.RegistryEntryHider.INTEGRATION),
|
||||
(False, None, None),
|
||||
(False, "user", "user"),
|
||||
(True, "integration", None),
|
||||
(False, er.RegistryEntryHider.USER, er.RegistryEntryHider.USER),
|
||||
(True, er.RegistryEntryHider.INTEGRATION, None),
|
||||
(True, None, None),
|
||||
(True, "user", "user"),
|
||||
(True, er.RegistryEntryHider.USER, er.RegistryEntryHider.USER),
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
@ -1444,7 +1444,7 @@ async def test_unhide_members_on_remove(
|
||||
group_type: str,
|
||||
extra_options: dict[str, Any],
|
||||
hide_members: bool,
|
||||
hidden_by_initial: str,
|
||||
hidden_by_initial: er.RegistryEntryHider,
|
||||
hidden_by: str,
|
||||
) -> None:
|
||||
"""Test removing a config entry."""
|
||||
|
@ -65,8 +65,8 @@ async def test_config_flow(
|
||||
@pytest.mark.parametrize(
|
||||
"hidden_by_before,hidden_by_after",
|
||||
(
|
||||
(er.RegistryEntryHider.USER.value, er.RegistryEntryHider.USER.value),
|
||||
(None, er.RegistryEntryHider.INTEGRATION.value),
|
||||
(er.RegistryEntryHider.USER, er.RegistryEntryHider.USER),
|
||||
(None, er.RegistryEntryHider.INTEGRATION),
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize("target_domain", PLATFORMS_TO_TEST)
|
||||
|
@ -365,8 +365,8 @@ async def test_setup_and_remove_config_entry(
|
||||
@pytest.mark.parametrize(
|
||||
"hidden_by_before,hidden_by_after",
|
||||
(
|
||||
(er.RegistryEntryHider.USER.value, er.RegistryEntryHider.USER.value),
|
||||
(er.RegistryEntryHider.INTEGRATION.value, None),
|
||||
(er.RegistryEntryHider.USER, er.RegistryEntryHider.USER),
|
||||
(er.RegistryEntryHider.INTEGRATION, None),
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize("target_domain", PLATFORMS_TO_TEST)
|
||||
|
@ -79,6 +79,7 @@ def test_get_or_create_updates_data(registry):
|
||||
device_id="mock-dev-id",
|
||||
disabled_by=er.RegistryEntryDisabler.HASS,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
hidden_by=er.RegistryEntryHider.INTEGRATION,
|
||||
original_device_class="mock-device-class",
|
||||
original_icon="initial-original_icon",
|
||||
original_name="initial-original_name",
|
||||
@ -97,6 +98,7 @@ def test_get_or_create_updates_data(registry):
|
||||
device_id="mock-dev-id",
|
||||
disabled_by=er.RegistryEntryDisabler.HASS,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
hidden_by=er.RegistryEntryHider.INTEGRATION,
|
||||
icon=None,
|
||||
id=orig_entry.id,
|
||||
name=None,
|
||||
@ -119,6 +121,7 @@ def test_get_or_create_updates_data(registry):
|
||||
device_id="new-mock-dev-id",
|
||||
disabled_by=er.RegistryEntryDisabler.USER,
|
||||
entity_category=None,
|
||||
hidden_by=er.RegistryEntryHider.USER,
|
||||
original_device_class="new-mock-device-class",
|
||||
original_icon="updated-original_icon",
|
||||
original_name="updated-original_name",
|
||||
@ -137,6 +140,7 @@ def test_get_or_create_updates_data(registry):
|
||||
device_id="new-mock-dev-id",
|
||||
disabled_by=er.RegistryEntryDisabler.HASS, # Should not be updated
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
hidden_by=er.RegistryEntryHider.INTEGRATION, # Should not be updated
|
||||
icon=None,
|
||||
id=orig_entry.id,
|
||||
name=None,
|
||||
@ -191,6 +195,7 @@ async def test_loading_saving_data(hass, registry):
|
||||
device_id="mock-dev-id",
|
||||
disabled_by=er.RegistryEntryDisabler.HASS,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
hidden_by=er.RegistryEntryHider.INTEGRATION,
|
||||
original_device_class="mock-device-class",
|
||||
original_icon="hass:original-icon",
|
||||
original_name="Original Name",
|
||||
@ -231,6 +236,7 @@ async def test_loading_saving_data(hass, registry):
|
||||
assert new_entry2.disabled_by is er.RegistryEntryDisabler.HASS
|
||||
assert new_entry2.entity_category == "config"
|
||||
assert new_entry2.icon == "hass:user-icon"
|
||||
assert new_entry2.hidden_by == er.RegistryEntryHider.INTEGRATION
|
||||
assert new_entry2.name == "User Name"
|
||||
assert new_entry2.options == {"light": {"minimum_brightness": 20}}
|
||||
assert new_entry2.original_device_class == "mock-device-class"
|
||||
@ -261,8 +267,8 @@ def test_is_registered(registry):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("load_registries", [False])
|
||||
async def test_loading_extra_values(hass, hass_storage):
|
||||
"""Test we load extra data from the registry."""
|
||||
async def test_filter_on_load(hass, hass_storage):
|
||||
"""Test we transform some data when loading from storage."""
|
||||
hass_storage[er.STORAGE_KEY] = {
|
||||
"version": er.STORAGE_VERSION_MAJOR,
|
||||
"minor_version": 1,
|
||||
@ -274,6 +280,7 @@ async def test_loading_extra_values(hass, hass_storage):
|
||||
"unique_id": "with-name",
|
||||
"name": "registry override",
|
||||
},
|
||||
# This entity's name should be None
|
||||
{
|
||||
"entity_id": "test.no_name",
|
||||
"platform": "super_platform",
|
||||
@ -283,20 +290,22 @@ async def test_loading_extra_values(hass, hass_storage):
|
||||
"entity_id": "test.disabled_user",
|
||||
"platform": "super_platform",
|
||||
"unique_id": "disabled-user",
|
||||
"disabled_by": er.RegistryEntryDisabler.USER,
|
||||
"disabled_by": "user", # We store the string representation
|
||||
},
|
||||
{
|
||||
"entity_id": "test.disabled_hass",
|
||||
"platform": "super_platform",
|
||||
"unique_id": "disabled-hass",
|
||||
"disabled_by": er.RegistryEntryDisabler.HASS,
|
||||
"disabled_by": "hass", # We store the string representation
|
||||
},
|
||||
# This entry should not be loaded because the entity_id is invalid
|
||||
{
|
||||
"entity_id": "test.invalid__entity",
|
||||
"platform": "super_platform",
|
||||
"unique_id": "invalid-hass",
|
||||
"disabled_by": er.RegistryEntryDisabler.HASS,
|
||||
"disabled_by": "hass", # We store the string representation
|
||||
},
|
||||
# This entry should have the entity_category reset to None
|
||||
{
|
||||
"entity_id": "test.system_entity",
|
||||
"platform": "super_platform",
|
||||
@ -311,6 +320,13 @@ async def test_loading_extra_values(hass, hass_storage):
|
||||
registry = er.async_get(hass)
|
||||
|
||||
assert len(registry.entities) == 5
|
||||
assert set(registry.entities.keys()) == {
|
||||
"test.disabled_hass",
|
||||
"test.disabled_user",
|
||||
"test.named",
|
||||
"test.no_name",
|
||||
"test.system_entity",
|
||||
}
|
||||
|
||||
entry_with_name = registry.async_get_or_create(
|
||||
"test", "super_platform", "with-name"
|
||||
@ -1221,7 +1237,7 @@ def test_entity_registry_items():
|
||||
|
||||
|
||||
async def test_disabled_by_str_not_allowed(hass):
|
||||
"""Test we need to pass entity category type."""
|
||||
"""Test we need to pass disabled by type."""
|
||||
reg = er.async_get(hass)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
@ -1252,6 +1268,20 @@ async def test_entity_category_str_not_allowed(hass):
|
||||
)
|
||||
|
||||
|
||||
async def test_hidden_by_str_not_allowed(hass):
|
||||
"""Test we need to pass hidden by type."""
|
||||
reg = er.async_get(hass)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
reg.async_get_or_create(
|
||||
"light", "hue", "1234", hidden_by=er.RegistryEntryHider.USER.value
|
||||
)
|
||||
|
||||
entity_id = reg.async_get_or_create("light", "hue", "1234").entity_id
|
||||
with pytest.raises(ValueError):
|
||||
reg.async_update_entity(entity_id, hidden_by=er.RegistryEntryHider.USER.value)
|
||||
|
||||
|
||||
def test_migrate_entity_to_new_platform(hass, registry):
|
||||
"""Test migrate_entity_to_new_platform."""
|
||||
orig_config_entry = MockConfigEntry(domain="light")
|
||||
|
Loading…
x
Reference in New Issue
Block a user