From cba289386256f51cbe1040241804a71638e9ee79 Mon Sep 17 00:00:00 2001
From: Maciej Bieniek <bieniu@users.noreply.github.com>
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,
+            )
-- 
GitLab