From 1f53d304f68e1f93707a1037ae68d55c25af0eb0 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 27 Jan 2025 13:54:01 -0500 Subject: [PATCH] Add OTBR unit tests --- .../components/otbr/homeassistant_hardware.py | 3 +- .../otbr/test_homeassistant_hardware.py | 159 ++++++++++++++++++ 2 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 tests/components/otbr/test_homeassistant_hardware.py diff --git a/homeassistant/components/otbr/homeassistant_hardware.py b/homeassistant/components/otbr/homeassistant_hardware.py index fe583057128..a597a01fed5 100644 --- a/homeassistant/components/otbr/homeassistant_hardware.py +++ b/homeassistant/components/otbr/homeassistant_hardware.py @@ -28,8 +28,7 @@ async def get_firmware_info( ) -> FirmwareInfo | None: """Return firmware information for the OpenThread Border Router.""" config_entry = cast(OTBRConfigEntry, config_entry) - device = config_entry.data["device"] - if device is None: + if (device := config_entry.data.get("device", None)) is None: return None owners: list[OwningIntegration | OwningAddon] = [ diff --git a/tests/components/otbr/test_homeassistant_hardware.py b/tests/components/otbr/test_homeassistant_hardware.py new file mode 100644 index 00000000000..458d3a3afd5 --- /dev/null +++ b/tests/components/otbr/test_homeassistant_hardware.py @@ -0,0 +1,159 @@ +"""Test Home Assistant Hardware platform for OTBR.""" + +from unittest.mock import AsyncMock, patch + +import voluptuous as vol + +from homeassistant.components.homeassistant_hardware.util import ( + ApplicationType, + FirmwareInfo, + OwningAddon, + OwningIntegration, +) +from homeassistant.components.otbr.homeassistant_hardware import get_firmware_info +from homeassistant.config_entries import ConfigEntryState +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError + +from tests.common import MockConfigEntry + +COPROCESSOR_VERSION = "OPENTHREAD/thread-reference-20200818-1740-g33cc75ed3; NRF52840; Jun 2 2022 14:25:49" + + +async def test_get_firmware_info(hass: HomeAssistant) -> None: + """Test `get_firmware_info`.""" + + otbr = MockConfigEntry( + domain="otbr", + unique_id="some_unique_id", + data={ + "device": "/dev/ttyUSB1", + "url": "http://openthread_border_router:8888", + }, + version=1, + minor_version=2, + ) + otbr.add_to_hass(hass) + otbr.mock_state(hass, ConfigEntryState.LOADED) + + otbr.runtime_data = AsyncMock() + otbr.runtime_data.get_coprocessor_version.return_value = COPROCESSOR_VERSION + + with ( + patch( + "homeassistant.components.otbr.homeassistant_hardware.is_hassio", + return_value=True, + ), + patch( + "homeassistant.components.otbr.homeassistant_hardware.valid_addon", + return_value=True, + ), + ): + fw_info = await get_firmware_info(hass, otbr) + + assert fw_info == FirmwareInfo( + device="/dev/ttyUSB1", + firmware_type=ApplicationType.SPINEL, + firmware_version=COPROCESSOR_VERSION, + source="otbr", + owners=[ + OwningIntegration(config_entry_id=otbr.entry_id), + OwningAddon(slug="openthread_border_router"), + ], + ) + + +async def test_get_firmware_info_ignored(hass: HomeAssistant) -> None: + """Test `get_firmware_info` with ignored entry.""" + + otbr = MockConfigEntry( + domain="otbr", + unique_id="some_unique_id", + data={}, + version=1, + minor_version=2, + ) + otbr.add_to_hass(hass) + + fw_info = await get_firmware_info(hass, otbr) + assert fw_info is None + + +async def test_get_firmware_info_bad_addon(hass: HomeAssistant) -> None: + """Test `get_firmware_info`.""" + + otbr = MockConfigEntry( + domain="otbr", + unique_id="some_unique_id", + data={ + "device": "/dev/ttyUSB1", + "url": "http://openthread_border_router:8888", + }, + version=1, + minor_version=2, + ) + otbr.add_to_hass(hass) + otbr.mock_state(hass, ConfigEntryState.LOADED) + + otbr.runtime_data = AsyncMock() + otbr.runtime_data.get_coprocessor_version.return_value = COPROCESSOR_VERSION + + with ( + patch( + "homeassistant.components.otbr.homeassistant_hardware.is_hassio", + return_value=True, + ), + patch( + "homeassistant.components.otbr.homeassistant_hardware.valid_addon", + side_effect=vol.Invalid("Bad addon name"), + ), + ): + fw_info = await get_firmware_info(hass, otbr) + + assert fw_info == FirmwareInfo( + device="/dev/ttyUSB1", + firmware_type=ApplicationType.SPINEL, + firmware_version=COPROCESSOR_VERSION, + source="otbr", + owners=[ + OwningIntegration(config_entry_id=otbr.entry_id), + ], + ) + + +async def test_get_firmware_info_no_coprocessor_version(hass: HomeAssistant) -> None: + """Test `get_firmware_info`.""" + + otbr = MockConfigEntry( + domain="otbr", + unique_id="some_unique_id", + data={ + "device": "/dev/ttyUSB1", + "url": "http://openthread_border_router:8888", + }, + version=1, + minor_version=2, + ) + otbr.add_to_hass(hass) + otbr.mock_state(hass, ConfigEntryState.LOADED) + + otbr.runtime_data = AsyncMock() + otbr.runtime_data.get_coprocessor_version.side_effect = HomeAssistantError() + + with ( + patch( + "homeassistant.components.otbr.homeassistant_hardware.is_hassio", + return_value=False, + ), + ): + fw_info = await get_firmware_info(hass, otbr) + + assert fw_info == FirmwareInfo( + device="/dev/ttyUSB1", + firmware_type=ApplicationType.SPINEL, + firmware_version=None, + source="otbr", + owners=[ + OwningIntegration(config_entry_id=otbr.entry_id), + ], + )