mirror of
https://github.com/home-assistant/core.git
synced 2025-08-04 05:05:09 +02:00
WIP: Begin fixing unit tests
This commit is contained in:
@@ -19,7 +19,6 @@ from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
get_otbr_addon_manager,
|
||||
get_zigbee_flasher_addon_manager,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry, ConfigFlowResult, OptionsFlow
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@@ -62,6 +61,18 @@ class FakeFirmwareConfigFlow(BaseFirmwareConfigFlow, domain=TEST_DOMAIN):
|
||||
|
||||
return await self.async_step_confirm()
|
||||
|
||||
async def async_step_install_zigbee_firmware(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Install Zigbee firmware."""
|
||||
return await self.async_step_confirm_zigbee()
|
||||
|
||||
async def async_step_install_thread_firmware(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Install Thread firmware."""
|
||||
return await self.async_step_start_otbr_addon()
|
||||
|
||||
def _async_flow_finished(self) -> ConfigFlowResult:
|
||||
"""Create the config entry."""
|
||||
assert self._device is not None
|
||||
@@ -160,29 +171,8 @@ def mock_addon_info(
|
||||
update_available=False,
|
||||
version=None,
|
||||
),
|
||||
flasher_addon_info: AddonInfo = AddonInfo(
|
||||
available=True,
|
||||
hostname=None,
|
||||
options={},
|
||||
state=AddonState.NOT_INSTALLED,
|
||||
update_available=False,
|
||||
version=None,
|
||||
),
|
||||
) -> Iterator[tuple[Mock, Mock]]:
|
||||
"""Mock the main addon states for the config flow."""
|
||||
mock_flasher_manager = Mock(spec_set=get_zigbee_flasher_addon_manager(hass))
|
||||
mock_flasher_manager.addon_name = "Silicon Labs Flasher"
|
||||
mock_flasher_manager.async_start_addon_waiting = AsyncMock(
|
||||
side_effect=delayed_side_effect()
|
||||
)
|
||||
mock_flasher_manager.async_install_addon_waiting = AsyncMock(
|
||||
side_effect=delayed_side_effect()
|
||||
)
|
||||
mock_flasher_manager.async_uninstall_addon_waiting = AsyncMock(
|
||||
side_effect=delayed_side_effect()
|
||||
)
|
||||
mock_flasher_manager.async_get_addon_info.return_value = flasher_addon_info
|
||||
|
||||
mock_otbr_manager = Mock(spec_set=get_otbr_addon_manager(hass))
|
||||
mock_otbr_manager.addon_name = "OpenThread Border Router"
|
||||
mock_otbr_manager.async_install_addon_waiting = AsyncMock(
|
||||
@@ -216,10 +206,6 @@ def mock_addon_info(
|
||||
"homeassistant.components.homeassistant_hardware.util.get_otbr_addon_manager",
|
||||
return_value=mock_otbr_manager,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.firmware_config_flow.get_zigbee_flasher_addon_manager",
|
||||
return_value=mock_flasher_manager,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.firmware_config_flow.is_hassio",
|
||||
return_value=is_hassio,
|
||||
@@ -233,7 +219,7 @@ def mock_addon_info(
|
||||
return_value=firmware_info_result,
|
||||
),
|
||||
):
|
||||
yield mock_otbr_manager, mock_flasher_manager
|
||||
yield mock_otbr_manager
|
||||
|
||||
|
||||
async def test_config_flow_zigbee(hass: HomeAssistant) -> None:
|
||||
@@ -248,7 +234,7 @@ async def test_config_flow_zigbee(hass: HomeAssistant) -> None:
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option: we are now installing the addon
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@@ -266,16 +252,6 @@ async def test_config_flow_zigbee(hass: HomeAssistant) -> None:
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "run_zigbee_flasher_addon"
|
||||
assert result["progress_action"] == "run_zigbee_flasher_addon"
|
||||
assert mock_flasher_manager.async_set_addon_options.mock_calls == [
|
||||
call(
|
||||
{
|
||||
"device": TEST_DEVICE,
|
||||
"baudrate": 115200,
|
||||
"bootloader_baudrate": 115200,
|
||||
"flow_control": True,
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
@@ -287,9 +263,6 @@ async def test_config_flow_zigbee(hass: HomeAssistant) -> None:
|
||||
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
# We are finally done with the addon
|
||||
assert mock_flasher_manager.async_uninstall_addon_waiting.mock_calls == [call()]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "confirm_zigbee"
|
||||
@@ -344,7 +317,7 @@ async def test_config_flow_zigbee_skip_step_if_installed(hass: HomeAssistant) ->
|
||||
update_available=False,
|
||||
version="1.2.3",
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option: we skip installation, instead we directly run it
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@@ -419,7 +392,7 @@ async def test_config_flow_thread(hass: HomeAssistant) -> None:
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@@ -507,7 +480,7 @@ async def test_config_flow_thread_addon_already_installed(hass: HomeAssistant) -
|
||||
update_available=False,
|
||||
version=None,
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@@ -555,7 +528,7 @@ async def test_config_flow_zigbee_not_hassio(hass: HomeAssistant) -> None:
|
||||
hass,
|
||||
is_hassio=False,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"next_step_id": STEP_PICK_FIRMWARE_ZIGBEE},
|
||||
@@ -604,7 +577,7 @@ async def test_options_flow_zigbee_to_thread(hass: HomeAssistant) -> None:
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# First step is confirmation
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
@@ -703,7 +676,7 @@ async def test_options_flow_thread_to_zigbee(hass: HomeAssistant) -> None:
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option: we are now installing the addon
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
|
@@ -54,7 +54,7 @@ async def test_config_flow_cannot_probe_firmware(
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=None,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Start the flow
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
TEST_DOMAIN, context={"source": "hardware"}
|
||||
@@ -85,7 +85,7 @@ async def test_config_flow_zigbee_not_hassio_wrong_firmware(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
is_hassio=False,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -121,7 +121,7 @@ async def test_config_flow_zigbee_flasher_addon_already_running(
|
||||
update_available=False,
|
||||
version="1.0.0",
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -157,7 +157,7 @@ async def test_config_flow_zigbee_flasher_addon_info_fails(hass: HomeAssistant)
|
||||
update_available=False,
|
||||
version="1.0.0",
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_flasher_manager.async_get_addon_info.side_effect = AddonError()
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@@ -188,7 +188,7 @@ async def test_config_flow_zigbee_flasher_addon_install_fails(
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_flasher_manager.async_install_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -222,7 +222,7 @@ async def test_config_flow_zigbee_flasher_addon_set_config_fails(
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_flasher_manager.async_install_addon_waiting = AsyncMock(
|
||||
side_effect=delayed_side_effect()
|
||||
)
|
||||
@@ -258,7 +258,7 @@ async def test_config_flow_zigbee_flasher_run_fails(hass: HomeAssistant) -> None
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_flasher_manager.async_start_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -287,7 +287,7 @@ async def test_config_flow_zigbee_flasher_uninstall_fails(hass: HomeAssistant) -
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.SPINEL,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_flasher_manager.async_uninstall_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -326,7 +326,7 @@ async def test_config_flow_zigbee_confirmation_fails(hass: HomeAssistant) -> Non
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
# Pick the menu option: we are now installing the addon
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@@ -338,7 +338,7 @@ async def test_config_flow_zigbee_confirmation_fails(hass: HomeAssistant) -> Non
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=None, # Probing fails
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -360,7 +360,7 @@ async def test_config_flow_thread_not_hassio(hass: HomeAssistant) -> None:
|
||||
hass,
|
||||
is_hassio=False,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -386,7 +386,7 @@ async def test_config_flow_thread_addon_info_fails(hass: HomeAssistant) -> None:
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_get_addon_info.side_effect = AddonError()
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
@@ -422,7 +422,7 @@ async def test_config_flow_thread_addon_already_running(hass: HomeAssistant) ->
|
||||
update_available=False,
|
||||
version="1.0.0",
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_install_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -453,7 +453,7 @@ async def test_config_flow_thread_addon_install_fails(hass: HomeAssistant) -> No
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_install_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -484,7 +484,7 @@ async def test_config_flow_thread_addon_set_config_fails(hass: HomeAssistant) ->
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_set_addon_options = AsyncMock(side_effect=AddonError())
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@@ -515,7 +515,7 @@ async def test_config_flow_thread_flasher_run_fails(hass: HomeAssistant) -> None
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_start_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -543,7 +543,7 @@ async def test_config_flow_thread_flasher_uninstall_fails(hass: HomeAssistant) -
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
mock_otbr_manager.async_uninstall_addon_waiting = AsyncMock(
|
||||
side_effect=AddonError()
|
||||
)
|
||||
@@ -580,7 +580,7 @@ async def test_config_flow_thread_confirmation_fails(hass: HomeAssistant) -> Non
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=ApplicationType.EZSP,
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -601,7 +601,7 @@ async def test_config_flow_thread_confirmation_fails(hass: HomeAssistant) -> Non
|
||||
with mock_addon_info(
|
||||
hass,
|
||||
app_type=None, # Probing fails
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
@@ -694,7 +694,7 @@ async def test_options_flow_thread_to_zigbee_otbr_configured(
|
||||
update_available=False,
|
||||
version="1.0.0",
|
||||
),
|
||||
) as (mock_otbr_manager, mock_flasher_manager):
|
||||
) as mock_otbr_manager:
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={"next_step_id": STEP_PICK_FIRMWARE_ZIGBEE},
|
||||
|
@@ -6,7 +6,7 @@ import asyncio
|
||||
from collections.abc import AsyncGenerator
|
||||
import dataclasses
|
||||
import logging
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import aiohttp
|
||||
from ha_silabs_firmware_client import FirmwareManifest, FirmwareMetadata
|
||||
@@ -353,10 +353,14 @@ async def test_update_entity_installation(
|
||||
"https://example.org/release_notes"
|
||||
)
|
||||
|
||||
mock_firmware = Mock()
|
||||
mock_flasher = AsyncMock()
|
||||
|
||||
async def mock_flash_firmware(fw_image, progress_callback):
|
||||
async def mock_flash_firmware(
|
||||
hass: HomeAssistant,
|
||||
device: str,
|
||||
fw_data: bytes,
|
||||
expected_installed_firmware_type: ApplicationType,
|
||||
bootloader_reset_type: str | None = None,
|
||||
progress_callback: Callable[[int, int], None] | None = None,
|
||||
) -> FirmwareInfo:
|
||||
await asyncio.sleep(0)
|
||||
progress_callback(0, 100)
|
||||
await asyncio.sleep(0)
|
||||
@@ -364,31 +368,20 @@ async def test_update_entity_installation(
|
||||
await asyncio.sleep(0)
|
||||
progress_callback(100, 100)
|
||||
|
||||
mock_flasher.flash_firmware = mock_flash_firmware
|
||||
|
||||
# When we install it, the other integration is reloaded
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.parse_firmware_image",
|
||||
return_value=mock_firmware,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.Flasher",
|
||||
return_value=mock_flasher,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.probe_silabs_firmware_info",
|
||||
return_value=FirmwareInfo(
|
||||
return FirmwareInfo(
|
||||
device=TEST_DEVICE,
|
||||
firmware_type=ApplicationType.EZSP,
|
||||
firmware_version="7.4.4.0 build 0",
|
||||
owners=[],
|
||||
source="probe",
|
||||
)
|
||||
|
||||
# When we install it, the other integration is reloaded
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.async_flash_silabs_firmware",
|
||||
side_effect=mock_flash_firmware,
|
||||
),
|
||||
),
|
||||
patch.object(
|
||||
owning_config_entry, "async_unload", wraps=owning_config_entry.async_unload
|
||||
) as owning_config_entry_unload,
|
||||
):
|
||||
state_changes: list[Event[EventStateChangedData]] = async_capture_events(
|
||||
hass, EVENT_STATE_CHANGED
|
||||
@@ -421,9 +414,6 @@ async def test_update_entity_installation(
|
||||
assert state_changes[6].data["new_state"].attributes["update_percentage"] is None
|
||||
assert state_changes[6].data["new_state"].attributes["in_progress"] is False
|
||||
|
||||
# The owning integration was unloaded and is again running
|
||||
assert len(owning_config_entry_unload.mock_calls) == 1
|
||||
|
||||
# After the firmware update, the entity has the new version and the correct state
|
||||
state_after_install = hass.states.get(TEST_UPDATE_ENTITY_ID)
|
||||
assert state_after_install is not None
|
||||
@@ -454,19 +444,10 @@ async def test_update_entity_installation_failure(
|
||||
assert state_before_install.attributes["installed_version"] == "7.3.1.0"
|
||||
assert state_before_install.attributes["latest_version"] == "7.4.4.0"
|
||||
|
||||
mock_flasher = AsyncMock()
|
||||
mock_flasher.flash_firmware.side_effect = RuntimeError(
|
||||
"Something broke during flashing!"
|
||||
)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.parse_firmware_image",
|
||||
return_value=Mock(),
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.Flasher",
|
||||
return_value=mock_flasher,
|
||||
"homeassistant.components.homeassistant_hardware.update.async_flash_silabs_firmware",
|
||||
side_effect=HomeAssistantError("Failed to flash firmware"),
|
||||
),
|
||||
pytest.raises(HomeAssistantError, match="Failed to flash firmware"),
|
||||
):
|
||||
@@ -509,16 +490,10 @@ async def test_update_entity_installation_probe_failure(
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.parse_firmware_image",
|
||||
return_value=Mock(),
|
||||
"homeassistant.components.homeassistant_hardware.update.async_flash_silabs_firmware",
|
||||
side_effect=HomeAssistantError(
|
||||
"Failed to probe the firmware after flashing"
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.Flasher",
|
||||
return_value=AsyncMock(),
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_hardware.update.probe_silabs_firmware_info",
|
||||
return_value=None,
|
||||
),
|
||||
pytest.raises(
|
||||
HomeAssistantError, match="Failed to probe the firmware after flashing"
|
||||
|
Reference in New Issue
Block a user