Add NextDNS button platform (#74492)

* Add button platform

* Add button tests

* Fix typo

* Use Platform enum

* Fix coordinator type
This commit is contained in:
Maciej Bieniek 2022-07-06 16:29:53 +02:00 committed by GitHub
parent 47048e4df4
commit 41fd1a24bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 107 additions and 2 deletions

View File

@ -20,7 +20,7 @@ from nextdns import (
from nextdns.model import NextDnsData
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_API_KEY
from homeassistant.const import CONF_API_KEY, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -131,7 +131,7 @@ class NextDnsProtocolsUpdateCoordinator(NextDnsUpdateCoordinator):
_LOGGER = logging.getLogger(__name__)
PLATFORMS = ["sensor"]
PLATFORMS = [Platform.BUTTON, Platform.SENSOR]
COORDINATORS = [
(ATTR_DNSSEC, NextDnsDnssecUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),
(ATTR_ENCRYPTION, NextDnsEncryptionUpdateCoordinator, UPDATE_INTERVAL_ANALYTICS),

View File

@ -0,0 +1,58 @@
"""Support for the NextDNS service."""
from __future__ import annotations
from typing import cast
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import NextDnsStatusUpdateCoordinator
from .const import ATTR_STATUS, DOMAIN
PARALLEL_UPDATES = 1
CLEAR_LOGS_BUTTON = ButtonEntityDescription(
key="clear_logs",
name="{profile_name} Clear Logs",
entity_category=EntityCategory.CONFIG,
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Add aNextDNS entities from a config_entry."""
coordinator: NextDnsStatusUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
ATTR_STATUS
]
buttons: list[NextDnsButton] = []
buttons.append(NextDnsButton(coordinator, CLEAR_LOGS_BUTTON))
async_add_entities(buttons)
class NextDnsButton(CoordinatorEntity[NextDnsStatusUpdateCoordinator], ButtonEntity):
"""Define an NextDNS button."""
def __init__(
self,
coordinator: NextDnsStatusUpdateCoordinator,
description: ButtonEntityDescription,
) -> None:
"""Initialize."""
super().__init__(coordinator)
self._attr_device_info = coordinator.device_info
self._attr_unique_id = f"{coordinator.profile_id}_{description.key}"
self._attr_name = cast(str, description.name).format(
profile_name=coordinator.profile_name
)
self.entity_description = description
async def async_press(self) -> None:
"""Trigger cleaning logs."""
await self.coordinator.nextdns.clear_logs(self.coordinator.profile_id)

View File

@ -0,0 +1,47 @@
"""Test button of NextDNS integration."""
from unittest.mock import patch
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN
from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt as dt_util
from . import init_integration
async def test_button(hass):
"""Test states of the button."""
registry = er.async_get(hass)
await init_integration(hass)
state = hass.states.get("button.fake_profile_clear_logs")
assert state
assert state.state == STATE_UNKNOWN
entry = registry.async_get("button.fake_profile_clear_logs")
assert entry
assert entry.unique_id == "xyz12_clear_logs"
async def test_button_press(hass):
"""Test button press."""
await init_integration(hass)
now = dt_util.utcnow()
with patch(
"homeassistant.components.nextdns.NextDns.clear_logs"
) as mock_clear_logs, patch("homeassistant.core.dt_util.utcnow", return_value=now):
await hass.services.async_call(
BUTTON_DOMAIN,
"press",
{ATTR_ENTITY_ID: "button.fake_profile_clear_logs"},
blocking=True,
)
await hass.async_block_till_done()
mock_clear_logs.assert_called_once()
state = hass.states.get("button.fake_profile_clear_logs")
assert state
assert state.state == now.isoformat()