Skip to content

Commit

Permalink
Strip out deleted entities when configuring homekit (#59844)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Nov 18, 2021
1 parent 8fb8427 commit 0fb21af
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 11 deletions.
29 changes: 19 additions & 10 deletions homeassistant/components/homekit/config_flow.py
Expand Up @@ -330,13 +330,19 @@ async def async_step_advanced(self, user_input=None):
return self.async_create_entry(title="", data=self.hk_options)

all_supported_devices = await _async_get_supported_devices(self.hass)
# Strip out devices that no longer exist to prevent error in the UI
devices = [
device_id
for device_id in self.hk_options.get(CONF_DEVICES, [])
if device_id in all_supported_devices
]
return self.async_show_form(
step_id="advanced",
data_schema=vol.Schema(
{
vol.Optional(
CONF_DEVICES, default=self.hk_options.get(CONF_DEVICES, [])
): cv.multi_select(all_supported_devices)
vol.Optional(CONF_DEVICES, default=devices): cv.multi_select(
all_supported_devices
)
}
),
)
Expand Down Expand Up @@ -445,13 +451,16 @@ async def async_step_include_exclude(self, user_input=None):
)

data_schema = {}
entities = entity_filter.get(CONF_INCLUDE_ENTITIES, [])
if self.hk_options[CONF_HOMEKIT_MODE] == HOMEKIT_MODE_ACCESSORY:
entity_schema = vol.In
else:
if entities:
include_exclude_mode = MODE_INCLUDE
else:
entity_schema = vol.In
# Strip out entities that no longer exist to prevent error in the UI
entities = [
entity_id
for entity_id in entity_filter.get(CONF_INCLUDE_ENTITIES, [])
if entity_id in all_supported_entities
]
if self.hk_options[CONF_HOMEKIT_MODE] != HOMEKIT_MODE_ACCESSORY:
include_exclude_mode = MODE_INCLUDE
if not entities:
include_exclude_mode = MODE_EXCLUDE
entities = entity_filter.get(CONF_EXCLUDE_ENTITIES, [])
data_schema[
Expand Down
73 changes: 72 additions & 1 deletion tests/components/homekit/test_config_flow.py
Expand Up @@ -365,7 +365,24 @@ async def test_options_flow_devices(
mock_hap, hass, demo_cleanup, device_reg, entity_reg, mock_get_source_ip
):
"""Test devices can be bridged."""
config_entry = _mock_config_entry_with_options_populated()
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
options={
"devices": ["notexist"],
"filter": {
"include_domains": [
"fan",
"humidifier",
"vacuum",
"media_player",
"climate",
"alarm_control_panel",
],
"exclude_entities": ["climate.front_gate"],
},
},
)
config_entry.add_to_hass(hass)

demo_config_entry = MockConfigEntry(domain="domain")
Expand Down Expand Up @@ -491,6 +508,60 @@ async def test_options_flow_devices_preserved_when_advanced_off(
}


async def test_options_flow_with_non_existant_entity(hass, mock_get_source_ip):
"""Test config flow options in include mode."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
options={
"filter": {
"include_entities": ["climate.not_exist", "climate.front_gate"],
},
},
)
config_entry.add_to_hass(hass)
hass.states.async_set("climate.front_gate", "off")
hass.states.async_set("climate.new", "off")

await hass.async_block_till_done()

result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": False}
)

assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "init"

result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={"domains": ["fan", "vacuum", "climate"]},
)

assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "include_exclude"

entities = result["data_schema"]({})["entities"]
assert "climate.not_exist" not in entities

result2 = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
"entities": ["climate.new", "climate.front_gate"],
"include_exclude_mode": "include",
},
)
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
"mode": "bridge",
"filter": {
"exclude_domains": [],
"exclude_entities": [],
"include_domains": ["fan", "vacuum"],
"include_entities": ["climate.new", "climate.front_gate"],
},
}


async def test_options_flow_include_mode_basic(hass, mock_get_source_ip):
"""Test config flow options in include mode."""

Expand Down

0 comments on commit 0fb21af

Please sign in to comment.