diff --git a/homeassistant/components/samsungtv/config_flow.py b/homeassistant/components/samsungtv/config_flow.py index debe7349b6c..e52123297ab 100644 --- a/homeassistant/components/samsungtv/config_flow.py +++ b/homeassistant/components/samsungtv/config_flow.py @@ -5,6 +5,7 @@ from urllib.parse import urlparse from samsungctl import Remote from samsungctl.exceptions import AccessDenied, UnhandledResponse import voluptuous as vol +from websocket import WebSocketException from homeassistant import config_entries from homeassistant.components.ssdp import ( @@ -23,7 +24,7 @@ from homeassistant.const import ( ) # pylint:disable=unused-import -from .const import CONF_MANUFACTURER, CONF_MODEL, DOMAIN, LOGGER, METHODS +from .const import CONF_MANUFACTURER, CONF_MODEL, DOMAIN, LOGGER DATA_SCHEMA = vol.Schema({vol.Required(CONF_HOST): str, vol.Required(CONF_NAME): str}) @@ -32,6 +33,12 @@ RESULT_SUCCESS = "success" RESULT_NOT_SUCCESSFUL = "not_successful" RESULT_NOT_SUPPORTED = "not_supported" +SUPPORTED_METHODS = ( + {"method": "websocket", "timeout": 1}, + # We need this high timeout because waiting for auth popup is just an open socket + {"method": "legacy", "timeout": 31}, +) + def _get_ip(host): if host is None: @@ -76,27 +83,25 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): def _try_connect(self): """Try to connect and check auth.""" - for method in METHODS: + for cfg in SUPPORTED_METHODS: config = { "name": "HomeAssistant", "description": "HomeAssistant", "id": "ha.component.samsung", "host": self._host, - "method": method, "port": self._port, - # We need this high timeout because waiting for auth popup is just an open socket - "timeout": 31, } + config.update(cfg) try: LOGGER.debug("Try config: %s", config) with Remote(config.copy()): LOGGER.debug("Working config: %s", config) - self._method = method + self._method = cfg["method"] return RESULT_SUCCESS except AccessDenied: LOGGER.debug("Working but denied config: %s", config) return RESULT_AUTH_MISSING - except UnhandledResponse: + except (UnhandledResponse, WebSocketException): LOGGER.debug("Working but unsupported config: %s", config) return RESULT_NOT_SUPPORTED except OSError as err: diff --git a/homeassistant/components/samsungtv/const.py b/homeassistant/components/samsungtv/const.py index ea893390a5b..46f6fb59a8c 100644 --- a/homeassistant/components/samsungtv/const.py +++ b/homeassistant/components/samsungtv/const.py @@ -9,5 +9,3 @@ DEFAULT_NAME = "Samsung TV" CONF_MANUFACTURER = "manufacturer" CONF_MODEL = "model" CONF_ON_ACTION = "turn_on_action" - -METHODS = ("websocket", "legacy") diff --git a/tests/components/samsungtv/test_config_flow.py b/tests/components/samsungtv/test_config_flow.py index 9c8ec3a9a09..91ee8a7205f 100644 --- a/tests/components/samsungtv/test_config_flow.py +++ b/tests/components/samsungtv/test_config_flow.py @@ -4,6 +4,7 @@ from unittest.mock import call, patch from asynctest import mock import pytest from samsungctl.exceptions import AccessDenied, UnhandledResponse +from websocket import WebSocketProtocolException from homeassistant.components.samsungtv.const import ( CONF_MANUFACTURER, @@ -42,7 +43,7 @@ AUTODETECT_WEBSOCKET = { "method": "websocket", "port": None, "host": "fake_host", - "timeout": 31, + "timeout": 1, } AUTODETECT_LEGACY = { "name": "HomeAssistant", @@ -245,6 +246,28 @@ async def test_ssdp_not_supported(hass): assert result["reason"] == "not_supported" +async def test_ssdp_not_supported_2(hass): + """Test starting a flow from discovery for not supported device.""" + with patch( + "homeassistant.components.samsungtv.config_flow.Remote", + side_effect=WebSocketProtocolException("Boom"), + ), patch("homeassistant.components.samsungtv.config_flow.socket"): + + # confirm to add the entry + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA + ) + assert result["type"] == "form" + assert result["step_id"] == "confirm" + + # device not supported + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input="whatever" + ) + assert result["type"] == "abort" + assert result["reason"] == "not_supported" + + async def test_ssdp_not_successful(hass): """Test starting a flow from discovery but no device found.""" with patch(