diff --git a/homeassistant/components/upnp/config_flow.py b/homeassistant/components/upnp/config_flow.py index 8afd3465f07..a85e47c5919 100644 --- a/homeassistant/components/upnp/config_flow.py +++ b/homeassistant/components/upnp/config_flow.py @@ -134,6 +134,14 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """ _LOGGER.debug("async_step_ssdp: discovery_info: %s", discovery_info) + # Ensure complete discovery. + if ( + ssdp.ATTR_UPNP_UDN not in discovery_info + or ssdp.ATTR_SSDP_ST not in discovery_info + ): + _LOGGER.debug("Incomplete discovery, ignoring") + return self.async_abort(reason="incomplete_discovery") + # Ensure not already configuring/configured. udn = discovery_info[ssdp.ATTR_UPNP_UDN] st = discovery_info[ssdp.ATTR_SSDP_ST] # pylint: disable=invalid-name @@ -218,6 +226,7 @@ class UpnpOptionsFlowHandler(config_entries.OptionsFlow): CONFIG_ENTRY_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL ) update_interval = timedelta(seconds=update_interval_sec) + _LOGGER.debug("Updating coordinator, update_interval: %s", update_interval) coordinator.update_interval = update_interval return self.async_create_entry(title="", data=user_input) diff --git a/homeassistant/components/upnp/strings.json b/homeassistant/components/upnp/strings.json index 8936d2ec791..99e58698f2e 100644 --- a/homeassistant/components/upnp/strings.json +++ b/homeassistant/components/upnp/strings.json @@ -17,7 +17,8 @@ "abort": { "already_configured": "UPnP/IGD is already configured", "no_devices_discovered": "No UPnP/IGDs discovered", - "no_devices_found": "No UPnP/IGD devices found on the network." + "no_devices_found": "No UPnP/IGD devices found on the network.", + "incomplete_discovery": "Incomplete discovery" } } } diff --git a/tests/components/upnp/test_config_flow.py b/tests/components/upnp/test_config_flow.py index c0f5b6b4ff2..870aa13fc41 100644 --- a/tests/components/upnp/test_config_flow.py +++ b/tests/components/upnp/test_config_flow.py @@ -65,6 +65,34 @@ async def test_flow_ssdp_discovery(hass: HomeAssistantType): } +async def test_flow_ssdp_discovery_incomplete(hass: HomeAssistantType): + """Test config flow: incomplete discovery through ssdp.""" + udn = "uuid:device_1" + mock_device = MockDevice(udn) + discovery_infos = [ + { + DISCOVERY_ST: mock_device.device_type, + DISCOVERY_UDN: mock_device.udn, + DISCOVERY_LOCATION: "dummy", + } + ] + with patch.object( + Device, "async_create_device", AsyncMock(return_value=mock_device) + ), patch.object(Device, "async_discover", AsyncMock(return_value=discovery_infos)): + # Discovered via step ssdp. + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": config_entries.SOURCE_SSDP}, + data={ + ssdp.ATTR_SSDP_ST: mock_device.device_type, + # ssdp.ATTR_UPNP_UDN: mock_device.udn, # Not provided. + "friendlyName": mock_device.name, + }, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "incomplete_discovery" + + async def test_flow_user(hass: HomeAssistantType): """Test config flow: discovered + configured through user.""" udn = "uuid:device_1"