mirror of
https://github.com/home-assistant/core.git
synced 2026-08-24 10:13:52 -05:00
Bump pyisy to 3.6.1 and modernize TLS handling for isy994 (#170136)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
Joost Lekkerkerker
Copilot Autofix powered by AI
parent
8fd3dcc7b1
commit
6159516dc0
@@ -13,6 +13,7 @@ from homeassistant.const import (
|
||||
CONF_PASSWORD,
|
||||
CONF_USERNAME,
|
||||
CONF_VARIABLES,
|
||||
CONF_VERIFY_SSL,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
Platform,
|
||||
)
|
||||
@@ -31,9 +32,9 @@ from .const import (
|
||||
CONF_IGNORE_STRING,
|
||||
CONF_NETWORK,
|
||||
CONF_SENSOR_STRING,
|
||||
CONF_TLS_VER,
|
||||
DEFAULT_IGNORE_STRING,
|
||||
DEFAULT_SENSOR_STRING,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
DOMAIN,
|
||||
ISY_CONF_FIRMWARE,
|
||||
ISY_CONF_MODEL,
|
||||
@@ -62,6 +63,16 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
async def async_migrate_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool:
|
||||
"""Migrate old config entries."""
|
||||
if entry.version == 1 and entry.minor_version == 1:
|
||||
new_data = {key: value for key, value in entry.data.items() if key != "tls"}
|
||||
new_data.setdefault(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)
|
||||
hass.config_entries.async_update_entry(entry, data=new_data, minor_version=2)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool:
|
||||
"""Set up the ISY 994 integration."""
|
||||
isy_config = entry.data
|
||||
@@ -71,9 +82,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool:
|
||||
user = isy_config[CONF_USERNAME]
|
||||
password = isy_config[CONF_PASSWORD]
|
||||
host = urlparse(isy_config[CONF_HOST])
|
||||
|
||||
# Optional
|
||||
tls_version = isy_config.get(CONF_TLS_VER)
|
||||
verify_ssl = isy_config[CONF_VERIFY_SSL]
|
||||
ignore_identifier = isy_options.get(CONF_IGNORE_STRING, DEFAULT_IGNORE_STRING)
|
||||
sensor_identifier = isy_options.get(CONF_SENSOR_STRING, DEFAULT_SENSOR_STRING)
|
||||
|
||||
@@ -86,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool:
|
||||
elif host.scheme == SCHEME_HTTPS:
|
||||
https = True
|
||||
port = host.port or 443
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
session = aiohttp_client.async_get_clientsession(hass, verify_ssl=verify_ssl)
|
||||
else:
|
||||
_LOGGER.error("The ISY/IoX host value in configuration is invalid")
|
||||
return False
|
||||
@@ -98,7 +107,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IsyConfigEntry) -> bool:
|
||||
username=user,
|
||||
password=password,
|
||||
use_https=https,
|
||||
tls_ver=tls_version,
|
||||
verify_ssl=verify_ssl,
|
||||
webroot=host.path,
|
||||
websession=session,
|
||||
use_websocket=True,
|
||||
|
||||
@@ -6,6 +6,7 @@ import logging
|
||||
from typing import Any
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
import aiohttp
|
||||
from aiohttp import CookieJar
|
||||
from pyisy import ISYConnectionError, ISYInvalidAuthError, ISYResponseParseError
|
||||
from pyisy.configuration import Configuration
|
||||
@@ -18,7 +19,13 @@ from homeassistant.config_entries import (
|
||||
ConfigFlowResult,
|
||||
OptionsFlowWithReload,
|
||||
)
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_NAME,
|
||||
CONF_PASSWORD,
|
||||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
@@ -34,13 +41,12 @@ from .const import (
|
||||
CONF_IGNORE_STRING,
|
||||
CONF_RESTORE_LIGHT_STATE,
|
||||
CONF_SENSOR_STRING,
|
||||
CONF_TLS_VER,
|
||||
CONF_VAR_SENSOR_STRING,
|
||||
DEFAULT_IGNORE_STRING,
|
||||
DEFAULT_RESTORE_LIGHT_STATE,
|
||||
DEFAULT_SENSOR_STRING,
|
||||
DEFAULT_TLS_VERSION,
|
||||
DEFAULT_VAR_SENSOR_STRING,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
DOMAIN,
|
||||
HTTP_PORT,
|
||||
HTTPS_PORT,
|
||||
@@ -63,7 +69,7 @@ def _data_schema(schema_input: dict[str, str]) -> vol.Schema:
|
||||
vol.Required(CONF_HOST, default=schema_input.get(CONF_HOST, "")): str,
|
||||
vol.Required(CONF_USERNAME): str,
|
||||
vol.Required(CONF_PASSWORD): str,
|
||||
vol.Optional(CONF_TLS_VER, default=DEFAULT_TLS_VERSION): vol.In([1.1, 1.2]),
|
||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): bool,
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
@@ -77,7 +83,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
user = data[CONF_USERNAME]
|
||||
password = data[CONF_PASSWORD]
|
||||
host = urlparse(data[CONF_HOST])
|
||||
tls_version = data.get(CONF_TLS_VER)
|
||||
verify_ssl = data[CONF_VERIFY_SSL]
|
||||
|
||||
if host.scheme == SCHEME_HTTP:
|
||||
https = False
|
||||
@@ -88,7 +94,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
elif host.scheme == SCHEME_HTTPS:
|
||||
https = True
|
||||
port = host.port or HTTPS_PORT
|
||||
session = aiohttp_client.async_get_clientsession(hass)
|
||||
session = aiohttp_client.async_get_clientsession(hass, verify_ssl=verify_ssl)
|
||||
else:
|
||||
_LOGGER.error("The ISY/IoX host value in configuration is invalid")
|
||||
raise InvalidHost
|
||||
@@ -100,7 +106,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
user,
|
||||
password,
|
||||
use_https=https,
|
||||
tls_ver=tls_version,
|
||||
verify_ssl=verify_ssl,
|
||||
webroot=host.path,
|
||||
websession=session,
|
||||
)
|
||||
@@ -111,6 +117,10 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
except ISYInvalidAuthError as error:
|
||||
raise InvalidAuth from error
|
||||
except ISYConnectionError as error:
|
||||
# pyisy chains the underlying aiohttp error via __cause__; ClientSSLError
|
||||
# covers both protocol mismatch and certificate verification failures.
|
||||
if isinstance(error.__cause__, aiohttp.ClientSSLError):
|
||||
raise SslError from error
|
||||
raise CannotConnect from error
|
||||
|
||||
try:
|
||||
@@ -131,6 +141,7 @@ class Isy994ConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Universal Devices ISY/IoX."""
|
||||
|
||||
VERSION = 1
|
||||
MINOR_VERSION = 2
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the ISY/IoX config flow."""
|
||||
@@ -156,6 +167,8 @@ class Isy994ConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
info = await validate_input(self.hass, user_input)
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except SslError:
|
||||
errors["base"] = "ssl_error"
|
||||
except InvalidHost:
|
||||
errors["base"] = "invalid_host"
|
||||
except InvalidAuth:
|
||||
@@ -291,6 +304,8 @@ class Isy994ConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
await validate_input(self.hass, new_data)
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except SslError:
|
||||
errors["base"] = "ssl_error"
|
||||
except InvalidAuth:
|
||||
errors[CONF_PASSWORD] = "invalid_auth"
|
||||
else:
|
||||
@@ -368,5 +383,9 @@ class CannotConnect(HomeAssistantError):
|
||||
"""Error to indicate we cannot connect."""
|
||||
|
||||
|
||||
class SslError(HomeAssistantError):
|
||||
"""Error to indicate a TLS/SSL handshake failure."""
|
||||
|
||||
|
||||
class InvalidAuth(HomeAssistantError):
|
||||
"""Error to indicate there is invalid auth."""
|
||||
|
||||
@@ -69,13 +69,12 @@ CONF_NETWORK = "network"
|
||||
CONF_IGNORE_STRING = "ignore_string"
|
||||
CONF_SENSOR_STRING = "sensor_string"
|
||||
CONF_VAR_SENSOR_STRING = "variable_sensor_string"
|
||||
CONF_TLS_VER = "tls"
|
||||
CONF_RESTORE_LIGHT_STATE = "restore_light_state"
|
||||
|
||||
DEFAULT_IGNORE_STRING = "{IGNORE ME}"
|
||||
DEFAULT_SENSOR_STRING = "sensor"
|
||||
DEFAULT_RESTORE_LIGHT_STATE = False
|
||||
DEFAULT_TLS_VERSION = 1.1
|
||||
DEFAULT_VERIFY_SSL = False
|
||||
DEFAULT_PROGRAM_STRING = "HA."
|
||||
DEFAULT_VAR_SENSOR_STRING = "HA."
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyisy"],
|
||||
"requirements": ["pyisy==3.5.1"],
|
||||
"requirements": ["pyisy==3.6.1"],
|
||||
"ssdp": [
|
||||
{
|
||||
"deviceType": "urn:udi-com:device:X_Insteon_Lighting_Device:1",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"invalid_host": "The host entry was not in full URL format, e.g., {sample_ip}",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"ssl_error": "TLS handshake failed. The controller may require a newer TLS version, or SSL verification may be failing due to a self-signed certificate.",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"flow_title": "{name} ({host})",
|
||||
@@ -25,8 +26,11 @@
|
||||
"data": {
|
||||
"host": "[%key:common::config_flow::data::url%]",
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"tls": "The TLS version of the ISY controller.",
|
||||
"username": "[%key:common::config_flow::data::username%]"
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
|
||||
},
|
||||
"data_description": {
|
||||
"verify_ssl": "Verify the controller's TLS certificate. Leave disabled for ISY-994/eisy/Polisy controllers using their default self-signed certificate."
|
||||
},
|
||||
"description": "The host entry must be in full URL format, e.g., {sample_ip}",
|
||||
"title": "Connect to your ISY"
|
||||
|
||||
Generated
+1
-1
@@ -2240,7 +2240,7 @@ pyiskra==0.1.27
|
||||
pyiss==1.0.1
|
||||
|
||||
# homeassistant.components.isy994
|
||||
pyisy==3.5.1
|
||||
pyisy==3.6.1
|
||||
|
||||
# homeassistant.components.itach
|
||||
pyitachip2ir==0.0.7
|
||||
|
||||
Generated
+1
-1
@@ -1929,7 +1929,7 @@ pyiskra==0.1.27
|
||||
pyiss==1.0.1
|
||||
|
||||
# homeassistant.components.isy994
|
||||
pyisy==3.5.1
|
||||
pyisy==3.6.1
|
||||
|
||||
# homeassistant.components.ituran
|
||||
pyituran==0.1.5
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
"""Test the Universal Devices ISY/IoX config flow."""
|
||||
|
||||
import re
|
||||
from unittest.mock import patch
|
||||
import ssl
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import aiohttp
|
||||
from pyisy import ISYConnectionError, ISYInvalidAuthError
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.isy994.const import (
|
||||
CONF_TLS_VER,
|
||||
DOMAIN,
|
||||
ISY_URL_POSTFIX,
|
||||
UDN_UUID_PREFIX,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_IGNORE, SOURCE_SSDP
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
@@ -30,7 +32,7 @@ MOCK_USERNAME = "test-username"
|
||||
MOCK_PASSWORD = "test-password"
|
||||
|
||||
# Don't use the integration defaults here to make sure they're being set correctly.
|
||||
MOCK_TLS_VERSION = 1.2
|
||||
MOCK_VERIFY_SSL = True
|
||||
MOCK_IGNORE_STRING = "{IGNOREME}"
|
||||
MOCK_RESTORE_LIGHT_STATE = True
|
||||
MOCK_SENSOR_STRING = "IMASENSOR"
|
||||
@@ -40,13 +42,13 @@ MOCK_USER_INPUT = {
|
||||
CONF_HOST: f"http://{MOCK_HOSTNAME}",
|
||||
CONF_USERNAME: MOCK_USERNAME,
|
||||
CONF_PASSWORD: MOCK_PASSWORD,
|
||||
CONF_TLS_VER: MOCK_TLS_VERSION,
|
||||
CONF_VERIFY_SSL: MOCK_VERIFY_SSL,
|
||||
}
|
||||
MOCK_IOX_USER_INPUT = {
|
||||
CONF_HOST: f"http://{MOCK_HOSTNAME}:8080",
|
||||
CONF_USERNAME: MOCK_USERNAME,
|
||||
CONF_PASSWORD: MOCK_PASSWORD,
|
||||
CONF_TLS_VER: MOCK_TLS_VERSION,
|
||||
CONF_VERIFY_SSL: MOCK_VERIFY_SSL,
|
||||
}
|
||||
|
||||
MOCK_DEVICE_NAME = "Name of the device"
|
||||
@@ -124,10 +126,10 @@ async def test_form_invalid_host(hass: HomeAssistant) -> None:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
"host": MOCK_HOSTNAME, # Test with missing protocol (http://)
|
||||
"username": MOCK_USERNAME,
|
||||
"password": MOCK_PASSWORD,
|
||||
"tls": MOCK_TLS_VERSION,
|
||||
CONF_HOST: MOCK_HOSTNAME, # Test with missing protocol (http://)
|
||||
CONF_USERNAME: MOCK_USERNAME,
|
||||
CONF_PASSWORD: MOCK_PASSWORD,
|
||||
CONF_VERIFY_SSL: MOCK_VERIFY_SSL,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -189,6 +191,66 @@ async def test_form_isy_connection_error(hass: HomeAssistant) -> None:
|
||||
assert result2["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
||||
async def test_form_isy_ssl_error(hass: HomeAssistant) -> None:
|
||||
"""Test we surface ssl_error when pyisy chains an aiohttp.ClientSSLError.
|
||||
|
||||
Uses an HTTPS URL so the HTTPS session branch (which honors verify_ssl)
|
||||
is also exercised.
|
||||
"""
|
||||
ssl_cause = aiohttp.ClientSSLError(
|
||||
connection_key=None, os_error=ssl.SSLError("handshake failed")
|
||||
)
|
||||
isy_error = ISYConnectionError("ssl handshake failed")
|
||||
isy_error.__cause__ = ssl_cause
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
with patch(PATCH_CONNECTION, side_effect=isy_error):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{**MOCK_USER_INPUT, CONF_HOST: f"https://{MOCK_HOSTNAME}"},
|
||||
)
|
||||
|
||||
assert result2["type"] is FlowResultType.FORM
|
||||
assert result2["errors"] == {"base": "ssl_error"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("verify_ssl", [True, False])
|
||||
async def test_form_forwards_verify_ssl_to_connection(
|
||||
hass: HomeAssistant, verify_ssl: bool
|
||||
) -> None:
|
||||
"""Test verify_ssl is forwarded to the pyisy Connection used during validation."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with (
|
||||
patch(
|
||||
f"{INTEGRATION}.config_flow.Connection",
|
||||
) as mock_connection_cls,
|
||||
patch(
|
||||
PATCH_ASYNC_SETUP_ENTRY,
|
||||
return_value=True,
|
||||
),
|
||||
):
|
||||
mock_connection_cls.return_value.test_connection = AsyncMock(
|
||||
return_value=MOCK_CONFIG_RESPONSE
|
||||
)
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
**MOCK_USER_INPUT,
|
||||
CONF_HOST: f"https://{MOCK_HOSTNAME}",
|
||||
CONF_VERIFY_SSL: verify_ssl,
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert mock_connection_cls.call_args.kwargs["verify_ssl"] is verify_ssl
|
||||
|
||||
|
||||
async def test_form_isy_parse_response_error(hass: HomeAssistant) -> None:
|
||||
"""Test we handle poorly formatted XML response from ISY."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@@ -641,6 +703,7 @@ async def test_reauth(hass: HomeAssistant) -> None:
|
||||
data={
|
||||
CONF_USERNAME: "bob",
|
||||
CONF_HOST: f"http://{MOCK_HOSTNAME}:1443{ISY_URL_POSTFIX}",
|
||||
CONF_VERIFY_SSL: False,
|
||||
},
|
||||
unique_id=MOCK_UUID,
|
||||
)
|
||||
@@ -681,6 +744,22 @@ async def test_reauth(hass: HomeAssistant) -> None:
|
||||
assert result3["type"] is FlowResultType.FORM
|
||||
assert result3["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
ssl_error = ISYConnectionError("ssl handshake failed")
|
||||
ssl_error.__cause__ = aiohttp.ClientSSLError(
|
||||
connection_key=None, os_error=ssl.SSLError("handshake failed")
|
||||
)
|
||||
with patch(PATCH_CONNECTION, side_effect=ssl_error):
|
||||
result_ssl = await hass.config_entries.flow.async_configure(
|
||||
result3["flow_id"],
|
||||
{
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
|
||||
assert result_ssl["type"] is FlowResultType.FORM
|
||||
assert result_ssl["errors"] == {"base": "ssl_error"}
|
||||
|
||||
with (
|
||||
patch(PATCH_CONNECTION, return_value=MOCK_CONFIG_RESPONSE),
|
||||
patch(
|
||||
@@ -689,7 +768,7 @@ async def test_reauth(hass: HomeAssistant) -> None:
|
||||
) as mock_setup_entry,
|
||||
):
|
||||
result4 = await hass.config_entries.flow.async_configure(
|
||||
result3["flow_id"],
|
||||
result_ssl["flow_id"],
|
||||
{
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
"""Test the Universal Devices ISY/IoX integration init."""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.isy994.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_UUID = "ce:fb:72:31:b7:b9"
|
||||
|
||||
|
||||
async def test_migrate_minor_version_drops_tls(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test minor migration drops legacy "tls" and seeds verify_ssl."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=1,
|
||||
minor_version=1,
|
||||
data={
|
||||
CONF_HOST: "http://1.1.1.1",
|
||||
CONF_USERNAME: "user",
|
||||
CONF_PASSWORD: "pass",
|
||||
"tls": 1.1,
|
||||
},
|
||||
unique_id=MOCK_UUID,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert entry.version == 1
|
||||
assert entry.minor_version == 2
|
||||
assert "tls" not in entry.data
|
||||
assert entry.data[CONF_VERIFY_SSL] is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("verify_ssl", [True, False])
|
||||
async def test_setup_forwards_verify_ssl_to_pyisy(
|
||||
hass: HomeAssistant,
|
||||
mock_isy: MagicMock,
|
||||
verify_ssl: bool,
|
||||
) -> None:
|
||||
"""Test the verify_ssl entry option is forwarded to the pyisy ISY constructor."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
version=1,
|
||||
minor_version=2,
|
||||
data={
|
||||
CONF_HOST: "https://1.1.1.1",
|
||||
CONF_USERNAME: "user",
|
||||
CONF_PASSWORD: "pass",
|
||||
CONF_VERIFY_SSL: verify_ssl,
|
||||
},
|
||||
unique_id=MOCK_UUID,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.isy994.ISY", return_value=mock_isy
|
||||
) as isy_constructor:
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert isy_constructor.call_args.kwargs["verify_ssl"] is verify_ssl
|
||||
Reference in New Issue
Block a user