From 6c615016b854562e83810fdf23b8940f64e74cd3 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 25 Nov 2022 14:30:02 +0100 Subject: [PATCH] Fix None schema in SchemaCommonFlowHandler (#82699) --- .../helpers/schema_config_entry_flow.py | 27 +++++++++------- .../helpers/test_schema_config_entry_flow.py | 31 +++++++++++++++++++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/homeassistant/helpers/schema_config_entry_flow.py b/homeassistant/helpers/schema_config_entry_flow.py index c721b9d4ad6..457f541abfc 100644 --- a/homeassistant/helpers/schema_config_entry_flow.py +++ b/homeassistant/helpers/schema_config_entry_flow.py @@ -139,19 +139,21 @@ class SchemaCommonFlowHandler: # User input was validated successfully, update options self._options.update(user_input) - next_step_id: str = step_id if user_input is not None or form_step.schema is None: - # Get next step - if form_step.next_step is None: - # Flow done, create entry or update config entry options - return self._handler.async_create_entry(data=self._options) + return self._show_next_step_or_create_entry(form_step) - if isinstance(form_step.next_step, str): - next_step_id = form_step.next_step - else: - next_step_id = form_step.next_step(self._options) + return self._show_next_step(step_id) - return self._show_next_step(next_step_id) + def _show_next_step_or_create_entry( + self, form_step: SchemaFlowFormStep + ) -> FlowResult: + if form_step.next_step is None: + # Flow done, create entry or update config entry options + return self._handler.async_create_entry(data=self._options) + + if isinstance(form_step.next_step, str): + return self._show_next_step(form_step.next_step) + return self._show_next_step(form_step.next_step(self._options)) def _show_next_step( self, @@ -173,7 +175,10 @@ class SchemaCommonFlowHandler: form_step = cast(SchemaFlowFormStep, self._flow[next_step_id]) - if (data_schema := self._get_schema(form_step)) and data_schema.schema: + if (data_schema := self._get_schema(form_step)) is None: + return self._show_next_step_or_create_entry(form_step) + + if data_schema.schema: # Make a copy of the schema with suggested values set to saved options schema = {} for key, val in data_schema.schema.items(): diff --git a/tests/helpers/test_schema_config_entry_flow.py b/tests/helpers/test_schema_config_entry_flow.py index 7ea5768fcad..7efc70cb5d5 100644 --- a/tests/helpers/test_schema_config_entry_flow.py +++ b/tests/helpers/test_schema_config_entry_flow.py @@ -70,3 +70,34 @@ async def test_menu_step(hass: HomeAssistant) -> None: result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) assert result["type"] == FlowResultType.CREATE_ENTRY + + +async def test_schema_none(hass: HomeAssistant) -> None: + """Test SchemaFlowFormStep with schema set to None.""" + + CONFIG_FLOW: dict[str, SchemaFlowFormStep | SchemaFlowMenuStep] = { + "user": SchemaFlowFormStep(next_step="option1"), + "option1": SchemaFlowFormStep(vol.Schema({}), next_step="pass"), + "pass": SchemaFlowFormStep(next_step="option3"), + "option3": SchemaFlowFormStep(vol.Schema({})), + } + + class TestConfigFlow(SchemaConfigFlowHandler, domain=TEST_DOMAIN): + """Handle a config or options flow for Derivative.""" + + config_flow = CONFIG_FLOW + + mock_platform(hass, f"{TEST_DOMAIN}.config_flow") + with patch.dict(config_entries.HANDLERS, {TEST_DOMAIN: TestConfigFlow}): + result = await hass.config_entries.flow.async_init( + TEST_DOMAIN, context={"source": "user"} + ) + assert result["type"] == FlowResultType.FORM + assert result["step_id"] == "option1" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + assert result["type"] == FlowResultType.FORM + assert result["step_id"] == "option3" + + result = await hass.config_entries.flow.async_configure(result["flow_id"], {}) + assert result["type"] == FlowResultType.CREATE_ENTRY