Add diagnostics to LinkPlay (#126768)
parent
0468e7e7a3
commit
784ad20fb6
|
@ -0,0 +1,17 @@
|
|||
"""Diagnostics support for Linkplay."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import LinkPlayConfigEntry
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: LinkPlayConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
data = entry.runtime_data
|
||||
return {"device_info": data.bridge.to_dict()}
|
|
@ -1 +1,16 @@
|
|||
"""Tests for the LinkPlay integration."""
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_integration(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Fixture for setting up the component."""
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
"""Test configuration and mocks for LinkPlay component."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Generator, Iterator
|
||||
from contextlib import contextmanager
|
||||
from typing import Any
|
||||
from unittest import mock
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from linkplay.bridge import LinkPlayBridge, LinkPlayDevice
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.linkplay.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST, EVENT_HOMEASSISTANT_CLOSE
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
from tests.conftest import AiohttpClientMocker
|
||||
|
||||
HOST = "10.0.0.150"
|
||||
HOST_REENTRY = "10.0.0.66"
|
||||
UUID = "FF31F09E-5001-FBDE-0546-2DBFFF31F09E"
|
||||
|
@ -24,15 +34,15 @@ def mock_linkplay_factory_bridge() -> Generator[AsyncMock]:
|
|||
),
|
||||
patch(
|
||||
"homeassistant.components.linkplay.config_flow.linkplay_factory_httpapi_bridge",
|
||||
) as factory,
|
||||
) as conf_factory,
|
||||
):
|
||||
bridge = AsyncMock(spec=LinkPlayBridge)
|
||||
bridge.endpoint = HOST
|
||||
bridge.device = AsyncMock(spec=LinkPlayDevice)
|
||||
bridge.device.uuid = UUID
|
||||
bridge.device.name = NAME
|
||||
factory.return_value = bridge
|
||||
yield factory
|
||||
conf_factory.return_value = bridge
|
||||
yield conf_factory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -43,3 +53,55 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
|||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Mock a config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title=NAME,
|
||||
data={CONF_HOST: HOST},
|
||||
unique_id=UUID,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_player_ex(
|
||||
mock_player_ex: AsyncMock,
|
||||
) -> AsyncMock:
|
||||
"""Mock a update_status of the LinkPlayPlayer."""
|
||||
mock_player_ex.return_value = load_fixture("getPlayerEx.json", DOMAIN)
|
||||
return mock_player_ex
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_status_ex(
|
||||
mock_status_ex: AsyncMock,
|
||||
) -> AsyncMock:
|
||||
"""Mock a update_status of the LinkPlayDevice."""
|
||||
mock_status_ex.return_value = load_fixture("getStatusEx.json", DOMAIN)
|
||||
return mock_status_ex
|
||||
|
||||
|
||||
@contextmanager
|
||||
def mock_lp_aiohttp_client() -> Iterator[AiohttpClientMocker]:
|
||||
"""Context manager to mock aiohttp client."""
|
||||
mocker = AiohttpClientMocker()
|
||||
|
||||
def create_session(hass: HomeAssistant, *args: Any, **kwargs: Any) -> ClientSession:
|
||||
session = mocker.create_session(hass.loop)
|
||||
|
||||
async def close_session(event):
|
||||
"""Close session."""
|
||||
await session.close()
|
||||
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, close_session)
|
||||
|
||||
return session
|
||||
|
||||
with mock.patch(
|
||||
"homeassistant.components.linkplay.async_get_client_session",
|
||||
side_effect=create_session,
|
||||
):
|
||||
yield mocker
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"type": "0",
|
||||
"ch": "0",
|
||||
"mode": "0",
|
||||
"loop": "0",
|
||||
"eq": "0",
|
||||
"status": "stop",
|
||||
"curpos": "0",
|
||||
"offset_pts": "0",
|
||||
"totlen": "0",
|
||||
"Title": "",
|
||||
"Artist": "",
|
||||
"Album": "",
|
||||
"alarmflag": "0",
|
||||
"plicount": "0",
|
||||
"plicurr": "0",
|
||||
"vol": "80",
|
||||
"mute": "0"
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"uuid": "FF31F09E5001FBDE05462DBFFF31F09E",
|
||||
"DeviceName": "Smart Zone 1_54B9",
|
||||
"GroupName": "Smart Zone 1_54B9",
|
||||
"ssid": "Smart Zone 1_54B9",
|
||||
"language": "en_us",
|
||||
"firmware": "4.6.415145",
|
||||
"hardware": "A31",
|
||||
"build": "release",
|
||||
"project": "SMART_ZONE4_AMP",
|
||||
"priv_prj": "SMART_ZONE4_AMP",
|
||||
"project_build_name": "a31rakoit",
|
||||
"Release": "20220427",
|
||||
"temp_uuid": "97296CE38DE8CC3D",
|
||||
"hideSSID": "1",
|
||||
"SSIDStrategy": "2",
|
||||
"branch": "A31_stable_4.6",
|
||||
"group": "0",
|
||||
"wmrm_version": "4.2",
|
||||
"internet": "1",
|
||||
"MAC": "00:22:6C:21:7F:1D",
|
||||
"STA_MAC": "00:00:00:00:00:00",
|
||||
"CountryCode": "CN",
|
||||
"CountryRegion": "1",
|
||||
"netstat": "0",
|
||||
"essid": "",
|
||||
"apcli0": "",
|
||||
"eth2": "192.168.168.197",
|
||||
"ra0": "10.10.10.254",
|
||||
"eth_dhcp": "1",
|
||||
"VersionUpdate": "0",
|
||||
"NewVer": "0",
|
||||
"set_dns_enable": "1",
|
||||
"mcu_ver": "37",
|
||||
"mcu_ver_new": "0",
|
||||
"dsp_ver": "0",
|
||||
"dsp_ver_new": "0",
|
||||
"date": "2024:10:29",
|
||||
"time": "17:13:22",
|
||||
"tz": "1.0000",
|
||||
"dst_enable": "1",
|
||||
"region": "unknown",
|
||||
"prompt_status": "1",
|
||||
"iot_ver": "1.0.0",
|
||||
"upnp_version": "1005",
|
||||
"cap1": "0x305200",
|
||||
"capability": "0x28e90b80",
|
||||
"languages": "0x6",
|
||||
"streams_all": "0x7bff7ffe",
|
||||
"streams": "0x7b9831fe",
|
||||
"external": "0x0",
|
||||
"plm_support": "0x40152",
|
||||
"preset_key": "10",
|
||||
"spotify_active": "0",
|
||||
"lbc_support": "0",
|
||||
"privacy_mode": "0",
|
||||
"WifiChannel": "11",
|
||||
"RSSI": "0",
|
||||
"BSSID": "",
|
||||
"battery": "0",
|
||||
"battery_percent": "0",
|
||||
"securemode": "1",
|
||||
"auth": "WPAPSKWPA2PSK",
|
||||
"encry": "AES",
|
||||
"upnp_uuid": "uuid:FF31F09E-5001-FBDE-0546-2DBFFF31F09E",
|
||||
"uart_pass_port": "8899",
|
||||
"communication_port": "8819",
|
||||
"web_firmware_update_hide": "0",
|
||||
"ignore_talkstart": "0",
|
||||
"web_login_result": "-1",
|
||||
"silenceOTATime": "",
|
||||
"ignore_silenceOTATime": "1",
|
||||
"new_tunein_preset_and_alarm": "1",
|
||||
"iheartradio_new": "1",
|
||||
"new_iheart_podcast": "1",
|
||||
"tidal_version": "2.0",
|
||||
"service_version": "1.0",
|
||||
"ETH_MAC": "00:22:6C:21:7F:20",
|
||||
"security": "https/2.0",
|
||||
"security_version": "2.0"
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
# serializer version: 1
|
||||
# name: test_diagnostics
|
||||
dict({
|
||||
'device_info': dict({
|
||||
'device': dict({
|
||||
'properties': dict({
|
||||
'BSSID': '',
|
||||
'CountryCode': 'CN',
|
||||
'CountryRegion': '1',
|
||||
'DeviceName': 'Smart Zone 1_54B9',
|
||||
'ETH_MAC': '00:22:6C:21:7F:20',
|
||||
'GroupName': 'Smart Zone 1_54B9',
|
||||
'MAC': '00:22:6C:21:7F:1D',
|
||||
'NewVer': '0',
|
||||
'RSSI': '0',
|
||||
'Release': '20220427',
|
||||
'SSIDStrategy': '2',
|
||||
'STA_MAC': '00:00:00:00:00:00',
|
||||
'VersionUpdate': '0',
|
||||
'WifiChannel': '11',
|
||||
'apcli0': '',
|
||||
'auth': 'WPAPSKWPA2PSK',
|
||||
'battery': '0',
|
||||
'battery_percent': '0',
|
||||
'branch': 'A31_stable_4.6',
|
||||
'build': 'release',
|
||||
'cap1': '0x305200',
|
||||
'capability': '0x28e90b80',
|
||||
'communication_port': '8819',
|
||||
'date': '2024:10:29',
|
||||
'dsp_ver': '0',
|
||||
'dsp_ver_new': '0',
|
||||
'dst_enable': '1',
|
||||
'encry': 'AES',
|
||||
'essid': '',
|
||||
'eth2': '192.168.168.197',
|
||||
'eth_dhcp': '1',
|
||||
'external': '0x0',
|
||||
'firmware': '4.6.415145',
|
||||
'group': '0',
|
||||
'hardware': 'A31',
|
||||
'hideSSID': '1',
|
||||
'ignore_silenceOTATime': '1',
|
||||
'ignore_talkstart': '0',
|
||||
'iheartradio_new': '1',
|
||||
'internet': '1',
|
||||
'iot_ver': '1.0.0',
|
||||
'language': 'en_us',
|
||||
'languages': '0x6',
|
||||
'lbc_support': '0',
|
||||
'mcu_ver': '37',
|
||||
'mcu_ver_new': '0',
|
||||
'netstat': '0',
|
||||
'new_iheart_podcast': '1',
|
||||
'new_tunein_preset_and_alarm': '1',
|
||||
'plm_support': '0x40152',
|
||||
'preset_key': '10',
|
||||
'priv_prj': 'SMART_ZONE4_AMP',
|
||||
'privacy_mode': '0',
|
||||
'project': 'SMART_ZONE4_AMP',
|
||||
'project_build_name': 'a31rakoit',
|
||||
'prompt_status': '1',
|
||||
'ra0': '10.10.10.254',
|
||||
'region': 'unknown',
|
||||
'securemode': '1',
|
||||
'security': 'https/2.0',
|
||||
'security_version': '2.0',
|
||||
'service_version': '1.0',
|
||||
'set_dns_enable': '1',
|
||||
'silenceOTATime': '',
|
||||
'spotify_active': '0',
|
||||
'ssid': 'Smart Zone 1_54B9',
|
||||
'streams': '0x7b9831fe',
|
||||
'streams_all': '0x7bff7ffe',
|
||||
'temp_uuid': '97296CE38DE8CC3D',
|
||||
'tidal_version': '2.0',
|
||||
'time': '17:13:22',
|
||||
'tz': '1.0000',
|
||||
'uart_pass_port': '8899',
|
||||
'upnp_uuid': 'uuid:FF31F09E-5001-FBDE-0546-2DBFFF31F09E',
|
||||
'upnp_version': '1005',
|
||||
'uuid': 'FF31F09E5001FBDE05462DBFFF31F09E',
|
||||
'web_firmware_update_hide': '0',
|
||||
'web_login_result': '-1',
|
||||
'wmrm_version': '4.2',
|
||||
}),
|
||||
}),
|
||||
'endpoint': dict({
|
||||
'endpoint': 'https://10.0.0.150',
|
||||
}),
|
||||
'multiroom': None,
|
||||
'player': dict({
|
||||
'properties': dict({
|
||||
'Album': '',
|
||||
'Artist': '',
|
||||
'Title': '',
|
||||
'alarmflag': '0',
|
||||
'ch': '0',
|
||||
'curpos': '0',
|
||||
'eq': '0',
|
||||
'loop': '0',
|
||||
'mode': '0',
|
||||
'mute': '0',
|
||||
'offset_pts': '0',
|
||||
'plicount': '0',
|
||||
'plicurr': '0',
|
||||
'status': 'stop',
|
||||
'totlen': '0',
|
||||
'type': '0',
|
||||
'vol': '80',
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
# ---
|
|
@ -0,0 +1,53 @@
|
|||
"""Tests for the LinkPlay diagnostics."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from linkplay.bridge import LinkPlayMultiroom
|
||||
from linkplay.consts import API_ENDPOINT
|
||||
from linkplay.endpoint import LinkPlayApiEndpoint
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.linkplay.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import setup_integration
|
||||
from .conftest import HOST, mock_lp_aiohttp_client
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
|
||||
async def test_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics."""
|
||||
|
||||
with (
|
||||
mock_lp_aiohttp_client() as mock_session,
|
||||
patch.object(LinkPlayMultiroom, "update_status", return_value=None),
|
||||
):
|
||||
endpoints = [
|
||||
LinkPlayApiEndpoint(protocol="https", endpoint=HOST, session=None),
|
||||
LinkPlayApiEndpoint(protocol="http", endpoint=HOST, session=None),
|
||||
]
|
||||
for endpoint in endpoints:
|
||||
mock_session.get(
|
||||
API_ENDPOINT.format(str(endpoint), "getPlayerStatusEx"),
|
||||
text=load_fixture("getPlayerEx.json", DOMAIN),
|
||||
)
|
||||
|
||||
mock_session.get(
|
||||
API_ENDPOINT.format(str(endpoint), "getStatusEx"),
|
||||
text=load_fixture("getStatusEx.json", DOMAIN),
|
||||
)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert (
|
||||
await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry)
|
||||
== snapshot
|
||||
)
|
Loading…
Reference in New Issue