mirror of
https://github.com/home-assistant/core.git
synced 2025-06-25 01:21:51 +02:00
Add diagnostics to Twinkly (#100146)
This commit is contained in:
@ -1324,8 +1324,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/tuya/ @Tuya @zlinoliver @frenck
|
||||
/homeassistant/components/twentemilieu/ @frenck
|
||||
/tests/components/twentemilieu/ @frenck
|
||||
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221
|
||||
/tests/components/twinkly/ @dr1rrb @Robbie1221
|
||||
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221 @Olen
|
||||
/tests/components/twinkly/ @dr1rrb @Robbie1221 @Olen
|
||||
/homeassistant/components/twitch/ @joostlek
|
||||
/tests/components/twitch/ @joostlek
|
||||
/homeassistant/components/ukraine_alarm/ @PaulAnnekov
|
||||
|
40
homeassistant/components/twinkly/diagnostics.py
Normal file
40
homeassistant/components/twinkly/diagnostics.py
Normal file
@ -0,0 +1,40 @@
|
||||
"""Diagnostics support for Twinkly."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_IP_ADDRESS, CONF_MAC
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .const import DATA_DEVICE_INFO, DOMAIN
|
||||
|
||||
TO_REDACT = [CONF_HOST, CONF_IP_ADDRESS, CONF_MAC]
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a Twinkly config entry."""
|
||||
attributes = None
|
||||
state = None
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
LIGHT_DOMAIN, DOMAIN, str(entry.unique_id)
|
||||
)
|
||||
if entity_id:
|
||||
state = hass.states.get(entity_id)
|
||||
if state:
|
||||
attributes = state.attributes
|
||||
return async_redact_data(
|
||||
{
|
||||
"entry": entry.as_dict(),
|
||||
"device_info": hass.data[DOMAIN][entry.entry_id][DATA_DEVICE_INFO],
|
||||
"attributes": attributes,
|
||||
},
|
||||
TO_REDACT,
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "twinkly",
|
||||
"name": "Twinkly",
|
||||
"codeowners": ["@dr1rrb", "@Robbie1221"],
|
||||
"codeowners": ["@dr1rrb", "@Robbie1221", "@Olen"],
|
||||
"config_flow": true,
|
||||
"dhcp": [
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""Constants and mock for the twkinly component tests."""
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from aiohttp.client_exceptions import ClientConnectionError
|
||||
|
||||
@ -8,6 +7,7 @@ from homeassistant.components.twinkly.const import DEV_NAME
|
||||
|
||||
TEST_HOST = "test.twinkly.com"
|
||||
TEST_ID = "twinkly_test_device_id"
|
||||
TEST_UID = "4c8fccf5-e08a-4173-92d5-49bf479252a2"
|
||||
TEST_NAME = "twinkly_test_device_name"
|
||||
TEST_NAME_ORIGINAL = "twinkly_test_original_device_name" # the original (deprecated) name stored in the conf
|
||||
TEST_MODEL = "twinkly_test_device_model"
|
||||
@ -28,11 +28,12 @@ class ClientMock:
|
||||
self.mode = None
|
||||
self.version = "2.8.10"
|
||||
|
||||
self.id = str(uuid4())
|
||||
self.id = TEST_UID
|
||||
self.device_info = {
|
||||
"uuid": self.id,
|
||||
"device_name": self.id, # we make sure that entity id is different for each test
|
||||
"device_name": TEST_NAME,
|
||||
"product_code": TEST_MODEL,
|
||||
"sw_version": self.version,
|
||||
}
|
||||
|
||||
@property
|
||||
|
54
tests/components/twinkly/conftest.py
Normal file
54
tests/components/twinkly/conftest.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""Configure tests for the Twinkly integration."""
|
||||
from collections.abc import Awaitable, Callable, Coroutine
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from . import TEST_MODEL, TEST_NAME, TEST_UID, ClientMock
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
ComponentSetup = Callable[[], Awaitable[ClientMock]]
|
||||
|
||||
DOMAIN = "twinkly"
|
||||
TITLE = "Twinkly"
|
||||
|
||||
|
||||
@pytest.fixture(name="config_entry")
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Create Twinkly entry in Home Assistant."""
|
||||
client = ClientMock()
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title=TITLE,
|
||||
unique_id=TEST_UID,
|
||||
entry_id=TEST_UID,
|
||||
data={
|
||||
"host": client.host,
|
||||
"id": client.id,
|
||||
"name": TEST_NAME,
|
||||
"model": TEST_MODEL,
|
||||
"device_name": TEST_NAME,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="setup_integration")
|
||||
async def mock_setup_integration(
|
||||
hass: HomeAssistant, config_entry: MockConfigEntry
|
||||
) -> Callable[[], Coroutine[Any, Any, ClientMock]]:
|
||||
"""Fixture for setting up the component."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
async def func() -> ClientMock:
|
||||
mock = ClientMock()
|
||||
with patch("homeassistant.components.twinkly.Twinkly", return_value=mock):
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
return mock
|
||||
|
||||
return func
|
43
tests/components/twinkly/snapshots/test_diagnostics.ambr
Normal file
43
tests/components/twinkly/snapshots/test_diagnostics.ambr
Normal file
@ -0,0 +1,43 @@
|
||||
# serializer version: 1
|
||||
# name: test_diagnostics
|
||||
dict({
|
||||
'attributes': dict({
|
||||
'brightness': 26,
|
||||
'color_mode': 'brightness',
|
||||
'effect_list': list([
|
||||
]),
|
||||
'friendly_name': 'twinkly_test_device_name',
|
||||
'icon': 'mdi:string-lights',
|
||||
'supported_color_modes': list([
|
||||
'brightness',
|
||||
]),
|
||||
'supported_features': 4,
|
||||
}),
|
||||
'device_info': dict({
|
||||
'device_name': 'twinkly_test_device_name',
|
||||
'product_code': 'twinkly_test_device_model',
|
||||
'sw_version': '2.8.10',
|
||||
'uuid': '4c8fccf5-e08a-4173-92d5-49bf479252a2',
|
||||
}),
|
||||
'entry': dict({
|
||||
'data': dict({
|
||||
'device_name': 'twinkly_test_device_name',
|
||||
'host': '**REDACTED**',
|
||||
'id': '4c8fccf5-e08a-4173-92d5-49bf479252a2',
|
||||
'model': 'twinkly_test_device_model',
|
||||
'name': 'twinkly_test_device_name',
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'domain': 'twinkly',
|
||||
'entry_id': '4c8fccf5-e08a-4173-92d5-49bf479252a2',
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Twinkly',
|
||||
'unique_id': '4c8fccf5-e08a-4173-92d5-49bf479252a2',
|
||||
'version': 1,
|
||||
}),
|
||||
})
|
||||
# ---
|
@ -12,7 +12,7 @@ from homeassistant.components.twinkly.const import (
|
||||
from homeassistant.const import CONF_MODEL
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import TEST_MODEL, ClientMock
|
||||
from . import TEST_MODEL, TEST_NAME, ClientMock
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@ -60,11 +60,11 @@ async def test_success_flow(hass: HomeAssistant) -> None:
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == client.id
|
||||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
CONF_HOST: "dummy",
|
||||
CONF_ID: client.id,
|
||||
CONF_NAME: client.id,
|
||||
CONF_NAME: TEST_NAME,
|
||||
CONF_MODEL: TEST_MODEL,
|
||||
}
|
||||
|
||||
@ -113,11 +113,11 @@ async def test_dhcp_success(hass: HomeAssistant) -> None:
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == client.id
|
||||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
CONF_HOST: "1.2.3.4",
|
||||
CONF_ID: client.id,
|
||||
CONF_NAME: client.id,
|
||||
CONF_NAME: TEST_NAME,
|
||||
CONF_MODEL: TEST_MODEL,
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ async def test_dhcp_already_exists(hass: HomeAssistant) -> None:
|
||||
data={
|
||||
CONF_HOST: "1.2.3.4",
|
||||
CONF_ID: client.id,
|
||||
CONF_NAME: client.id,
|
||||
CONF_NAME: TEST_NAME,
|
||||
CONF_MODEL: TEST_MODEL,
|
||||
},
|
||||
unique_id=client.id,
|
||||
|
28
tests/components/twinkly/test_diagnostics.py
Normal file
28
tests/components/twinkly/test_diagnostics.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""Tests for the diagnostics of the twinkly component."""
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import ClientMock
|
||||
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
ComponentSetup = Callable[[], Awaitable[ClientMock]]
|
||||
|
||||
DOMAIN = "twinkly"
|
||||
|
||||
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
setup_integration: ComponentSetup,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics."""
|
||||
await setup_integration()
|
||||
entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
|
||||
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == snapshot
|
@ -16,7 +16,7 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
from homeassistant.helpers.entity_registry import RegistryEntry
|
||||
|
||||
from . import TEST_MODEL, TEST_NAME_ORIGINAL, ClientMock
|
||||
from . import TEST_MODEL, TEST_NAME, TEST_NAME_ORIGINAL, ClientMock
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@ -28,16 +28,16 @@ async def test_initial_state(hass: HomeAssistant) -> None:
|
||||
state = hass.states.get(entity.entity_id)
|
||||
|
||||
# Basic state properties
|
||||
assert state.name == entity.unique_id
|
||||
assert state.name == TEST_NAME
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_BRIGHTNESS] == 26
|
||||
assert state.attributes["friendly_name"] == entity.unique_id
|
||||
assert state.attributes["friendly_name"] == TEST_NAME
|
||||
assert state.attributes["icon"] == "mdi:string-lights"
|
||||
|
||||
assert entity.original_name == entity.unique_id
|
||||
assert entity.original_name == TEST_NAME
|
||||
assert entity.original_icon == "mdi:string-lights"
|
||||
|
||||
assert device.name == entity.unique_id
|
||||
assert device.name == TEST_NAME
|
||||
assert device.model == TEST_MODEL
|
||||
assert device.manufacturer == "LEDWORKS"
|
||||
|
||||
|
Reference in New Issue
Block a user