Fix homekit options being mutated during config_flow/migration (#64003)
This commit is contained in:
parent
f034ea5b4b
commit
1019156899
3 changed files with 18 additions and 6 deletions
|
@ -2,6 +2,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
import ipaddress
|
||||
import logging
|
||||
import os
|
||||
|
@ -348,8 +349,8 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
|||
|
||||
@callback
|
||||
def _async_import_options_from_data_if_missing(hass: HomeAssistant, entry: ConfigEntry):
|
||||
options = dict(entry.options)
|
||||
data = dict(entry.data)
|
||||
options = deepcopy(dict(entry.options))
|
||||
data = deepcopy(dict(entry.data))
|
||||
modified = False
|
||||
for importable_option in CONFIG_OPTIONS:
|
||||
if importable_option not in entry.options and importable_option in entry.data:
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from copy import deepcopy
|
||||
import random
|
||||
import re
|
||||
import string
|
||||
from typing import Final
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -117,7 +119,7 @@ DEFAULT_DOMAINS = [
|
|||
"water_heater",
|
||||
]
|
||||
|
||||
_EMPTY_ENTITY_FILTER = {
|
||||
_EMPTY_ENTITY_FILTER: Final = {
|
||||
CONF_INCLUDE_DOMAINS: [],
|
||||
CONF_EXCLUDE_DOMAINS: [],
|
||||
CONF_INCLUDE_ENTITIES: [],
|
||||
|
@ -152,7 +154,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
async def async_step_user(self, user_input=None):
|
||||
"""Choose specific domains in bridge mode."""
|
||||
if user_input is not None:
|
||||
entity_filter = _EMPTY_ENTITY_FILTER.copy()
|
||||
entity_filter = deepcopy(_EMPTY_ENTITY_FILTER)
|
||||
entity_filter[CONF_INCLUDE_DOMAINS] = user_input[CONF_INCLUDE_DOMAINS]
|
||||
self.hk_data[CONF_FILTER] = entity_filter
|
||||
return await self.async_step_pairing()
|
||||
|
@ -493,7 +495,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||
self.hk_options.update(user_input)
|
||||
return await self.async_step_include_exclude()
|
||||
|
||||
self.hk_options = dict(self.config_entry.options)
|
||||
self.hk_options = deepcopy(dict(self.config_entry.options))
|
||||
entity_filter = self.hk_options.get(CONF_FILTER, {})
|
||||
homekit_mode = self.hk_options.get(CONF_HOMEKIT_MODE, DEFAULT_HOMEKIT_MODE)
|
||||
domains = entity_filter.get(CONF_INCLUDE_DOMAINS, [])
|
||||
|
|
|
@ -2,9 +2,14 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components.homekit.const import DOMAIN, SHORT_BRIDGE_NAME
|
||||
from homeassistant.components.homekit.const import (
|
||||
CONF_FILTER,
|
||||
DOMAIN,
|
||||
SHORT_BRIDGE_NAME,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_IGNORE, SOURCE_IMPORT
|
||||
from homeassistant.const import CONF_NAME, CONF_PORT
|
||||
from homeassistant.helpers.entityfilter import CONF_INCLUDE_DOMAINS
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .util import PATH_HOMEKIT, async_init_entry
|
||||
|
@ -347,6 +352,10 @@ async def test_options_flow_exclude_mode_basic(hass, mock_get_source_ip):
|
|||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "include_exclude"
|
||||
|
||||
# Inject garbage to ensure the options data
|
||||
# is being deep copied and we cannot mutate it in flight
|
||||
config_entry.options[CONF_FILTER][CONF_INCLUDE_DOMAINS].append("garbage")
|
||||
|
||||
result2 = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"entities": ["climate.old"], "include_exclude_mode": "exclude"},
|
||||
|
|
Loading…
Add table
Reference in a new issue