Add helper to set name of helper config entries (#67950)

This commit is contained in:
Erik Montnemery 2022-03-10 16:18:26 +01:00 committed by GitHub
parent 4e7d4db7ae
commit ee38dbd698
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 75 additions and 107 deletions

View file

@ -6,12 +6,7 @@ from typing import Any
import voluptuous as vol
from homeassistant.core import split_entity_id
from homeassistant.helpers import (
entity_registry as er,
helper_config_entry_flow,
selector,
)
from homeassistant.helpers import helper_config_entry_flow, selector
from . import DOMAIN
@ -40,12 +35,6 @@ class SwitchAsXConfigFlowHandler(
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
"""Return config entry title."""
registry = er.async_get(self.hass)
object_id = split_entity_id(options["entity_id"])[1]
entry = registry.async_get(options["entity_id"])
if entry:
return entry.name or entry.original_name or object_id
state = self.hass.states.get(options["entity_id"])
if state:
return state.name or object_id
return object_id
return helper_config_entry_flow.wrapped_entity_config_entry_title(
self.hass, options["entity_id"]
)

View file

@ -10,9 +10,11 @@ from typing import Any
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback, split_entity_id
from homeassistant.data_entry_flow import FlowResult, UnknownHandler
from . import entity_registry as er
@dataclass
class HelperFlowStep:
@ -181,3 +183,25 @@ class HelperOptionsFlowHandler(config_entries.OptionsFlow):
) -> FlowResult:
"""Finish config flow and create a config entry."""
return super().async_create_entry(title="", **kwargs)
@callback
def wrapped_entity_config_entry_title(
hass: HomeAssistant, entity_id_or_uuid: str
) -> str:
"""Generate title for a config entry wrapping a single entity.
If the entity is registered, use the registry entry's name.
If the entity is in the state machine, use the name from the state.
Otherwise, fall back to the object ID.
"""
registry = er.async_get(hass)
entity_id = er.async_validate_entity_id(registry, entity_id_or_uuid)
object_id = split_entity_id(entity_id)[1]
entry = registry.async_get(entity_id)
if entry:
return entry.name or entry.original_name or object_id
state = hass.states.get(entity_id)
if state:
return state.name or object_id
return object_id

View file

@ -48,72 +48,17 @@ async def test_config_flow(hass: HomeAssistant, target_domain) -> None:
"target_domain": target_domain,
}
assert hass.states.get(f"{target_domain}.ceiling")
# Check the wrapped switch has a state and is added to the registry
state = hass.states.get(f"{target_domain}.ceiling")
assert state.state == "unavailable"
# Name copied from config entry title
assert state.name == "ceiling"
@pytest.mark.parametrize("target_domain", ("light",))
async def test_name(hass: HomeAssistant, target_domain) -> None:
"""Test the config flow name is copied from registry entry, with fallback to state."""
# Check the light is added to the entity registry
registry = er.async_get(hass)
# No entry or state, use Object ID
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"entity_id": "switch.ceiling", "target_domain": target_domain},
)
assert result["title"] == "ceiling"
# State set, use name from state
hass.states.async_set("switch.ceiling", "on", {"friendly_name": "State Name"})
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"entity_id": "switch.ceiling", "target_domain": target_domain},
)
assert result["title"] == "State Name"
# Entity registered, use original name from registry entry
hass.states.async_remove("switch.ceiling")
entry = registry.async_get_or_create(
"switch",
"test",
"unique",
suggested_object_id="ceiling",
original_name="Original Name",
)
assert entry.entity_id == "switch.ceiling"
hass.states.async_set("switch.ceiling", "on", {"friendly_name": "State Name"})
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"entity_id": "switch.ceiling", "target_domain": target_domain},
)
assert result["title"] == "Original Name"
# Entity has customized name
registry.async_update_entity("switch.ceiling", name="Custom Name")
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"entity_id": "switch.ceiling", "target_domain": target_domain},
)
assert result["title"] == "Custom Name"
entity_entry = registry.async_get(f"{target_domain}.ceiling")
assert entity_entry.unique_id == config_entry.entry_id
@pytest.mark.parametrize("target_domain", ("light",))

View file

@ -106,34 +106,6 @@ async def test_switch_service_calls(hass):
assert hass.states.get("light.decorative_lights").state == "on"
@pytest.mark.parametrize("target_domain", ("light",))
async def test_config_entry(hass: HomeAssistant, target_domain):
"""Test light switch setup from config entry."""
config_entry = MockConfigEntry(
data={},
domain=DOMAIN,
options={"entity_id": "switch.abc", "target_domain": target_domain},
title="ABC",
)
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert DOMAIN in hass.config.components
state = hass.states.get(f"{target_domain}.abc")
assert state.state == "unavailable"
# Name copied from config entry title
assert state.name == "ABC"
# Check the light is added to the entity registry
registry = er.async_get(hass)
entity_entry = registry.async_get(f"{target_domain}.abc")
assert entity_entry.unique_id == config_entry.entry_id
@pytest.mark.parametrize("target_domain", ("light",))
async def test_config_entry_uuid(hass: HomeAssistant, target_domain):
"""Test light switch setup from config entry with entity registry id."""

View file

@ -0,0 +1,38 @@
"""Test helper_config_entry_flow."""
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.helper_config_entry_flow import (
wrapped_entity_config_entry_title,
)
async def test_name(hass: HomeAssistant) -> None:
"""Test the config flow name is copied from registry entry, with fallback to state."""
registry = er.async_get(hass)
entity_id = "switch.ceiling"
# No entry or state, use Object ID
assert wrapped_entity_config_entry_title(hass, entity_id) == "ceiling"
# State set, use name from state
hass.states.async_set(entity_id, "on", {"friendly_name": "State Name"})
assert wrapped_entity_config_entry_title(hass, entity_id) == "State Name"
# Entity registered, use original name from registry entry
hass.states.async_remove(entity_id)
entry = registry.async_get_or_create(
"switch",
"test",
"unique",
suggested_object_id="ceiling",
original_name="Original Name",
)
hass.states.async_set(entity_id, "on", {"friendly_name": "State Name"})
assert entry.entity_id == entity_id
assert wrapped_entity_config_entry_title(hass, entity_id) == "Original Name"
assert wrapped_entity_config_entry_title(hass, entry.id) == "Original Name"
# Entity has customized name
registry.async_update_entity("switch.ceiling", name="Custom Name")
assert wrapped_entity_config_entry_title(hass, entity_id) == "Custom Name"
assert wrapped_entity_config_entry_title(hass, entry.id) == "Custom Name"