Reject Hot Spring Spa Network Adapter (SNA) in config flow (hotfix) (#181261)

This commit is contained in:
Christophe Gagnier
2026-09-05 10:33:33 +00:00
committed by Franck Nijhof
parent c6cd02013e
commit aeef1e5d5e
3 changed files with 46 additions and 15 deletions
@@ -3,7 +3,13 @@
from collections.abc import Mapping
from typing import Any, override
from hotspring import HotSpring, HotSpringConnectionError, HotSpringError, Spa
from hotspring import (
HotSpring,
HotSpringConnectionError,
HotSpringError,
HotSpringSNADetectedError,
Spa,
)
import voluptuous as vol
from homeassistant.config_entries import (
@@ -52,6 +58,8 @@ class HotSpringConfigFlow(ConfigFlow, domain=DOMAIN):
if user_input is not None:
try:
spa = await validate_input(self.hass, user_input)
except HotSpringSNADetectedError:
errors["base"] = "sna_device"
except HotSpringConnectionError, HotSpringError:
errors["base"] = "cannot_connect"
else:
@@ -101,6 +109,8 @@ class HotSpringConfigFlow(ConfigFlow, domain=DOMAIN):
self.discovered_spa = await validate_input(
self.hass, {CONF_HOST: discovery_info.host}
)
except HotSpringSNADetectedError:
return self.async_abort(reason="sna_device")
except HotSpringConnectionError, HotSpringError:
return self.async_abort(reason="cannot_connect")
@@ -4,10 +4,12 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"sna_device": "The discovered device is a Spa Network Adapter (SNA). Only the Home Network Adapter (HNA) can be configured.",
"unique_id_mismatch": "The MAC address does not match the configured device. Please ensure you reconfigure against the same device."
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"sna_device": "The entered address belongs to the Spa Network Adapter (SNA). Please enter the IP address or hostname of your Home Network Adapter (HNA) instead."
},
"step": {
"user": {
+32 -13
View File
@@ -4,7 +4,12 @@ import dataclasses
from ipaddress import ip_address
from unittest.mock import MagicMock
from hotspring import HotSpringConnectionError, HotSpringError, Spa
from hotspring import (
HotSpringConnectionError,
HotSpringError,
HotSpringSNADetectedError,
Spa,
)
import pytest
from homeassistant.components.hotspring.const import DOMAIN
@@ -69,14 +74,21 @@ async def test_user_device_exists_abort(
@pytest.mark.parametrize(
"exception",
[HotSpringConnectionError, HotSpringError],
("exception", "error_key"),
[
(HotSpringConnectionError, "cannot_connect"),
(HotSpringError, "cannot_connect"),
(HotSpringSNADetectedError, "sna_device"),
],
)
@pytest.mark.usefixtures("mock_setup_entry")
async def test_form_cannot_connect(
hass: HomeAssistant, mock_hotspring: MagicMock, exception: type[Exception]
async def test_form_errors(
hass: HomeAssistant,
mock_hotspring: MagicMock,
exception: type[Exception],
error_key: str,
) -> None:
"""Test we show user form on Hot Spring connection error and recover."""
"""Test we show user form on error and recover."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
@@ -92,7 +104,7 @@ async def test_form_cannot_connect(
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "cannot_connect"}
assert result["errors"] == {"base": error_key}
mock_hotspring.update.side_effect = None
result = await hass.config_entries.flow.async_configure(
@@ -158,13 +170,20 @@ async def test_full_zeroconf_flow_implementation(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
"exception",
[HotSpringConnectionError, HotSpringError],
("exception", "reason"),
[
(HotSpringConnectionError, "cannot_connect"),
(HotSpringError, "cannot_connect"),
(HotSpringSNADetectedError, "sna_device"),
],
)
async def test_zeroconf_connection_error(
hass: HomeAssistant, mock_hotspring: MagicMock, exception: type[Exception]
async def test_zeroconf_error(
hass: HomeAssistant,
mock_hotspring: MagicMock,
exception: type[Exception],
reason: str,
) -> None:
"""Test we abort zeroconf flow on Hot Spring connection error."""
"""Test we abort zeroconf flow on Hot Spring error."""
mock_hotspring.update.side_effect = exception
result = await hass.config_entries.flow.async_init(
@@ -174,7 +193,7 @@ async def test_zeroconf_connection_error(
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
assert result["reason"] == reason
@pytest.mark.usefixtures("mock_hotspring")