From 1eb8035122c170beb0d144980b5688e35ab54984 Mon Sep 17 00:00:00 2001 From: Felipe Martins Diel <41558831+felipediel@users.noreply.github.com> Date: Fri, 18 Sep 2020 10:29:26 -0300 Subject: [PATCH] Handle an unsupported device in the Broadlink config flow (#40242) --- .../components/broadlink/config_flow.py | 16 ++++++++- .../components/broadlink/strings.json | 1 + .../components/broadlink/translations/en.json | 1 + tests/components/broadlink/__init__.py | 10 ++++++ .../components/broadlink/test_config_flow.py | 35 +++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/broadlink/config_flow.py b/homeassistant/components/broadlink/config_flow.py index 284a9bffe19..4dfc80c6fe9 100644 --- a/homeassistant/components/broadlink/config_flow.py +++ b/homeassistant/components/broadlink/config_flow.py @@ -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 ) diff --git a/homeassistant/components/broadlink/strings.json b/homeassistant/components/broadlink/strings.json index 44cb1801ede..d17c639469a 100644 --- a/homeassistant/components/broadlink/strings.json +++ b/homeassistant/components/broadlink/strings.json @@ -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": { diff --git a/homeassistant/components/broadlink/translations/en.json b/homeassistant/components/broadlink/translations/en.json index fa3feb88008..bd8dfd0c403 100644 --- a/homeassistant/components/broadlink/translations/en.json +++ b/homeassistant/components/broadlink/translations/en.json @@ -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": { diff --git a/tests/components/broadlink/__init__.py b/tests/components/broadlink/__init__.py index 95a2ef97c6f..86756c922f1 100644 --- a/tests/components/broadlink/__init__.py +++ b/tests/components/broadlink/__init__.py @@ -56,6 +56,16 @@ BROADLINK_DEVICES = { 20025, 5, ), + "Kitchen": ( # Not supported. + "192.168.0.64", + "34ea34b61d2c", + "LB1", + "Broadlink", + "SmartBulb", + 0x504E, + 57, + 5, + ), } diff --git a/tests/components/broadlink/test_config_flow.py b/tests/components/broadlink/test_config_flow.py index 4089c551ff5..920ff8be1a6 100644 --- a/tests/components/broadlink/test_config_flow.py +++ b/tests/components/broadlink/test_config_flow.py @@ -172,6 +172,25 @@ 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( @@ -631,6 +650,22 @@ 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)):