From cba289386256f51cbe1040241804a71638e9ee79 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Mon, 22 Aug 2022 07:08:57 +0200 Subject: [PATCH] Set quality scale to platinum in the NextDNS integration (#77099) * Set quality scale to platinum * Catch exceptions on when service calls * Add tests --- .../components/nextdns/manifest.json | 3 +- homeassistant/components/nextdns/switch.py | 36 ++++++++++++------- tests/components/nextdns/test_switch.py | 30 +++++++++++++++- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/nextdns/manifest.json b/homeassistant/components/nextdns/manifest.json index ee52aaaee75..04c2e3575f1 100644 --- a/homeassistant/components/nextdns/manifest.json +++ b/homeassistant/components/nextdns/manifest.json @@ -6,5 +6,6 @@ "requirements": ["nextdns==1.1.1"], "config_flow": true, "iot_class": "cloud_polling", - "loggers": ["nextdns"] + "loggers": ["nextdns"], + "quality_scale": "platinum" } diff --git a/homeassistant/components/nextdns/switch.py b/homeassistant/components/nextdns/switch.py index a353106723b..c0a0973a24c 100644 --- a/homeassistant/components/nextdns/switch.py +++ b/homeassistant/components/nextdns/switch.py @@ -1,15 +1,19 @@ """Support for the NextDNS service.""" from __future__ import annotations +import asyncio from collections.abc import Callable from dataclasses import dataclass from typing import Any, Generic -from nextdns import Settings +from aiohttp import ClientError +from aiohttp.client_exceptions import ClientConnectorError +from nextdns import ApiError, Settings from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -564,20 +568,28 @@ class NextDnsSwitch(CoordinatorEntity[NextDnsSettingsUpdateCoordinator], SwitchE async def async_turn_on(self, **kwargs: Any) -> None: """Turn on switch.""" - result = await self.coordinator.nextdns.set_setting( - self.coordinator.profile_id, self.entity_description.key, True - ) - - if result: - self._attr_is_on = True - self.async_write_ha_state() + await self.async_set_setting(True) async def async_turn_off(self, **kwargs: Any) -> None: """Turn off switch.""" - result = await self.coordinator.nextdns.set_setting( - self.coordinator.profile_id, self.entity_description.key, False - ) + await self.async_set_setting(False) + + async def async_set_setting(self, new_state: bool) -> None: + """Set the new state.""" + try: + result = await self.coordinator.nextdns.set_setting( + self.coordinator.profile_id, self.entity_description.key, new_state + ) + except ( + ApiError, + ClientConnectorError, + asyncio.TimeoutError, + ClientError, + ) as err: + raise HomeAssistantError( + f"NextDNS API returned an error calling set_setting for {self.entity_id}: {err}" + ) from err if result: - self._attr_is_on = False + self._attr_is_on = new_state self.async_write_ha_state() diff --git a/tests/components/nextdns/test_switch.py b/tests/components/nextdns/test_switch.py index cc873fcc4b7..72d504be574 100644 --- a/tests/components/nextdns/test_switch.py +++ b/tests/components/nextdns/test_switch.py @@ -1,8 +1,12 @@ """Test switch of NextDNS integration.""" +import asyncio from datetime import timedelta -from unittest.mock import patch +from unittest.mock import Mock, patch +from aiohttp import ClientError +from aiohttp.client_exceptions import ClientConnectorError from nextdns import ApiError +import pytest from homeassistant.components.nextdns.const import DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN @@ -15,6 +19,7 @@ from homeassistant.const import ( STATE_UNAVAILABLE, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from homeassistant.util.dt import utcnow @@ -977,3 +982,26 @@ async def test_availability(hass: HomeAssistant) -> None: assert state assert state.state != STATE_UNAVAILABLE assert state.state == STATE_ON + + +@pytest.mark.parametrize( + "exc", + [ + ApiError(Mock()), + asyncio.TimeoutError, + ClientConnectorError(Mock(), Mock()), + ClientError, + ], +) +async def test_switch_failure(hass: HomeAssistant, exc: Exception) -> None: + """Tests that the turn on/off service throws HomeAssistantError.""" + await init_integration(hass) + + with patch("homeassistant.components.nextdns.NextDns.set_setting", side_effect=exc): + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.fake_profile_block_page"}, + blocking=True, + )