Merge pull request #40310 from home-assistant/rc

This commit is contained in:
Paulus Schoutsen 2020-09-19 23:06:09 +02:00 committed by GitHub
commit ddbadb1e26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 157 additions and 76 deletions

View File

@ -11,7 +11,7 @@ from broadlink.exceptions import (
)
import voluptuous as vol
from homeassistant import config_entries
from homeassistant import config_entries, data_entry_flow
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, CONF_TIMEOUT, CONF_TYPE
from homeassistant.helpers import config_validation as cv
@ -20,6 +20,7 @@ from .const import ( # pylint: disable=unused-import
DEFAULT_PORT,
DEFAULT_TIMEOUT,
DOMAIN,
DOMAINS_AND_TYPES,
)
from .helpers import format_mac
@ -36,6 +37,19 @@ class BroadlinkFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
async def async_set_device(self, device, raise_on_progress=True):
"""Define a device for the config flow."""
supported_types = {
device_type
for _, device_types in DOMAINS_AND_TYPES
for device_type in device_types
}
if device.type not in supported_types:
LOGGER.error(
"Unsupported device: %s. If it worked before, please open "
"an issue at https://github.com/home-assistant/core/issues",
hex(device.devtype),
)
raise data_entry_flow.AbortFlow("not_supported")
await self.async_set_unique_id(
device.mac.hex(), raise_on_progress=raise_on_progress
)

View File

@ -35,6 +35,7 @@
"already_in_progress": "There is already a configuration flow in progress for this device",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_host": "Invalid hostname or IP address",
"not_supported": "Device not supported",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {

View File

@ -5,6 +5,7 @@
"already_in_progress": "There is already a configuration flow in progress for this device",
"cannot_connect": "Failed to connect",
"invalid_host": "Invalid hostname or IP address",
"not_supported": "Device not supported",
"unknown": "Unexpected error"
},
"error": {

View File

@ -2,7 +2,7 @@
"domain": "frontend",
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": ["home-assistant-frontend==20200917.1"],
"requirements": ["home-assistant-frontend==20200918.0"],
"dependencies": [
"api",
"auth",

View File

@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/hangouts",
"requirements": [
"hangups==0.4.10"
"hangups==0.4.11"
],
"codeowners": []
}

View File

@ -116,6 +116,9 @@ class KodiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
}
)
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context.update({"title_placeholders": {CONF_NAME: self._name}})
try:
await validate_http(self.hass, self._get_data())
await validate_ws(self.hass, self._get_data())
@ -129,8 +132,6 @@ class KodiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
_LOGGER.exception("Unexpected exception")
return self.async_abort(reason="unknown")
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context.update({"title_placeholders": {CONF_NAME: self._name}})
return await self.async_step_discovery_confirm()
async def async_step_discovery_confirm(self, user_input=None):

View File

@ -171,7 +171,7 @@ class ModbusCoilSwitch(ToggleEntity, RestoreEntity):
return
self._available = True
return bool(result.bits[0])
return bool(result.bits[coil])
def _write_coil(self, coil, value):
"""Write coil using the Modbus hub slave."""

View File

