Delete optional schema keys, when they are not present (#101755)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
c76ce76824
commit
b932c67eb7
2 changed files with 105 additions and 2 deletions
|
@ -171,13 +171,37 @@ class SchemaCommonFlowHandler:
|
|||
|
||||
if user_input is not None:
|
||||
# User input was validated successfully, update options
|
||||
self._options.update(user_input)
|
||||
self._update_and_remove_omitted_optional_keys(
|
||||
self._options, user_input, data_schema
|
||||
)
|
||||
|
||||
if user_input is not None or form_step.schema is None:
|
||||
return await self._show_next_step_or_create_entry(form_step)
|
||||
|
||||
return await self._show_next_step(step_id)
|
||||
|
||||
def _update_and_remove_omitted_optional_keys(
|
||||
self,
|
||||
values: dict[str, Any],
|
||||
user_input: dict[str, Any],
|
||||
data_schema: vol.Schema | None,
|
||||
) -> None:
|
||||
values.update(user_input)
|
||||
if data_schema and data_schema.schema:
|
||||
for key in data_schema.schema:
|
||||
if (
|
||||
isinstance(key, vol.Optional)
|
||||
and key not in user_input
|
||||
and not (
|
||||
# don't remove advanced keys, if they are hidden
|
||||
key.description
|
||||
and key.description.get("advanced")
|
||||
and not self._handler.show_advanced_options
|
||||
)
|
||||
):
|
||||
# Key not present, delete keys old value (if present) too
|
||||
values.pop(key, None)
|
||||
|
||||
async def _show_next_step_or_create_entry(
|
||||
self, form_step: SchemaFlowFormStep
|
||||
) -> FlowResult:
|
||||
|
@ -221,7 +245,9 @@ class SchemaCommonFlowHandler:
|
|||
if user_input:
|
||||
# We don't want to mutate the existing options
|
||||
suggested_values = copy.deepcopy(suggested_values)
|
||||
suggested_values.update(user_input)
|
||||
self._update_and_remove_omitted_optional_keys(
|
||||
suggested_values, user_input, await self._get_schema(form_step)
|
||||
)
|
||||
|
||||
if data_schema.schema:
|
||||
# Make a copy of the schema with suggested values set to saved options
|
||||
|
|
|
@ -671,3 +671,80 @@ async def test_options_flow_state(hass: HomeAssistant) -> None:
|
|||
"idx_from_flow_state": "blublu",
|
||||
"option1": "blabla",
|
||||
}
|
||||
|
||||
|
||||
async def test_options_flow_omit_optional_keys(
|
||||
hass: HomeAssistant, manager: data_entry_flow.FlowManager
|
||||
) -> None:
|
||||
"""Test handling of advanced options in options flow."""
|
||||
manager.hass = hass
|
||||
|
||||
OPTIONS_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional("optional_no_default"): str,
|
||||
vol.Optional("optional_default", default="a very reasonable default"): str,
|
||||
vol.Optional("advanced_no_default", description={"advanced": True}): str,
|
||||
vol.Optional(
|
||||
"advanced_default",
|
||||
default="a very reasonable default",
|
||||
description={"advanced": True},
|
||||
): str,
|
||||
}
|
||||
)
|
||||
|
||||
OPTIONS_FLOW: dict[str, SchemaFlowFormStep | SchemaFlowMenuStep] = {
|
||||
"init": SchemaFlowFormStep(OPTIONS_SCHEMA)
|
||||
}
|
||||
|
||||
class TestFlow(MockSchemaConfigFlowHandler, domain="test"):
|
||||
config_flow = {}
|
||||
options_flow = OPTIONS_FLOW
|
||||
|
||||
mock_integration(hass, MockModule("test"))
|
||||
mock_entity_platform(hass, "config_flow.test", None)
|
||||
config_entry = MockConfigEntry(
|
||||
data={},
|
||||
domain="test",
|
||||
options={
|
||||
"optional_no_default": "abc123",
|
||||
"optional_default": "not default",
|
||||
"advanced_no_default": "abc123",
|
||||
"advanced_default": "not default",
|
||||
},
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
# Start flow in basic mode
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert list(result["data_schema"].schema.keys()) == [
|
||||
"optional_no_default",
|
||||
"optional_default",
|
||||
]
|
||||
|
||||
result = await hass.config_entries.options.async_configure(result["flow_id"], {})
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
"advanced_default": "not default",
|
||||
"advanced_no_default": "abc123",
|
||||
"optional_default": "a very reasonable default",
|
||||
}
|
||||
|
||||
# Start flow in advanced mode
|
||||
result = await hass.config_entries.options.async_init(
|
||||
config_entry.entry_id, context={"show_advanced_options": True}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.FlowResultType.FORM
|
||||
assert list(result["data_schema"].schema.keys()) == [
|
||||
"optional_no_default",
|
||||
"optional_default",
|
||||
"advanced_no_default",
|
||||
"advanced_default",
|
||||
]
|
||||
|
||||
result = await hass.config_entries.options.async_configure(result["flow_id"], {})
|
||||
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
"advanced_default": "a very reasonable default",
|
||||
"optional_default": "a very reasonable default",
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue