"""Tests for the SwitchBot Cloud integration init.""" from unittest.mock import patch import pytest from switchbot_api import ( Device, PowerState, Remote, SwitchBotAuthenticationError, SwitchBotConnectionError, ) from homeassistant.components.switchbot_cloud import SwitchBotAPI from homeassistant.config_entries import ConfigEntryState from homeassistant.const import CONF_WEBHOOK_ID, EVENT_HOMEASSISTANT_START from homeassistant.core import HomeAssistant from homeassistant.core_config import async_process_ha_core_config from . import configure_integration from tests.typing import ClientSessionGenerator @pytest.fixture def mock_list_devices(): """Mock list_devices.""" with patch.object(SwitchBotAPI, "list_devices") as mock_list_devices: yield mock_list_devices @pytest.fixture def mock_get_status(): """Mock get_status.""" with patch.object(SwitchBotAPI, "get_status") as mock_get_status: yield mock_get_status @pytest.fixture def mock_get_webook_configuration(): """Mock get_status.""" with patch.object( SwitchBotAPI, "get_webook_configuration" ) as mock_get_webook_configuration: yield mock_get_webook_configuration @pytest.fixture def mock_delete_webhook(): """Mock get_status.""" with patch.object(SwitchBotAPI, "delete_webhook") as mock_delete_webhook: yield mock_delete_webhook @pytest.fixture def mock_setup_webhook(): """Mock get_status.""" with patch.object(SwitchBotAPI, "setup_webhook") as mock_setup_webhook: yield mock_setup_webhook async def test_setup_entry_success( hass: HomeAssistant, mock_list_devices, mock_get_status, mock_get_webook_configuration, mock_delete_webhook, mock_setup_webhook, ) -> None: """Test successful setup of entry.""" await async_process_ha_core_config( hass, {"external_url": "https://example.com"}, ) mock_get_webook_configuration.return_value = {"urls": ["https://example.com"]} mock_list_devices.return_value = [ Remote( version="V1.0", deviceId="air-conditonner-id-1", deviceName="air-conditonner-name-1", remoteType="Air Conditioner", hubDeviceId="test-hub-id", ), Device( version="V1.0", deviceId="plug-id-1", deviceName="plug-name-1", deviceType="Plug", hubDeviceId="test-hub-id", ), Remote( version="V1.0", deviceId="plug-id-2", deviceName="plug-name-2", remoteType="DIY Plug", hubDeviceId="test-hub-id", ), Remote( version="V1.0", deviceId="meter-pro-1", deviceName="meter-pro-name-1", deviceType="MeterPro(CO2)", hubDeviceId="test-hub-id", ), Remote( version="V1.0", deviceId="hub2-1", deviceName="hub2-name-1", deviceType="Hub 2", hubDeviceId="test-hub-id", ), Device( deviceId="vacuum-1", deviceName="vacuum-name-1", deviceType="K10+", hubDeviceId=None, ), ] mock_get_status.return_value = {"power": PowerState.ON.value} entry = await configure_integration(hass) assert entry.state is ConfigEntryState.LOADED hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() mock_list_devices.assert_called_once() mock_get_status.assert_called() mock_get_webook_configuration.assert_called_once() mock_delete_webhook.assert_called_once() mock_setup_webhook.assert_called_once() @pytest.mark.parametrize( ("error", "state"), [ (SwitchBotAuthenticationError, ConfigEntryState.SETUP_ERROR), (SwitchBotConnectionError, ConfigEntryState.SETUP_RETRY), ], ) async def test_setup_entry_fails_when_listing_devices( hass: HomeAssistant, error: Exception, state: ConfigEntryState, mock_list_devices, mock_get_status, ) -> None: """Test error handling when list_devices in setup of entry.""" mock_list_devices.side_effect = error entry = await configure_integration(hass) assert entry.state == state hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() mock_list_devices.assert_called_once() mock_get_status.assert_not_called() async def test_setup_entry_fails_when_refreshing( hass: HomeAssistant, mock_list_devices, mock_get_status ) -> None: """Test error handling in get_status in setup of entry.""" mock_list_devices.return_value = [ Device( version="V1.0", deviceId="test-id", deviceName="test-name", deviceType="Plug", hubDeviceId="test-hub-id", ) ] mock_get_status.side_effect = SwitchBotConnectionError entry = await configure_integration(hass) assert entry.state is ConfigEntryState.SETUP_RETRY hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() mock_list_devices.assert_called_once() mock_get_status.assert_called() async def test_posting_to_webhook( hass: HomeAssistant, mock_list_devices, mock_get_status, mock_get_webook_configuration, mock_delete_webhook, mock_setup_webhook, hass_client_no_auth: ClientSessionGenerator, ) -> None: """Test handler webhook call.""" await async_process_ha_core_config( hass, {"external_url": "https://example.com"}, ) mock_get_webook_configuration.return_value = {"urls": ["https://example.com"]} mock_list_devices.return_value = [ Device( deviceId="vacuum-1", deviceName="vacuum-name-1", deviceType="K10+", hubDeviceId=None, ), ] mock_get_status.return_value = {"power": PowerState.ON.value} mock_delete_webhook.return_value = {} mock_setup_webhook.return_value = {} entry = await configure_integration(hass) assert entry.state is ConfigEntryState.LOADED hass.bus.async_fire(EVENT_HOMEASSISTANT_START) webhook_id = entry.data[CONF_WEBHOOK_ID] client = await hass_client_no_auth() # fire webhook await client.post( f"/api/webhook/{webhook_id}", json={ "eventType": "changeReport", "eventVersion": "1", "context": {"deviceType": "...", "deviceMac": "vacuum-1"}, }, ) await hass.async_block_till_done() mock_setup_webhook.assert_called_once()