@ -60,6 +60,7 @@ from .const import (
CONF_RETAIN,
CONF_STATE_TOPIC,
CONF_WILL_MESSAGE,
DATA_MQTT_CONFIG,
DEFAULT_BIRTH,
DEFAULT_DISCOVERY,
DEFAULT_PAYLOAD_AVAILABLE,
@ -88,7 +89,6 @@ _LOGGER = logging.getLogger(__name__)
DOMAIN = "mqtt"
DATA_MQTT = "mqtt"
DATA_MQTT_CONFIG = "mqtt_config"
SERVICE_PUBLISH = "publish"
SERVICE_DUMP = "dump"

View File

@ -24,6 +24,7 @@ from .const import (
CONF_BROKER,
CONF_DISCOVERY,
CONF_WILL_MESSAGE,
DATA_MQTT_CONFIG,
DEFAULT_BIRTH,
DEFAULT_DISCOVERY,
DEFAULT_WILL,
@ -162,6 +163,7 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow):
"""Manage the MQTT options."""
errors = {}
current_config = self.config_entry.data
yaml_config = self.hass.data.get(DATA_MQTT_CONFIG, {})
if user_input is not None:
can_connect = await self.hass.async_add_executor_job(
try_connection,
@ -178,20 +180,22 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow):
errors["base"] = "cannot_connect"
fields = OrderedDict()
fields[vol.Required(CONF_BROKER, default=current_config[CONF_BROKER])] = str
fields[vol.Required(CONF_PORT, default=current_config[CONF_PORT])] = vol.Coerce(
int
)
current_broker = current_config.get(CONF_BROKER, yaml_config.get(CONF_BROKER))
current_port = current_config.get(CONF_PORT, yaml_config.get(CONF_PORT))
current_user = current_config.get(CONF_USERNAME, yaml_config.get(CONF_USERNAME))
current_pass = current_config.get(CONF_PASSWORD, yaml_config.get(CONF_PASSWORD))
fields[vol.Required(CONF_BROKER, default=current_broker)] = str
fields[vol.Required(CONF_PORT, default=current_port)] = vol.Coerce(int)
fields[
vol.Optional(
CONF_USERNAME,
description={"suggested_value": current_config.get(CONF_USERNAME)},
description={"suggested_value": current_user},
)
] = str
fields[
vol.Optional(
CONF_PASSWORD,
description={"suggested_value": current_config.get(CONF_PASSWORD)},
description={"suggested_value": current_pass},
)
] = str
@ -205,6 +209,7 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow):
"""Manage the MQTT options."""
errors = {}
current_config = self.config_entry.data
yaml_config = self.hass.data.get(DATA_MQTT_CONFIG, {})
options_config = {}
if user_input is not None:
bad_birth = False
@ -253,16 +258,24 @@ class MQTTOptionsFlowHandler(config_entries.OptionsFlow):
)
return self.async_create_entry(title="", data=None)
birth = {**DEFAULT_BIRTH, **current_config.get(CONF_BIRTH_MESSAGE, {})}
will = {**DEFAULT_WILL, **current_config.get(CONF_WILL_MESSAGE, {})}
birth = {
**DEFAULT_BIRTH,
**current_config.get(
CONF_BIRTH_MESSAGE, yaml_config.get(CONF_BIRTH_MESSAGE, {})
),
}
will = {
**DEFAULT_WILL,
**current_config.get(
CONF_WILL_MESSAGE, yaml_config.get(CONF_WILL_MESSAGE, {})
),
}
discovery = current_config.get(
CONF_DISCOVERY, yaml_config.get(CONF_DISCOVERY, DEFAULT_DISCOVERY)
)
fields = OrderedDict()
fields[
vol.Optional(
CONF_DISCOVERY,
default=current_config.get(CONF_DISCOVERY, DEFAULT_DISCOVERY),
)
] = bool
fields[vol.Optional(CONF_DISCOVERY, default=discovery)] = bool
# Birth message is disabled if CONF_BIRTH_MESSAGE = {}
fields[

View File

@ -17,6 +17,8 @@ CONF_RETAIN = ATTR_RETAIN
CONF_STATE_TOPIC = "state_topic"
CONF_WILL_MESSAGE = "will_message"
DATA_MQTT_CONFIG = "mqtt_config"
DEFAULT_PREFIX = "homeassistant"
DEFAULT_BIRTH_WILL_TOPIC = DEFAULT_PREFIX + "/status"
DEFAULT_DISCOVERY = False

View File

@ -20,4 +20,5 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if entry and import_config.items() != entry.data.items():
self.hass.config_entries.async_update_entry(entry, data=import_config)
return self.async_abort(reason="already_configured")
self._abort_if_unique_id_configured()
return self.async_create_entry(title="RFXTRX", data=import_config)

View File

@ -3,6 +3,6 @@
"name": "Vera",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/vera",
"requirements": ["pyvera==0.3.9"],
"requirements": ["pyvera==0.3.10"],
"codeowners": ["@vangorra"]
}

View File

