diff --git a/homeassistant/components/huawei_lte/config_flow.py b/homeassistant/components/huawei_lte/config_flow.py index d1ab0547801d2..2319cc9a3ed22 100644 --- a/homeassistant/components/huawei_lte/config_flow.py +++ b/homeassistant/components/huawei_lte/config_flow.py @@ -250,6 +250,24 @@ async def async_step_ssdp(self, discovery_info: ssdp.SsdpServiceInfo) -> FlowRes await self.async_set_unique_id(unique_id) self._abort_if_unique_id_configured(updates={CONF_URL: url}) + def _is_supported_device() -> bool: + """ + See if we are looking at a possibly supported device. + + Matching solely on SSDP data does not yield reliable enough results. + """ + try: + with Connection(url=url, timeout=CONNECTION_TIMEOUT) as conn: + basic_info = Client(conn).device.basic_information() + except ResponseErrorException: # API compatible error + return True + except Exception: # API incompatible error # pylint: disable=broad-except + return False + return isinstance(basic_info, dict) # Crude content check + + if not await self.hass.async_add_executor_job(_is_supported_device): + return self.async_abort(reason="unsupported_device") + self.context.update( { "title_placeholders": { diff --git a/homeassistant/components/huawei_lte/strings.json b/homeassistant/components/huawei_lte/strings.json index dbc30510d1338..3875433888d46 100644 --- a/homeassistant/components/huawei_lte/strings.json +++ b/homeassistant/components/huawei_lte/strings.json @@ -1,7 +1,8 @@ { "config": { "abort": { - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" + "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", + "unsupported_device": "Unsupported device" }, "error": { "connection_timeout": "Connection timeout", diff --git a/homeassistant/components/huawei_lte/translations/en.json b/homeassistant/components/huawei_lte/translations/en.json index 134a5372f71b0..42d28a2687161 100644 --- a/homeassistant/components/huawei_lte/translations/en.json +++ b/homeassistant/components/huawei_lte/translations/en.json @@ -1,8 +1,8 @@ { "config": { "abort": { - "not_huawei_lte": "Not a Huawei LTE device", - "reauth_successful": "Re-authentication was successful" + "reauth_successful": "Re-authentication was successful", + "unsupported_device": "Unsupported device" }, "error": { "connection_timeout": "Connection timeout", diff --git a/tests/components/huawei_lte/test_config_flow.py b/tests/components/huawei_lte/test_config_flow.py index d29c0554bcaa1..9e723204b331f 100644 --- a/tests/components/huawei_lte/test_config_flow.py +++ b/tests/components/huawei_lte/test_config_flow.py @@ -211,9 +211,14 @@ async def test_success(hass, login_requests_mock): @pytest.mark.parametrize( - ("upnp_data", "expected_result"), + ("requests_mock_request_kwargs", "upnp_data", "expected_result"), ( ( + { + "method": ANY, + "url": f"{FIXTURE_USER_INPUT[CONF_URL]}api/device/basic_information", + "text": "Mock device", + }, { ssdp.ATTR_UPNP_FRIENDLY_NAME: "Mobile Wi-Fi", ssdp.ATTR_UPNP_SERIAL: "00000000", @@ -225,6 +230,11 @@ async def test_success(hass, login_requests_mock): }, ), ( + { + "method": ANY, + "url": f"{FIXTURE_USER_INPUT[CONF_URL]}api/device/basic_information", + "text": "100002", + }, { ssdp.ATTR_UPNP_FRIENDLY_NAME: "Mobile Wi-Fi", # No ssdp.ATTR_UPNP_SERIAL @@ -235,19 +245,36 @@ async def test_success(hass, login_requests_mock): "errors": {}, }, ), + ( + { + "method": ANY, + "url": f"{FIXTURE_USER_INPUT[CONF_URL]}api/device/basic_information", + "exc": Exception("Something unexpected"), + }, + { + # Does not matter + }, + { + "type": data_entry_flow.FlowResultType.ABORT, + "reason": "unsupported_device", + }, + ), ), ) -async def test_ssdp(hass, upnp_data, expected_result): +async def test_ssdp( + hass, login_requests_mock, requests_mock_request_kwargs, upnp_data, expected_result +): """Test SSDP discovery initiates config properly.""" - url = "http://192.168.100.1/" + url = FIXTURE_USER_INPUT[CONF_URL][:-1] # strip trailing slash for appending port context = {"source": config_entries.SOURCE_SSDP} + login_requests_mock.request(**requests_mock_request_kwargs) result = await hass.config_entries.flow.async_init( DOMAIN, context=context, data=ssdp.SsdpServiceInfo( ssdp_usn="mock_usn", ssdp_st="upnp:rootdevice", - ssdp_location="http://192.168.100.1:60957/rootDesc.xml", + ssdp_location=f"{url}:60957/rootDesc.xml", upnp={ ssdp.ATTR_UPNP_DEVICE_TYPE: "urn:schemas-upnp-org:device:InternetGatewayDevice:1", ssdp.ATTR_UPNP_MANUFACTURER: "Huawei", @@ -264,7 +291,7 @@ async def test_ssdp(hass, upnp_data, expected_result): for k, v in expected_result.items(): assert result[k] == v if result.get("data_schema"): - result["data_schema"]({})[CONF_URL] == url + assert result["data_schema"]({})[CONF_URL] == url + "/" @pytest.mark.parametrize(