"""Test repairs handling for Shelly.""" from unittest.mock import Mock from aioshelly.exceptions import DeviceConnectionError, RpcCallError import pytest from homeassistant.components.shelly.const import ( BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID, CONF_BLE_SCANNER_MODE, DOMAIN, BLEScannerMode, ) from homeassistant.core import HomeAssistant from homeassistant.helpers import issue_registry as ir from homeassistant.setup import async_setup_component from . import MOCK_MAC, init_integration from tests.components.repairs import ( async_process_repairs_platforms, process_repair_fix_flow, start_repair_fix_flow, ) from tests.typing import ClientSessionGenerator async def test_ble_scanner_unsupported_firmware_issue( hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_rpc_device: Mock, issue_registry: ir.IssueRegistry, ) -> None: """Test repair issues handling for BLE scanner with unsupported firmware.""" issue_id = BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID.format(unique=MOCK_MAC) assert await async_setup_component(hass, "repairs", {}) await hass.async_block_till_done() await init_integration( hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE} ) assert issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 1 await async_process_repairs_platforms(hass) client = await hass_client() result = await start_repair_fix_flow(client, DOMAIN, issue_id) flow_id = result["flow_id"] assert result["step_id"] == "confirm" result = await process_repair_fix_flow(client, flow_id) assert result["type"] == "create_entry" assert mock_rpc_device.trigger_ota_update.call_count == 1 # Assert the issue is no longer present assert not issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 0 async def test_unsupported_firmware_issue_update_not_available( hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_rpc_device: Mock, monkeypatch: pytest.MonkeyPatch, issue_registry: ir.IssueRegistry, ) -> None: """Test repair issues handling when firmware update is not available.""" issue_id = BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID.format(unique=MOCK_MAC) assert await async_setup_component(hass, "repairs", {}) await hass.async_block_till_done() await init_integration( hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE} ) assert issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 1 await async_process_repairs_platforms(hass) client = await hass_client() result = await start_repair_fix_flow(client, DOMAIN, issue_id) flow_id = result["flow_id"] assert result["step_id"] == "confirm" monkeypatch.setitem(mock_rpc_device.status, "sys", {"available_updates": {}}) result = await process_repair_fix_flow(client, flow_id) assert result["type"] == "abort" assert result["reason"] == "update_not_available" assert mock_rpc_device.trigger_ota_update.call_count == 0 assert issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 1 @pytest.mark.parametrize( "exception", [DeviceConnectionError, RpcCallError(999, "Unknown error")] ) async def test_unsupported_firmware_issue_exc( hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_rpc_device: Mock, issue_registry: ir.IssueRegistry, exception: Exception, ) -> None: """Test repair issues handling when OTA update ends with an exception.""" issue_id = BLE_SCANNER_FIRMWARE_UNSUPPORTED_ISSUE_ID.format(unique=MOCK_MAC) assert await async_setup_component(hass, "repairs", {}) await hass.async_block_till_done() await init_integration( hass, 2, options={CONF_BLE_SCANNER_MODE: BLEScannerMode.ACTIVE} ) assert issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 1 await async_process_repairs_platforms(hass) client = await hass_client() result = await start_repair_fix_flow(client, DOMAIN, issue_id) flow_id = result["flow_id"] assert result["step_id"] == "confirm" mock_rpc_device.trigger_ota_update.side_effect = exception result = await process_repair_fix_flow(client, flow_id) assert result["type"] == "abort" assert result["reason"] == "cannot_connect" assert mock_rpc_device.trigger_ota_update.call_count == 1 assert issue_registry.async_get_issue(DOMAIN, issue_id) assert len(issue_registry.issues) == 1