Elmax - fix issue 136877 (#138419)
* Fix IPv6 zero-conf discovery not handling hostname correctly. * Aligned tests. * Remove redundant !s notation. * Add IPv6 discovery tests * Parametrize input_uri to avoid duplicated code * Update tests/components/elmax/conftest.py --------- Co-authored-by: Josef Zweck <josef@zweck.dev>pull/138699/head^2
parent
e77193fa2e
commit
cd13eff8ae
|
@ -498,7 +498,11 @@ class ElmaxConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle device found via zeroconf."""
|
||||
host = discovery_info.host
|
||||
host = (
|
||||
f"[{discovery_info.ip_address}]"
|
||||
if discovery_info.ip_address.version == 6
|
||||
else str(discovery_info.ip_address)
|
||||
)
|
||||
https_port = (
|
||||
int(discovery_info.port)
|
||||
if discovery_info.port is not None
|
||||
|
|
|
@ -30,6 +30,7 @@ MOCK_PANEL_PIN = "000000"
|
|||
MOCK_WRONG_PANEL_PIN = "000000"
|
||||
MOCK_PASSWORD = "password"
|
||||
MOCK_DIRECT_HOST = "1.1.1.1"
|
||||
MOCK_DIRECT_HOST_V6 = "fd00::be2:54:34:2"
|
||||
MOCK_DIRECT_HOST_CHANGED = "2.2.2.2"
|
||||
MOCK_DIRECT_PORT = 443
|
||||
MOCK_DIRECT_SSL = True
|
||||
|
|
|
@ -18,6 +18,7 @@ import respx
|
|||
|
||||
from . import (
|
||||
MOCK_DIRECT_HOST,
|
||||
MOCK_DIRECT_HOST_V6,
|
||||
MOCK_DIRECT_PORT,
|
||||
MOCK_DIRECT_SSL,
|
||||
MOCK_PANEL_ID,
|
||||
|
@ -29,6 +30,7 @@ from tests.common import load_fixture
|
|||
MOCK_DIRECT_BASE_URI = (
|
||||
f"{'https' if MOCK_DIRECT_SSL else 'http'}://{MOCK_DIRECT_HOST}:{MOCK_DIRECT_PORT}"
|
||||
)
|
||||
MOCK_DIRECT_BASE_URI_V6 = f"{'https' if MOCK_DIRECT_SSL else 'http'}://[{MOCK_DIRECT_HOST_V6}]:{MOCK_DIRECT_PORT}"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
@ -58,12 +60,16 @@ def httpx_mock_cloud_fixture() -> Generator[respx.MockRouter]:
|
|||
yield respx_mock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def base_uri() -> str:
|
||||
"""Configure the base-uri for the respx mock fixtures."""
|
||||
return MOCK_DIRECT_BASE_URI
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def httpx_mock_direct_fixture() -> Generator[respx.MockRouter]:
|
||||
def httpx_mock_direct_fixture(base_uri: str) -> Generator[respx.MockRouter]:
|
||||
"""Configure httpx fixture for direct Panel-API communication."""
|
||||
with respx.mock(
|
||||
base_url=MOCK_DIRECT_BASE_URI, assert_all_called=False
|
||||
) as respx_mock:
|
||||
with respx.mock(base_url=base_uri, assert_all_called=False) as respx_mock:
|
||||
# Mock Login POST.
|
||||
login_route = respx_mock.post(f"/api/v2/{ENDPOINT_LOGIN}", name="login")
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
"""Tests for the Elmax config flow."""
|
||||
|
||||
from ipaddress import IPv4Address, IPv6Address
|
||||
from unittest.mock import patch
|
||||
|
||||
from elmax_api.exceptions import ElmaxBadLoginError, ElmaxBadPinError, ElmaxNetworkError
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.elmax.const import (
|
||||
|
@ -28,6 +30,7 @@ from . import (
|
|||
MOCK_DIRECT_CERT,
|
||||
MOCK_DIRECT_HOST,
|
||||
MOCK_DIRECT_HOST_CHANGED,
|
||||
MOCK_DIRECT_HOST_V6,
|
||||
MOCK_DIRECT_PORT,
|
||||
MOCK_DIRECT_SSL,
|
||||
MOCK_PANEL_ID,
|
||||
|
@ -37,12 +40,27 @@ from . import (
|
|||
MOCK_USERNAME,
|
||||
MOCK_WRONG_PANEL_PIN,
|
||||
)
|
||||
from .conftest import MOCK_DIRECT_BASE_URI_V6
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_ZEROCONF_DISCOVERY_INFO = ZeroconfServiceInfo(
|
||||
ip_address=MOCK_DIRECT_HOST,
|
||||
ip_addresses=[MOCK_DIRECT_HOST],
|
||||
ip_address=IPv4Address(address=MOCK_DIRECT_HOST),
|
||||
ip_addresses=[IPv4Address(address=MOCK_DIRECT_HOST)],
|
||||
hostname="VideoBox.local",
|
||||
name="VideoBox",
|
||||
port=443,
|
||||
properties={
|
||||
"idl": MOCK_PANEL_ID,
|
||||
"idr": MOCK_PANEL_ID,
|
||||
"v1": "PHANTOM64PRO_GSM 11.9.844",
|
||||
"v2": "4.9.13",
|
||||
},
|
||||
type="_elmax-ssl._tcp",
|
||||
)
|
||||
MOCK_ZEROCONF_DISCOVERY_INFO_V6 = ZeroconfServiceInfo(
|
||||
ip_address=IPv6Address(address=MOCK_DIRECT_HOST_V6),
|
||||
ip_addresses=[IPv6Address(address=MOCK_DIRECT_HOST_V6)],
|
||||
hostname="VideoBox.local",
|
||||
name="VideoBox",
|
||||
port=443,
|
||||
|
@ -55,8 +73,8 @@ MOCK_ZEROCONF_DISCOVERY_INFO = ZeroconfServiceInfo(
|
|||
type="_elmax-ssl._tcp",
|
||||
)
|
||||
MOCK_ZEROCONF_DISCOVERY_CHANGED_INFO = ZeroconfServiceInfo(
|
||||
ip_address=MOCK_DIRECT_HOST_CHANGED,
|
||||
ip_addresses=[MOCK_DIRECT_HOST_CHANGED],
|
||||
ip_address=IPv4Address(address=MOCK_DIRECT_HOST_CHANGED),
|
||||
ip_addresses=[IPv4Address(address=MOCK_DIRECT_HOST_CHANGED)],
|
||||
hostname="VideoBox.local",
|
||||
name="VideoBox",
|
||||
port=443,
|
||||
|
@ -69,8 +87,8 @@ MOCK_ZEROCONF_DISCOVERY_CHANGED_INFO = ZeroconfServiceInfo(
|
|||
type="_elmax-ssl._tcp",
|
||||
)
|
||||
MOCK_ZEROCONF_DISCOVERY_INFO_NOT_SUPPORTED = ZeroconfServiceInfo(
|
||||
ip_address=MOCK_DIRECT_HOST,
|
||||
ip_addresses=[MOCK_DIRECT_HOST],
|
||||
ip_address=IPv4Address(MOCK_DIRECT_HOST),
|
||||
ip_addresses=[IPv4Address(MOCK_DIRECT_HOST)],
|
||||
hostname="VideoBox.local",
|
||||
name="VideoBox",
|
||||
port=443,
|
||||
|
@ -194,6 +212,18 @@ async def test_zeroconf_discovery(hass: HomeAssistant) -> None:
|
|||
assert result["errors"] is None
|
||||
|
||||
|
||||
async def test_zeroconf_discovery_ipv6(hass: HomeAssistant) -> None:
|
||||
"""Test discovery of Elmax local api panel."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||
data=MOCK_ZEROCONF_DISCOVERY_INFO_V6,
|
||||
)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "zeroconf_setup"
|
||||
assert result["errors"] is None
|
||||
|
||||
|
||||
async def test_zeroconf_setup_show_form(hass: HomeAssistant) -> None:
|
||||
"""Test discovery shows a form when activated."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -230,6 +260,27 @@ async def test_zeroconf_setup(hass: HomeAssistant) -> None:
|
|||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
|
||||
|
||||
@pytest.mark.parametrize("base_uri", [MOCK_DIRECT_BASE_URI_V6])
|
||||
async def test_zeroconf_ipv6_setup(hass: HomeAssistant) -> None:
|
||||
"""Test the successful creation of config entry via discovery flow."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||
data=MOCK_ZEROCONF_DISCOVERY_INFO_V6,
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_ELMAX_PANEL_PIN: MOCK_PANEL_PIN,
|
||||
CONF_ELMAX_MODE_DIRECT_SSL: MOCK_DIRECT_SSL,
|
||||
},
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||
|
||||
|
||||
async def test_zeroconf_already_configured(hass: HomeAssistant) -> None:
|
||||
"""Ensure local discovery aborts when same panel is already added to ha."""
|
||||
MockConfigEntry(
|
||||
|
|
Loading…
Reference in New Issue