Use only IPv4 for zeroconf in bluesound integration (#140226)

* Use only ipv4 for zeroconf

* Fix tests

* Use only ip_address for ip version check

* Add test

* Reduce test
This commit is contained in:
Louis Christ 2025-03-14 10:20:16 +01:00 committed by GitHub
parent 2b0a2e7644
commit d952e8186f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 32 additions and 7 deletions

View File

@ -75,6 +75,9 @@ class BluesoundConfigFlow(ConfigFlow, domain=DOMAIN):
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
"""Handle a flow initialized by zeroconf discovery."""
# the player can have an ipv6 address, but the api is only available on ipv4
if discovery_info.ip_address.version != 4:
return self.async_abort(reason="no_ipv4_address")
if discovery_info.port is not None:
self._port = discovery_info.port

View File

@ -19,7 +19,8 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_service%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]"
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"no_ipv4_address": "No IPv4 address found."
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"

View File

@ -1,5 +1,6 @@
"""Test the Bluesound config flow."""
from ipaddress import IPv4Address, IPv6Address
from unittest.mock import AsyncMock
from pyblu.errors import PlayerUnreachableError
@ -121,8 +122,8 @@ async def test_zeroconf_flow_success(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=ZeroconfServiceInfo(
ip_address="1.1.1.1",
ip_addresses=["1.1.1.1"],
ip_address=IPv4Address("1.1.1.1"),
ip_addresses=[IPv4Address("1.1.1.1")],
port=11000,
hostname="player-name1111",
type="_musc._tcp.local.",
@ -160,8 +161,8 @@ async def test_zeroconf_flow_cannot_connect(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=ZeroconfServiceInfo(
ip_address="1.1.1.1",
ip_addresses=["1.1.1.1"],
ip_address=IPv4Address("1.1.1.1"),
ip_addresses=[IPv4Address("1.1.1.1")],
port=11000,
hostname="player-name1111",
type="_musc._tcp.local.",
@ -187,8 +188,8 @@ async def test_zeroconf_flow_already_configured(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=ZeroconfServiceInfo(
ip_address="1.1.1.2",
ip_addresses=["1.1.1.2"],
ip_address=IPv4Address("1.1.1.2"),
ip_addresses=[IPv4Address("1.1.1.2")],
port=11000,
hostname="player-name1112",
type="_musc._tcp.local.",
@ -203,3 +204,23 @@ async def test_zeroconf_flow_already_configured(
assert config_entry.data[CONF_HOST] == "1.1.1.2"
player_mocks.player_data_for_already_configured.player.sync_status.assert_called_once()
async def test_zeroconf_flow_no_ipv4_address(hass: HomeAssistant) -> None:
"""Test abort flow when no ipv4 address is found in zeroconf data."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=ZeroconfServiceInfo(
ip_address=IPv6Address("2001:db8::1"),
ip_addresses=[IPv6Address("2001:db8::1")],
port=11000,
hostname="player-name1112",
type="_musc._tcp.local.",
name="player-name._musc._tcp.local.",
properties={},
),
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "no_ipv4_address"