From c9e8a3a8870f8c7fc3a05bc482469825533f95d3 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Mon, 6 Nov 2023 23:43:56 +0100 Subject: [PATCH] Fix invalid MAC in samsungtv (#103512) * Fix invalid MAC in samsungtv * Also adjust __init__ --- .../components/samsungtv/__init__.py | 4 +- .../components/samsungtv/config_flow.py | 5 +- .../components/samsungtv/test_config_flow.py | 62 ++++++++++++++++--- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/samsungtv/__init__.py b/homeassistant/components/samsungtv/__init__.py index b7d400ce831..2ced868ada7 100644 --- a/homeassistant/components/samsungtv/__init__.py +++ b/homeassistant/components/samsungtv/__init__.py @@ -211,7 +211,9 @@ async def _async_create_bridge_with_updated_data( partial(getmac.get_mac_address, ip=host) ) - if mac: + if mac and mac != "none": + # Samsung sometimes returns a value of "none" for the mac address + # this should be ignored LOGGER.info("Updated mac to %s for %s", mac, host) updated_data[CONF_MAC] = mac else: diff --git a/homeassistant/components/samsungtv/config_flow.py b/homeassistant/components/samsungtv/config_flow.py index 124dab73004..f20a79cc9e6 100644 --- a/homeassistant/components/samsungtv/config_flow.py +++ b/homeassistant/components/samsungtv/config_flow.py @@ -219,7 +219,10 @@ class SamsungTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self._title = f"{self._name} ({self._model})" self._udn = _strip_uuid(dev_info.get("udn", info["id"])) if mac := mac_from_device_info(info): - self._mac = mac + # Samsung sometimes returns a value of "none" for the mac address + # this should be ignored - but also shouldn't trigger getmac + if mac != "none": + self._mac = mac elif mac := await self.hass.async_add_executor_job( partial(getmac.get_mac_address, ip=self._host) ): diff --git a/tests/components/samsungtv/test_config_flow.py b/tests/components/samsungtv/test_config_flow.py index a70a0042fcd..0eacd63b42d 100644 --- a/tests/components/samsungtv/test_config_flow.py +++ b/tests/components/samsungtv/test_config_flow.py @@ -1,4 +1,5 @@ """Tests for Samsung TV config flow.""" +from copy import deepcopy from ipaddress import ip_address from unittest.mock import ANY, AsyncMock, Mock, call, patch @@ -165,14 +166,6 @@ MOCK_DEVICE_INFO = { }, "id": "123", } -MOCK_DEVICE_INFO_2 = { - "device": { - "type": "Samsung SmartTV", - "name": "fake2_name", - "modelName": "fake2_model", - }, - "id": "345", -} AUTODETECT_LEGACY = { "name": "HomeAssistant", @@ -1968,3 +1961,56 @@ async def test_no_update_incorrect_udn_not_matching_mac_from_dhcp( assert result["step_id"] == "confirm" assert entry.data[CONF_MAC] == "aa:bb:ss:ss:dd:pp" assert entry.unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de" + + +@pytest.mark.usefixtures("remotews", "remoteencws_failing") +async def test_ssdp_update_mac(hass: HomeAssistant) -> None: + """Ensure that MAC address is correctly updated from SSDP.""" + with patch( + "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info", + return_value=MOCK_DEVICE_INFO, + ): + # entry was added + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_USER_DATA + ) + assert result["type"] == FlowResultType.CREATE_ENTRY + entry = result["result"] + assert entry.data[CONF_MANUFACTURER] == DEFAULT_MANUFACTURER + assert entry.data[CONF_MODEL] == "fake_model" + assert entry.data[CONF_MAC] is None + assert entry.unique_id == "123" + + device_info = deepcopy(MOCK_DEVICE_INFO) + device_info["device"]["wifiMac"] = "none" + with patch( + "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info", + return_value=device_info, + ): + # Updated + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA + ) + assert result["type"] == FlowResultType.ABORT + assert result["reason"] == RESULT_ALREADY_CONFIGURED + + # ensure mac wasn't updated with "none" + assert entry.data[CONF_MAC] is None + assert entry.unique_id == "123" + + device_info = deepcopy(MOCK_DEVICE_INFO) + device_info["device"]["wifiMac"] = "aa:bb:cc:dd:ee:ff" + with patch( + "homeassistant.components.samsungtv.bridge.SamsungTVWSBridge.async_device_info", + return_value=device_info, + ): + # Updated + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_SSDP}, data=MOCK_SSDP_DATA + ) + assert result["type"] == FlowResultType.ABORT + assert result["reason"] == RESULT_ALREADY_CONFIGURED + + # ensure mac was updated with new wifiMac value + assert entry.data[CONF_MAC] == "aa:bb:cc:dd:ee:ff" + assert entry.unique_id == "123"