"""The tests for Netatmo switch.""" from datetime import timedelta from typing import Any from unittest.mock import AsyncMock, patch from freezegun.api import FrozenDateTimeFactory import pyatmo import pytest from syrupy.assertion import SnapshotAssertion from homeassistant.components.switch import ( DOMAIN as SWITCH_DOMAIN, SERVICE_TURN_OFF, SERVICE_TURN_ON, ) from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from .common import fake_post_request, selected_platforms, snapshot_platform_entities from tests.common import MockConfigEntry, async_fire_time_changed async def test_entity( hass: HomeAssistant, config_entry: MockConfigEntry, netatmo_auth: AsyncMock, snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, ) -> None: """Test entities.""" await snapshot_platform_entities( hass, config_entry, Platform.SWITCH, entity_registry, snapshot, ) async def test_switch_setup_and_services( hass: HomeAssistant, config_entry: MockConfigEntry, netatmo_auth: AsyncMock ) -> None: """Test setup and services.""" with selected_platforms([Platform.SWITCH]): assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() switch_entity = "switch.prise" assert hass.states.get(switch_entity).state == "on" # Test turning switch off with patch("pyatmo.home.Home.async_set_state") as mock_set_state: await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: switch_entity}, blocking=True, ) await hass.async_block_till_done() mock_set_state.assert_called_once_with( { "modules": [ { "id": "12:34:56:80:00:12:ac:f2", "on": False, "bridge": "12:34:56:80:60:40", } ] } ) # Test turning switch on with patch("pyatmo.home.Home.async_set_state") as mock_set_state: await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: switch_entity}, blocking=True, ) await hass.async_block_till_done() mock_set_state.assert_called_once_with( { "modules": [ { "id": "12:34:56:80:00:12:ac:f2", "on": True, "bridge": "12:34:56:80:60:40", } ] } ) @pytest.mark.parametrize( "error", [TimeoutError, pyatmo.ApiError], ids=["timeout", "api_error"], ) async def test_switch_unavailable_on_fetch_error( hass: HomeAssistant, config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, error: type[Exception], ) -> None: """Test the switch becomes unavailable when the data cannot be fetched.""" raise_error = False async def fake_post(*args: Any, **kwargs: Any): if raise_error: raise error return await fake_post_request(hass, *args, **kwargs) with ( patch( "homeassistant.components.netatmo.api.AsyncConfigEntryNetatmoAuth" ) as mock_auth, patch("homeassistant.components.netatmo.coordinator.PLATFORMS", ["switch"]), patch( "homeassistant.components.netatmo.async_get_config_entry_implementation", return_value=AsyncMock(), ), patch("homeassistant.components.netatmo.webhook.webhook_generate_url"), ): mock_auth.return_value.async_post_api_request.side_effect = fake_post mock_auth.return_value.async_addwebhook.side_effect = AsyncMock() mock_auth.return_value.async_dropwebhook.side_effect = AsyncMock() assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() switch_entity = "switch.prise" assert hass.states.get(switch_entity).state == "on" raise_error = True for _ in range(11): freezer.tick(timedelta(seconds=30)) async_fire_time_changed(hass) await hass.async_block_till_done(wait_background_tasks=True) assert hass.states.get(switch_entity).state == STATE_UNAVAILABLE