@ -8,8 +8,8 @@
"pyserial==3.4",
"zha-quirks==0.0.44",
"zigpy-cc==0.5.2",
"zigpy-deconz==0.9.2",
"zigpy==0.23.2",
"zigpy-deconz==0.10.0",
"zigpy==0.24.1",
"zigpy-xbee==0.13.0",
"zigpy-zigate==0.6.2",
"zigpy-znp==0.1.1"

View File

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 115
PATCH_VERSION = "1"
PATCH_VERSION = "2"
__short_version__ = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__ = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER = (3, 7, 1)

View File

@ -13,7 +13,7 @@ defusedxml==0.6.0
distro==1.5.0
emoji==0.5.4
hass-nabucasa==0.37.0
home-assistant-frontend==20200917.1
home-assistant-frontend==20200918.0
importlib-metadata==1.6.0;python_version<'3.8'
jinja2>=2.11.2
netdisco==2.8.2

View File

@ -717,7 +717,7 @@ ha-philipsjs==0.0.8
habitipy==0.2.0
# homeassistant.components.hangouts
hangups==0.4.10
hangups==0.4.11
# homeassistant.components.cloud
hass-nabucasa==0.37.0
@ -747,7 +747,7 @@ hole==0.5.1
holidays==0.10.3
# homeassistant.components.frontend
home-assistant-frontend==20200917.1
home-assistant-frontend==20200918.0
# homeassistant.components.zwave
homeassistant-pyozw==0.1.10
@ -1825,7 +1825,7 @@ pyuptimerobot==0.0.5
# pyuserinput==0.1.11
# homeassistant.components.vera
pyvera==0.3.9
pyvera==0.3.10
# homeassistant.components.versasense
pyversasense==0.0.6
@ -2302,7 +2302,7 @@ ziggo-mediabox-xl==1.1.0
zigpy-cc==0.5.2
# homeassistant.components.zha
zigpy-deconz==0.9.2
zigpy-deconz==0.10.0
# homeassistant.components.zha
zigpy-xbee==0.13.0
@ -2314,7 +2314,7 @@ zigpy-zigate==0.6.2
zigpy-znp==0.1.1
# homeassistant.components.zha
zigpy==0.23.2
zigpy==0.24.1
# homeassistant.components.zoneminder
zm-py==0.4.0

View File

@ -349,7 +349,7 @@ griddypower==0.1.0
ha-ffmpeg==2.0
# homeassistant.components.hangouts
hangups==0.4.10
hangups==0.4.11
# homeassistant.components.cloud
hass-nabucasa==0.37.0
@ -370,7 +370,7 @@ hole==0.5.1
holidays==0.10.3
# homeassistant.components.frontend
home-assistant-frontend==20200917.1
home-assistant-frontend==20200918.0
# homeassistant.components.zwave
homeassistant-pyozw==0.1.10
@ -854,7 +854,7 @@ pytraccar==0.9.0
pytradfri[async]==7.0.2
# homeassistant.components.vera
pyvera==0.3.9
pyvera==0.3.10
# homeassistant.components.vesync
pyvesync==1.1.0
@ -1062,7 +1062,7 @@ zha-quirks==0.0.44
zigpy-cc==0.5.2
# homeassistant.components.zha
zigpy-deconz==0.9.2
zigpy-deconz==0.10.0
# homeassistant.components.zha
zigpy-xbee==0.13.0
@ -1074,4 +1074,4 @@ zigpy-zigate==0.6.2
zigpy-znp==0.1.1
# homeassistant.components.zha
zigpy==0.23.2
zigpy==0.24.1

View File

@ -56,6 +56,16 @@ BROADLINK_DEVICES = {
20025,
5,
),
"Kitchen": ( # Not supported.
"192.168.0.64",
"34ea34b61d2c",
"LB1",
"Broadlink",
"SmartBulb",
0x504E,
57,
5,
),
}

View File

