Fix user input malformed with deleted entities in HomeKit exclude flow (#60061)

This commit is contained in:
J. Nick Koston 2021-11-23 11:46:54 -06:00 committed by GitHub
parent 400aaeaa91
commit 6524cd4eb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 11 deletions

View File

@ -453,12 +453,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
data_schema = {}
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
]
entities = entity_filter.get(CONF_INCLUDE_ENTITIES, [])
if self.hk_options[CONF_HOMEKIT_MODE] != HOMEKIT_MODE_ACCESSORY:
include_exclude_mode = MODE_INCLUDE
if not entities:
@ -469,9 +464,13 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
] = vol.In(INCLUDE_EXCLUDE_MODES)
entity_schema = cv.multi_select
data_schema[vol.Optional(CONF_ENTITIES, default=entities)] = entity_schema(
all_supported_entities
)
# Strip out entities that no longer exist to prevent error in the UI
valid_entities = [
entity_id for entity_id in entities if entity_id in all_supported_entities
]
data_schema[
vol.Optional(CONF_ENTITIES, default=valid_entities)
] = entity_schema(all_supported_entities)
return self.async_show_form(
step_id="include_exclude", data_schema=vol.Schema(data_schema)

View File

@ -514,8 +514,10 @@ 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."""
async def test_options_flow_include_mode_with_non_existant_entity(
hass, mock_get_source_ip
):
"""Test config flow options in include mode with a non-existent entity."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
@ -568,6 +570,63 @@ async def test_options_flow_with_non_existant_entity(hass, mock_get_source_ip):
}
async def test_options_flow_exclude_mode_with_non_existant_entity(
hass, mock_get_source_ip
):
"""Test config flow options in exclude mode with a non-existent entity."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_NAME: "mock_name", CONF_PORT: 12345},
options={
"filter": {
"include_domains": ["climate"],
"exclude_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": ["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": "exclude",
},
)
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
"mode": "bridge",
"filter": {
"exclude_domains": [],
"exclude_entities": ["climate.new", "climate.front_gate"],
"include_domains": ["climate"],
"include_entities": [],
},
}
async def test_options_flow_include_mode_basic(hass, mock_get_source_ip):
"""Test config flow options in include mode."""