From 5b503f21d79b04c46a2638f8be08b3d36c2ed7ca Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Fri, 25 Apr 2025 09:37:58 +0200 Subject: [PATCH] Abort Shelly flows if the device is not fully provisioned (#143652) * Abort flows if the device is not fully provisioned * Update tests --- .../components/shelly/config_flow.py | 32 +++++++++---------- homeassistant/components/shelly/strings.json | 16 +++++----- tests/components/shelly/test_config_flow.py | 19 ++++------- 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 6e41df282ef..f0985171752 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -198,7 +198,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): CONF_GEN: device_info[CONF_GEN], }, ) - errors["base"] = "firmware_not_fully_provisioned" + return self.async_abort(reason="firmware_not_fully_provisioned") return self.async_show_form( step_id="user", data_schema=CONFIG_SCHEMA, errors=errors @@ -238,7 +238,7 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): CONF_GEN: device_info[CONF_GEN], }, ) - errors["base"] = "firmware_not_fully_provisioned" + return self.async_abort(reason="firmware_not_fully_provisioned") else: user_input = {} @@ -333,21 +333,19 @@ class ShellyConfigFlow(ConfigFlow, domain=DOMAIN): errors: dict[str, str] = {} if not self.device_info[CONF_MODEL]: - errors["base"] = "firmware_not_fully_provisioned" - model = "Shelly" - else: - model = get_model_name(self.info) - if user_input is not None: - return self.async_create_entry( - title=self.device_info["title"], - data={ - CONF_HOST: self.host, - CONF_SLEEP_PERIOD: self.device_info[CONF_SLEEP_PERIOD], - CONF_MODEL: self.device_info[CONF_MODEL], - CONF_GEN: self.device_info[CONF_GEN], - }, - ) - self._set_confirm_only() + return self.async_abort(reason="firmware_not_fully_provisioned") + model = get_model_name(self.info) + if user_input is not None: + return self.async_create_entry( + title=self.device_info["title"], + data={ + CONF_HOST: self.host, + CONF_SLEEP_PERIOD: self.device_info[CONF_SLEEP_PERIOD], + CONF_MODEL: self.device_info[CONF_MODEL], + CONF_GEN: self.device_info[CONF_GEN], + }, + ) + self._set_confirm_only() return self.async_show_form( step_id="confirm_discovery", diff --git a/homeassistant/components/shelly/strings.json b/homeassistant/components/shelly/strings.json index 2f07742898c..203c8467deb 100644 --- a/homeassistant/components/shelly/strings.json +++ b/homeassistant/components/shelly/strings.json @@ -50,21 +50,21 @@ }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "custom_port_not_supported": "Gen1 device does not support custom port.", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", "invalid_host": "[%key:common::config_flow::error::invalid_host%]", - "unknown": "[%key:common::config_flow::error::unknown%]", - "firmware_not_fully_provisioned": "Device not fully provisioned. Please contact Shelly support", - "custom_port_not_supported": "Gen1 device does not support custom port.", - "mac_address_mismatch": "The MAC address of the device does not match the one in the configuration, please reboot the device and try again." + "mac_address_mismatch": "The MAC address of the device does not match the one in the configuration, please reboot the device and try again.", + "unknown": "[%key:common::config_flow::error::unknown%]" }, "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", + "another_device": "Re-configuration was unsuccessful, the IP address/hostname of another Shelly device was used.", + "firmware_not_fully_provisioned": "Device not fully provisioned. Please contact Shelly support", + "ipv6_not_supported": "IPv6 is not supported.", + "mac_address_mismatch": "[%key:component::shelly::config::error::mac_address_mismatch%]", "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", "reauth_unsuccessful": "Re-authentication was unsuccessful, please remove the integration and set it up again.", - "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]", - "another_device": "Re-configuration was unsuccessful, the IP address/hostname of another Shelly device was used.", - "ipv6_not_supported": "IPv6 is not supported.", - "mac_address_mismatch": "[%key:component::shelly::config::error::mac_address_mismatch%]" + "reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]" } }, "device_automation": { diff --git a/tests/components/shelly/test_config_flow.py b/tests/components/shelly/test_config_flow.py index 60883ebf5bd..26944ab1f41 100644 --- a/tests/components/shelly/test_config_flow.py +++ b/tests/components/shelly/test_config_flow.py @@ -348,8 +348,8 @@ async def test_form_missing_model_key( {CONF_HOST: "1.1.1.1"}, ) - assert result2["type"] is FlowResultType.FORM - assert result2["errors"] == {"base": "firmware_not_fully_provisioned"} + assert result2["type"] is FlowResultType.ABORT + assert result2["reason"] == "firmware_not_fully_provisioned" async def test_form_missing_model_key_auth_enabled( @@ -378,8 +378,8 @@ async def test_form_missing_model_key_auth_enabled( result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], {CONF_PASSWORD: "1234"} ) - assert result3["type"] is FlowResultType.FORM - assert result3["errors"] == {"base": "firmware_not_fully_provisioned"} + assert result3["type"] is FlowResultType.ABORT + assert result3["reason"] == "firmware_not_fully_provisioned" async def test_form_missing_model_key_zeroconf( @@ -398,15 +398,8 @@ async def test_form_missing_model_key_zeroconf( data=DISCOVERY_INFO, context={"source": config_entries.SOURCE_ZEROCONF}, ) - assert result["type"] is FlowResultType.FORM - assert result["errors"] == {"base": "firmware_not_fully_provisioned"} - - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - {}, - ) - assert result2["type"] is FlowResultType.FORM - assert result2["errors"] == {"base": "firmware_not_fully_provisioned"} + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "firmware_not_fully_provisioned" @pytest.mark.parametrize(