@ -12,13 +12,16 @@ from . import get_device
from tests.async_mock import call, patch
DEVICE_DISCOVERY = "homeassistant.components.broadlink.config_flow.blk.discover"
DEVICE_FACTORY = "homeassistant.components.broadlink.config_flow.blk.gendevice"
@pytest.fixture(autouse=True)
def broadlink_setup_fixture():
"""Mock broadlink entry setup."""
with patch(
"homeassistant.components.broadlink.async_setup_entry", return_value=True
):
"homeassistant.components.broadlink.async_setup", return_value=True
), patch("homeassistant.components.broadlink.async_setup_entry", return_value=True):
yield
@ -38,7 +41,7 @@ async def test_flow_user_works(hass):
assert result["step_id"] == "user"
assert result["errors"] == {}
with patch("broadlink.discover", return_value=[mock_api]) as mock_discover:
with patch(DEVICE_DISCOVERY, return_value=[mock_api]) as mock_discover:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -69,7 +72,7 @@ async def test_flow_user_already_in_progress(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[device.get_mock_api()]):
with patch(DEVICE_DISCOVERY, return_value=[device.get_mock_api()]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -79,7 +82,7 @@ async def test_flow_user_already_in_progress(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[device.get_mock_api()]):
with patch(DEVICE_DISCOVERY, return_value=[device.get_mock_api()]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -106,7 +109,7 @@ async def test_flow_user_mac_already_configured(hass):
device.timeout = 20
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -125,7 +128,7 @@ async def test_flow_user_invalid_ip_address(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", side_effect=OSError(errno.EINVAL, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(errno.EINVAL, None)):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "0.0.0.1"},
@ -142,7 +145,7 @@ async def test_flow_user_invalid_hostname(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", side_effect=OSError(socket.EAI_NONAME, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(socket.EAI_NONAME, None)):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "pancakemaster.local"},
@ -161,7 +164,7 @@ async def test_flow_user_device_not_found(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[]):
with patch(DEVICE_DISCOVERY, return_value=[]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
@ -172,13 +175,32 @@ async def test_flow_user_device_not_found(hass):
assert result["errors"] == {"base": "cannot_connect"}
async def test_flow_user_device_not_supported(hass):
"""Test we handle a device not supported in the user step."""
device = get_device("Kitchen")
mock_api = device.get_mock_api()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
)
assert result["type"] == "abort"
assert result["reason"] == "not_supported"
async def test_flow_user_network_unreachable(hass):
"""Test we handle a network unreachable in the user step."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", side_effect=OSError(errno.ENETUNREACH, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(errno.ENETUNREACH, None)):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "192.168.1.32"},
@ -195,7 +217,7 @@ async def test_flow_user_os_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", side_effect=OSError()):
with patch(DEVICE_DISCOVERY, side_effect=OSError()):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": "192.168.1.32"},
@ -216,7 +238,7 @@ async def test_flow_auth_authentication_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -237,7 +259,7 @@ async def test_flow_auth_device_offline(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
@ -258,7 +280,7 @@ async def test_flow_auth_firmware_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
@ -279,7 +301,7 @@ async def test_flow_auth_network_unreachable(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
@ -300,7 +322,7 @@ async def test_flow_auth_os_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host},
@ -321,13 +343,13 @@ async def test_flow_reset_works(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
)
with patch("broadlink.discover", return_value=[device.get_mock_api()]):
with patch(DEVICE_DISCOVERY, return_value=[device.get_mock_api()]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -353,7 +375,7 @@ async def test_flow_unlock_works(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -392,7 +414,7 @@ async def test_flow_unlock_device_offline(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -419,7 +441,7 @@ async def test_flow_unlock_firmware_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -446,7 +468,7 @@ async def test_flow_unlock_network_unreachable(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -473,7 +495,7 @@ async def test_flow_unlock_os_error(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -499,7 +521,7 @@ async def test_flow_do_not_unlock(hass):
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -527,7 +549,7 @@ async def test_flow_import_works(hass):
device = get_device("Living Room")
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]) as mock_discover:
with patch(DEVICE_DISCOVERY, return_value=[mock_api]) as mock_discover:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -558,12 +580,12 @@ async def test_flow_import_already_in_progress(hass):
device = get_device("Living Room")
data = {"host": device.host}
with patch("broadlink.discover", return_value=[device.get_mock_api()]):
with patch(DEVICE_DISCOVERY, return_value=[device.get_mock_api()]):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=data
)
with patch("broadlink.discover", return_value=[device.get_mock_api()]):
with patch(DEVICE_DISCOVERY, return_value=[device.get_mock_api()]):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=data
)
@ -579,7 +601,7 @@ async def test_flow_import_host_already_configured(hass):
mock_entry.add_to_hass(hass)
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -602,7 +624,7 @@ async def test_flow_import_mac_already_configured(hass):
device.host = "192.168.1.16"
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]):
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -620,7 +642,7 @@ async def test_flow_import_mac_already_configured(hass):
async def test_flow_import_device_not_found(hass):
"""Test we handle a device not found in the import step."""
with patch("broadlink.discover", return_value=[]):
with patch(DEVICE_DISCOVERY, return_value=[]):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -631,9 +653,25 @@ async def test_flow_import_device_not_found(hass):
assert result["reason"] == "cannot_connect"
async def test_flow_import_device_not_supported(hass):
"""Test we handle a device not supported in the import step."""
device = get_device("Kitchen")
mock_api = device.get_mock_api()
with patch(DEVICE_DISCOVERY, return_value=[mock_api]):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={"host": device.host},
)
assert result["type"] == "abort"
assert result["reason"] == "not_supported"
async def test_flow_import_invalid_ip_address(hass):
"""Test we handle an invalid IP address in the import step."""
with patch("broadlink.discover", side_effect=OSError(errno.EINVAL, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(errno.EINVAL, None)):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -646,7 +684,7 @@ async def test_flow_import_invalid_ip_address(hass):
async def test_flow_import_invalid_hostname(hass):
"""Test we handle an invalid hostname in the import step."""
with patch("broadlink.discover", side_effect=OSError(socket.EAI_NONAME, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(socket.EAI_NONAME, None)):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -659,7 +697,7 @@ async def test_flow_import_invalid_hostname(hass):
async def test_flow_import_network_unreachable(hass):
"""Test we handle a network unreachable in the import step."""
with patch("broadlink.discover", side_effect=OSError(errno.ENETUNREACH, None)):
with patch(DEVICE_DISCOVERY, side_effect=OSError(errno.ENETUNREACH, None)):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -672,7 +710,7 @@ async def test_flow_import_network_unreachable(hass):
async def test_flow_import_os_error(hass):
"""Test we handle an OS error in the import step."""
with patch("broadlink.discover", side_effect=OSError()):
with patch(DEVICE_DISCOVERY, side_effect=OSError()):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
@ -692,7 +730,7 @@ async def test_flow_reauth_works(hass):
mock_api.auth.side_effect = blke.AuthenticationError()
data = {"name": device.name, **device.get_entry_data()}
with patch("broadlink.gendevice", return_value=mock_api):
with patch(DEVICE_FACTORY, return_value=mock_api):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "reauth"}, data=data
)
@ -702,7 +740,7 @@ async def test_flow_reauth_works(hass):
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]) as mock_discover:
with patch(DEVICE_DISCOVERY, return_value=[mock_api]) as mock_discover:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -728,7 +766,7 @@ async def test_flow_reauth_invalid_host(hass):
mock_api.auth.side_effect = blke.AuthenticationError()
data = {"name": device.name, **device.get_entry_data()}
with patch("broadlink.gendevice", return_value=mock_api):
with patch(DEVICE_FACTORY, return_value=mock_api):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "reauth"}, data=data
)
@ -736,7 +774,7 @@ async def test_flow_reauth_invalid_host(hass):
device.mac = get_device("Office").mac
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]) as mock_discover:
with patch(DEVICE_DISCOVERY, return_value=[mock_api]) as mock_discover:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},
@ -762,7 +800,7 @@ async def test_flow_reauth_valid_host(hass):
mock_api.auth.side_effect = blke.AuthenticationError()
data = {"name": device.name, **device.get_entry_data()}
with patch("broadlink.gendevice", return_value=mock_api):
with patch(DEVICE_FACTORY, return_value=mock_api):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "reauth"}, data=data
)
@ -770,7 +808,7 @@ async def test_flow_reauth_valid_host(hass):
device.host = "192.168.1.128"
mock_api = device.get_mock_api()
with patch("broadlink.discover", return_value=[mock_api]) as mock_discover:
with patch(DEVICE_DISCOVERY, return_value=[mock_api]) as mock_discover:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{"host": device.host, "timeout": device.timeout},