diff --git a/homeassistant/components/incomfort/config_flow.py b/homeassistant/components/incomfort/config_flow.py index bfc43faacf2..3db8e40f9f4 100644 --- a/homeassistant/components/incomfort/config_flow.py +++ b/homeassistant/components/incomfort/config_flow.py @@ -10,6 +10,7 @@ from incomfortclient import IncomfortError, InvalidHeaterList import voluptuous as vol from homeassistant.config_entries import ( + SOURCE_RECONFIGURE, ConfigEntry, ConfigFlow, ConfigFlowResult, @@ -106,15 +107,31 @@ class InComfortConfigFlow(ConfigFlow, domain=DOMAIN): ) -> ConfigFlowResult: """Handle the initial step.""" errors: dict[str, str] | None = None + data_schema: vol.Schema = CONFIG_SCHEMA + if is_reconfigure := (self.source == SOURCE_RECONFIGURE): + reconfigure_entry = self._get_reconfigure_entry() + data_schema = self.add_suggested_values_to_schema( + data_schema, reconfigure_entry.data + ) if user_input is not None: - self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]}) if ( - errors := await async_try_connect_gateway(self.hass, user_input) + errors := await async_try_connect_gateway( + self.hass, + (reconfigure_entry.data | user_input) + if is_reconfigure + else user_input, + ) ) is None: + if is_reconfigure: + return self.async_update_reload_and_abort( + reconfigure_entry, data_updates=user_input + ) + self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]}) return self.async_create_entry(title=TITLE, data=user_input) + data_schema = self.add_suggested_values_to_schema(data_schema, user_input) return self.async_show_form( - step_id="user", data_schema=CONFIG_SCHEMA, errors=errors + step_id="user", data_schema=data_schema, errors=errors ) async def async_step_reauth( @@ -145,6 +162,12 @@ class InComfortConfigFlow(ConfigFlow, domain=DOMAIN): step_id="reauth_confirm", data_schema=REAUTH_SCHEMA, errors=errors ) + async def async_step_reconfigure( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Handle reconfiguration flow.""" + return await self.async_step_user() + class InComfortOptionsFlowHandler(OptionsFlow): """Handle InComfort Lan2RF gateway options.""" diff --git a/homeassistant/components/incomfort/strings.json b/homeassistant/components/incomfort/strings.json index 9fd31ae1c6f..2f2f526421a 100644 --- a/homeassistant/components/incomfort/strings.json +++ b/homeassistant/components/incomfort/strings.json @@ -31,6 +31,7 @@ "not_found": "No Lan2RF gateway found.", "timeout_error": "Time out when connection to Lan2RF gateway.", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", + "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]", "unknown": "Unknown error when connection to Lan2RF gateway." }, "error": { diff --git a/tests/components/incomfort/test_config_flow.py b/tests/components/incomfort/test_config_flow.py index 0c5ef2f31b1..9ab5a672d61 100644 --- a/tests/components/incomfort/test_config_flow.py +++ b/tests/components/incomfort/test_config_flow.py @@ -39,7 +39,9 @@ async def test_form( assert len(mock_setup_entry.mock_calls) == 1 -async def test_entry_already_configured(hass: HomeAssistant) -> None: +async def test_entry_already_configured( + hass: HomeAssistant, mock_incomfort: MagicMock +) -> None: """Test aborting if the entry is already configured.""" entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG) entry.add_to_hass(hass) @@ -168,6 +170,58 @@ async def test_reauth_flow_failure( assert result["reason"] == "reauth_successful" +async def test_reconfigure_flow_success( + hass: HomeAssistant, + mock_incomfort: MagicMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the re-configure flow succeeds.""" + await hass.config_entries.async_setup(mock_config_entry.entry_id) + + result = await mock_config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=MOCK_CONFIG | {CONF_PASSWORD: "new-password"}, + ) + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + + +async def test_reconfigure_flow_failure( + hass: HomeAssistant, + mock_incomfort: MagicMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test the re-configure flow fails.""" + await hass.config_entries.async_setup(mock_config_entry.entry_id) + + result = await mock_config_entry.start_reconfigure_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + with patch.object( + mock_incomfort(), + "heaters", + side_effect=IncomfortError(ClientResponseError(None, None, status=401)), + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=MOCK_CONFIG | {CONF_PASSWORD: "wrong-password"}, + ) + assert result["type"] is FlowResultType.FORM + assert result["errors"] == {CONF_PASSWORD: "auth_error"} + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input=MOCK_CONFIG | {CONF_PASSWORD: "new-password"}, + ) + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reconfigure_successful" + + @pytest.mark.parametrize( ("user_input", "legacy_setpoint_status"), [