"""Nice G.O. switch tests.""" from unittest.mock import AsyncMock from aiohttp import ClientError from nice_go import ApiError, AuthFailedError import pytest from homeassistant.components.switch import ( DOMAIN as SWITCH_DOMAIN, SERVICE_TURN_OFF, SERVICE_TURN_ON, ) from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from . import setup_integration from tests.common import MockConfigEntry async def test_turn_on( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry ) -> None: """Test turn on switch.""" await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "switch.test_garage_1_vacation_mode"}, blocking=True, ) mock_nice_go.vacation_mode_on.assert_called_once_with("1") async def test_turn_off( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry ) -> None: """Test turn off switch.""" await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "switch.test_garage_2_vacation_mode"}, blocking=True, ) mock_nice_go.vacation_mode_off.assert_called_once_with("2") @pytest.mark.parametrize( ("action", "error", "entity_id", "expected_error"), [ ( SERVICE_TURN_OFF, ApiError, "switch.test_garage_1_vacation_mode", "Error while turning off the switch", ), ( SERVICE_TURN_ON, ClientError, "switch.test_garage_2_vacation_mode", "Error while turning on the switch", ), ], ) async def test_error( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry, action: str, error: Exception, entity_id: str, expected_error: str, ) -> None: """Test that errors are handled appropriately.""" await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) mock_nice_go.vacation_mode_on.side_effect = error mock_nice_go.vacation_mode_off.side_effect = error with pytest.raises(HomeAssistantError, match=expected_error): await hass.services.async_call( SWITCH_DOMAIN, action, {ATTR_ENTITY_ID: entity_id}, blocking=True, ) async def test_auth_failed_error( hass: HomeAssistant, mock_nice_go: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test that if an auth failed error occurs, the integration attempts a token refresh and a retry before throwing an error.""" await setup_integration(hass, mock_config_entry, [Platform.SWITCH]) def _on_side_effect(*args, **kwargs): if mock_nice_go.vacation_mode_on.call_count <= 3: raise AuthFailedError if mock_nice_go.vacation_mode_on.call_count == 5: raise AuthFailedError if mock_nice_go.vacation_mode_on.call_count == 6: raise ApiError def _off_side_effect(*args, **kwargs): if mock_nice_go.vacation_mode_off.call_count <= 3: raise AuthFailedError if mock_nice_go.vacation_mode_off.call_count == 4: raise ApiError mock_nice_go.vacation_mode_on.side_effect = _on_side_effect mock_nice_go.vacation_mode_off.side_effect = _off_side_effect with pytest.raises(HomeAssistantError, match="Error while turning on the switch"): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "switch.test_garage_1_vacation_mode"}, blocking=True, ) assert mock_nice_go.authenticate.call_count == 1 assert mock_nice_go.vacation_mode_on.call_count == 2 with pytest.raises(HomeAssistantError, match="Error while turning off the switch"): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "switch.test_garage_2_vacation_mode"}, blocking=True, ) assert mock_nice_go.authenticate.call_count == 2 assert mock_nice_go.vacation_mode_off.call_count == 2 # Try again, but this time the auth failed error should not be raised await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "switch.test_garage_1_vacation_mode"}, blocking=True, ) assert mock_nice_go.authenticate.call_count == 3 assert mock_nice_go.vacation_mode_on.call_count == 4 # One more time but with an ApiError instead of AuthFailed with pytest.raises(HomeAssistantError, match="Error while turning on the switch"): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: "switch.test_garage_1_vacation_mode"}, blocking=True, ) with pytest.raises(HomeAssistantError, match="Error while turning off the switch"): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: "switch.test_garage_2_vacation_mode"}, blocking=True, ) assert mock_nice_go.authenticate.call_count == 5 assert mock_nice_go.vacation_mode_on.call_count == 6 assert mock_nice_go.vacation_mode_off.call_count == 4