From 109b4d45ca721230cf52bc807a5b6013af5cce7e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 30 Apr 2022 14:17:18 -0500 Subject: [PATCH] Allow matching ssdp by manufacturerURL only (#71125) --- homeassistant/components/ssdp/__init__.py | 10 ++++- tests/components/ssdp/test_init.py | 54 +++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/ssdp/__init__.py b/homeassistant/components/ssdp/__init__.py index b59dc0ce1ee..8e8663a9734 100644 --- a/homeassistant/components/ssdp/__init__.py +++ b/homeassistant/components/ssdp/__init__.py @@ -45,6 +45,8 @@ ATTR_SSDP_SERVER = "ssdp_server" ATTR_SSDP_BOOTID = "BOOTID.UPNP.ORG" ATTR_SSDP_NEXTBOOTID = "NEXTBOOTID.UPNP.ORG" # Attributes for accessing info from retrieved UPnP device description +ATTR_ST = "st" +ATTR_NT = "nt" ATTR_UPNP_DEVICE_TYPE = "deviceType" ATTR_UPNP_FRIENDLY_NAME = "friendlyName" ATTR_UPNP_MANUFACTURER = "manufacturer" @@ -61,7 +63,13 @@ ATTR_UPNP_PRESENTATION_URL = "presentationURL" # Attributes for accessing info added by Home Assistant ATTR_HA_MATCHING_DOMAINS = "x_homeassistant_matching_domains" -PRIMARY_MATCH_KEYS = [ATTR_UPNP_MANUFACTURER, "st", ATTR_UPNP_DEVICE_TYPE, "nt"] +PRIMARY_MATCH_KEYS = [ + ATTR_UPNP_MANUFACTURER, + ATTR_ST, + ATTR_UPNP_DEVICE_TYPE, + ATTR_NT, + ATTR_UPNP_MANUFACTURER_URL, +] _LOGGER = logging.getLogger(__name__) diff --git a/tests/components/ssdp/test_init.py b/tests/components/ssdp/test_init.py index b947ce4269a..5bbc90307b5 100644 --- a/tests/components/ssdp/test_init.py +++ b/tests/components/ssdp/test_init.py @@ -88,6 +88,60 @@ async def test_ssdp_flow_dispatched_on_st(mock_get_ssdp, hass, caplog, mock_flow # End compatibility checks +@patch( + "homeassistant.components.ssdp.async_get_ssdp", + return_value={"mock-domain": [{"manufacturerURL": "mock-url"}]}, +) +@pytest.mark.usefixtures("mock_get_source_ip") +async def test_ssdp_flow_dispatched_on_manufacturer_url( + mock_get_ssdp, hass, caplog, mock_flow_init +): + """Test matching based on manufacturerURL.""" + mock_ssdp_search_response = _ssdp_headers( + { + "st": "mock-st", + "manufacturerURL": "mock-url", + "location": "http://1.1.1.1", + "usn": "uuid:mock-udn::mock-st", + "server": "mock-server", + "ext": "", + } + ) + ssdp_listener = await init_ssdp_component(hass) + await ssdp_listener._on_search(mock_ssdp_search_response) + await hass.async_block_till_done() + hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) + await hass.async_block_till_done() + + assert len(mock_flow_init.mock_calls) == 1 + assert mock_flow_init.mock_calls[0][1][0] == "mock-domain" + assert mock_flow_init.mock_calls[0][2]["context"] == { + "source": config_entries.SOURCE_SSDP + } + mock_call_data: ssdp.SsdpServiceInfo = mock_flow_init.mock_calls[0][2]["data"] + assert mock_call_data.ssdp_st == "mock-st" + assert mock_call_data.ssdp_location == "http://1.1.1.1" + assert mock_call_data.ssdp_usn == "uuid:mock-udn::mock-st" + assert mock_call_data.ssdp_server == "mock-server" + assert mock_call_data.ssdp_ext == "" + assert mock_call_data.ssdp_udn == ANY + assert mock_call_data.ssdp_headers["_timestamp"] == ANY + assert mock_call_data.x_homeassistant_matching_domains == {"mock-domain"} + assert mock_call_data.upnp == {ssdp.ATTR_UPNP_UDN: "uuid:mock-udn"} + assert "Failed to fetch ssdp data" not in caplog.text + # Compatibility with old dict access (to be removed after 2022.6) + assert mock_call_data[ssdp.ATTR_SSDP_ST] == "mock-st" + assert mock_call_data[ssdp.ATTR_SSDP_LOCATION] == "http://1.1.1.1" + assert mock_call_data[ssdp.ATTR_SSDP_USN] == "uuid:mock-udn::mock-st" + assert mock_call_data[ssdp.ATTR_SSDP_SERVER] == "mock-server" + assert mock_call_data[ssdp.ATTR_SSDP_EXT] == "" + assert mock_call_data[ssdp.ATTR_UPNP_UDN] == "uuid:mock-udn" + assert mock_call_data[ssdp.ATTR_SSDP_UDN] == ANY + assert mock_call_data["_timestamp"] == ANY + assert mock_call_data[ssdp.ATTR_HA_MATCHING_DOMAINS] == {"mock-domain"} + # End compatibility checks + + @pytest.mark.usefixtures("mock_get_source_ip") @patch( "homeassistant.components.ssdp.async_get_ssdp",