From f417ad86e51c52f88cf4445de259e9a5ec1f098c Mon Sep 17 00:00:00 2001 From: Ermanno Baschiera Date: Sun, 30 Aug 2026 16:58:11 +0200 Subject: [PATCH] Abort the Silla Prism config flow when MQTT is unavailable (#180712) --- .../components/silla_prism/config_flow.py | 10 ++++--- .../components/silla_prism/strings.json | 4 +-- .../silla_prism/test_config_flow.py | 26 +++++++++++++++---- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/silla_prism/config_flow.py b/homeassistant/components/silla_prism/config_flow.py index d6ac590158ad..3b793f97aaea 100644 --- a/homeassistant/components/silla_prism/config_flow.py +++ b/homeassistant/components/silla_prism/config_flow.py @@ -50,14 +50,16 @@ class PrismConfigFlow(ConfigFlow, domain=DOMAIN): await self.async_set_unique_id(base_topic) self._abort_if_unique_id_configured() + # Nothing the user can enter in this form brings the broker + # back, so this is a dead end rather than a form error. if not await async_wait_for_mqtt_client(self.hass): - errors["base"] = "mqtt_unavailable" - elif not await self._async_probe(base_topic): - errors["base"] = "no_device" - else: + return self.async_abort(reason="mqtt_unavailable") + + if await self._async_probe(base_topic): return self.async_create_entry( title="Silla Prism", data={CONF_BASE_TOPIC: base_topic} ) + errors["base"] = "no_device" return self.async_show_form( step_id="user", diff --git a/homeassistant/components/silla_prism/strings.json b/homeassistant/components/silla_prism/strings.json index 677608819c00..2b7dce9a180d 100644 --- a/homeassistant/components/silla_prism/strings.json +++ b/homeassistant/components/silla_prism/strings.json @@ -2,11 +2,11 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "invalid_discovery_info": "Invalid discovery information received." + "invalid_discovery_info": "Invalid discovery information received.", + "mqtt_unavailable": "The MQTT integration is not available. Set it up first." }, "error": { "invalid_base_topic": "This is not a valid MQTT topic. Enter the plain topic prefix from the Silla app, without wildcards.", - "mqtt_unavailable": "The MQTT integration is not available. Set it up first.", "no_device": "No Prism messages were received on this base topic. Check that the topic matches the one configured in the Silla app and that Prism is online." }, "flow_title": "{serial}", diff --git a/tests/components/silla_prism/test_config_flow.py b/tests/components/silla_prism/test_config_flow.py index 401ef0daac96..8d3dec7f6b60 100644 --- a/tests/components/silla_prism/test_config_flow.py +++ b/tests/components/silla_prism/test_config_flow.py @@ -70,7 +70,7 @@ async def test_user_flow(hass: HomeAssistant, mqtt_mock: MqttMockHAClient) -> No async def test_user_flow_no_device( hass: HomeAssistant, mqtt_mock: MqttMockHAClient ) -> None: - """Test the user flow errors when no traffic is seen.""" + """Test the user flow errors when no traffic is seen, then recovers.""" with patch(_PROBE_PATH, return_value=False): result = await hass.config_entries.flow.async_init( DOMAIN, @@ -80,19 +80,27 @@ async def test_user_flow_no_device( assert result["type"] is FlowResultType.FORM assert result["errors"] == {"base": "no_device"} + with patch(_PROBE_PATH, return_value=True): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_BASE_TOPIC: BASE_TOPIC} + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["data"] == {CONF_BASE_TOPIC: BASE_TOPIC} + async def test_user_flow_mqtt_unavailable( hass: HomeAssistant, mqtt_mock: MqttMockHAClient ) -> None: - """Test the user flow errors when MQTT is not available.""" + """Test the user flow aborts when MQTT is not available.""" with patch(_MQTT_CLIENT_PATH, return_value=False): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, data={CONF_BASE_TOPIC: BASE_TOPIC}, ) - assert result["type"] is FlowResultType.FORM - assert result["errors"] == {"base": "mqtt_unavailable"} + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "mqtt_unavailable" @pytest.mark.parametrize( @@ -103,7 +111,7 @@ async def test_user_flow_mqtt_unavailable( async def test_user_flow_invalid_base_topic( hass: HomeAssistant, mqtt_mock: MqttMockHAClient, base_topic: str ) -> None: - """Test the user flow rejects base topics that are not valid MQTT topics.""" + """Test the user flow rejects invalid base topics, then recovers.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -112,6 +120,14 @@ async def test_user_flow_invalid_base_topic( assert result["type"] is FlowResultType.FORM assert result["errors"] == {CONF_BASE_TOPIC: "invalid_base_topic"} + with patch(_PROBE_PATH, return_value=True): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_BASE_TOPIC: BASE_TOPIC} + ) + + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["data"] == {CONF_BASE_TOPIC: BASE_TOPIC} + async def test_user_flow_already_configured( hass: HomeAssistant,