Add diagnostics tests for Sonos (#146040)

* fix: add tests for diagnostics

* fix: add new files

* fix: add new files
This commit is contained in:
Pete Sage
2025-06-02 09:12:34 -04:00
committed by GitHub
parent 613728ad3b
commit e5f95b3aff
4 changed files with 255 additions and 2 deletions

View File

@ -130,11 +130,11 @@ async def async_generate_speaker_info(
value = getattr(speaker, attrib)
payload[attrib] = get_contents(value)
payload["enabled_entities"] = {
payload["enabled_entities"] = sorted(
entity_id
for entity_id, s in hass.data[DATA_SONOS].entity_id_mappings.items()
if s is speaker
}
)
payload["media"] = await async_generate_media_info(hass, speaker)
payload["activity_stats"] = speaker.activity_stats.report()
payload["event_stats"] = speaker.event_stats.report()

View File

@ -226,14 +226,22 @@ class SoCoMockFactory:
mock_soco.add_uri_to_queue = Mock(return_value=10)
mock_soco.avTransport = SonosMockService("AVTransport", ip_address)
mock_soco.avTransport.GetPositionInfo = Mock(
return_value=self.current_track_info
)
mock_soco.renderingControl = SonosMockService("RenderingControl", ip_address)
mock_soco.zoneGroupTopology = SonosMockService("ZoneGroupTopology", ip_address)
mock_soco.contentDirectory = SonosMockService("ContentDirectory", ip_address)
mock_soco.deviceProperties = SonosMockService("DeviceProperties", ip_address)
mock_soco.zone_group_state = Mock()
mock_soco.zone_group_state.processed_count = 10
mock_soco.zone_group_state.total_requests = 12
mock_soco.alarmClock = self.alarm_clock
mock_soco.get_battery_info.return_value = self.battery_info
mock_soco.all_zones = {mock_soco}
mock_soco.group.coordinator = mock_soco
mock_soco.household_id = "test_household_id"
self.mock_list[ip_address] = mock_soco
return mock_soco

View File

@ -0,0 +1,182 @@
# serializer version: 1
# name: test_diagnostics_config_entry
dict({
'discovered': dict({
'RINCON_test': dict({
'_group_members_missing': list([
]),
'_last_activity': -1200.0,
'_last_event_cache': dict({
}),
'activity_stats': dict({
}),
'available': True,
'battery_info': dict({
'Health': 'GREEN',
'Level': 100,
'PowerSource': 'SONOS_CHARGING_RING',
'Temperature': 'NORMAL',
}),
'enabled_entities': list([
'binary_sensor.zone_a_charging',
'binary_sensor.zone_a_microphone',
'media_player.zone_a',
'number.zone_a_audio_delay',
'number.zone_a_balance',
'number.zone_a_bass',
'number.zone_a_music_surround_level',
'number.zone_a_sub_gain',
'number.zone_a_surround_level',
'number.zone_a_treble',
'sensor.zone_a_audio_input_format',
'sensor.zone_a_battery',
'switch.sonos_alarm_14',
'switch.zone_a_crossfade',
'switch.zone_a_loudness',
'switch.zone_a_night_sound',
'switch.zone_a_speech_enhancement',
'switch.zone_a_subwoofer_enabled',
'switch.zone_a_surround_enabled',
'switch.zone_a_surround_music_full_volume',
]),
'event_stats': dict({
'soco:parse_event_xml': list([
0,
0,
128,
0,
]),
}),
'hardware_version': '1.20.1.6-1.1',
'household_id': 'test_household_id',
'is_coordinator': True,
'media': dict({
'album_name': None,
'artist': None,
'channel': None,
'current_track_poll': dict({
'album': '',
'album_art': '',
'artist': '',
'duration': 'NOT_IMPLEMENTED',
'duration_in_s': None,
'metadata': 'NOT_IMPLEMENTED',
'playlist_position': '1',
'position': 'NOT_IMPLEMENTED',
'position_in_s': None,
'title': '',
'uri': '',
}),
'duration': None,
'image_url': None,
'playlist_name': None,
'queue_position': None,
'source_name': None,
'title': None,
'uri': None,
}),
'model_name': 'Model Name',
'model_number': 'S12',
'software_version': '49.2-64250',
'subscription_address': '192.168.42.2:8080',
'subscriptions_failed': False,
'version': '13.1',
'zone_group_state_stats': dict({
'processed': 10,
'total_requests': 12,
}),
'zone_name': 'Zone A',
}),
}),
'discovery_known': list([
'RINCON_test',
]),
})
# ---
# name: test_diagnostics_device
dict({
'_group_members_missing': list([
]),
'_last_activity': -1200.0,
'_last_event_cache': dict({
}),
'activity_stats': dict({
}),
'available': True,
'battery_info': dict({
'Health': 'GREEN',
'Level': 100,
'PowerSource': 'SONOS_CHARGING_RING',
'Temperature': 'NORMAL',
}),
'enabled_entities': list([
'binary_sensor.zone_a_charging',
'binary_sensor.zone_a_microphone',
'media_player.zone_a',
'number.zone_a_audio_delay',
'number.zone_a_balance',
'number.zone_a_bass',
'number.zone_a_music_surround_level',
'number.zone_a_sub_gain',
'number.zone_a_surround_level',
'number.zone_a_treble',
'sensor.zone_a_audio_input_format',
'sensor.zone_a_battery',
'switch.sonos_alarm_14',
'switch.zone_a_crossfade',
'switch.zone_a_loudness',
'switch.zone_a_night_sound',
'switch.zone_a_speech_enhancement',
'switch.zone_a_subwoofer_enabled',
'switch.zone_a_surround_enabled',
'switch.zone_a_surround_music_full_volume',
]),
'event_stats': dict({
'soco:parse_event_xml': list([
0,
0,
128,
0,
]),
}),
'hardware_version': '1.20.1.6-1.1',
'household_id': 'test_household_id',
'is_coordinator': True,
'media': dict({
'album_name': None,
'artist': None,
'channel': None,
'current_track_poll': dict({
'album': '',
'album_art': '',
'artist': '',
'duration': 'NOT_IMPLEMENTED',
'duration_in_s': None,
'metadata': 'NOT_IMPLEMENTED',
'playlist_position': '1',
'position': 'NOT_IMPLEMENTED',
'position_in_s': None,
'title': '',
'uri': '',
}),
'duration': None,
'image_url': None,
'playlist_name': None,
'queue_position': None,
'source_name': None,
'title': None,
'uri': None,
}),
'model_name': 'Model Name',
'model_number': 'S12',
'software_version': '49.2-64250',
'subscription_address': '192.168.42.2:8080',
'subscriptions_failed': False,
'version': '13.1',
'zone_group_state_stats': dict({
'processed': 10,
'total_requests': 12,
}),
'zone_name': 'Zone A',
})
# ---

View File

@ -0,0 +1,63 @@
"""Tests for the diagnostics data provided by the Sonos integration."""
from syrupy.assertion import SnapshotAssertion
from syrupy.filters import paths
from homeassistant.components.sonos.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceRegistry
from tests.common import MockConfigEntry
from tests.components.diagnostics import (
get_diagnostics_for_config_entry,
get_diagnostics_for_device,
)
from tests.typing import ClientSessionGenerator
async def test_diagnostics_config_entry(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
async_autosetup_sonos,
config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test diagnostics for config entry."""
result = await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
# Exclude items that are timing dependent.
assert result == snapshot(
exclude=paths(
"current_timestamp",
"discovered.RINCON_test.event_stats.soco:from_didl_string",
"discovered.RINCON_test.sonos_group_entities",
)
)
async def test_diagnostics_device(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
device_registry: DeviceRegistry,
async_autosetup_sonos,
config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test diagnostics for device."""
TEST_DEVICE = "RINCON_test"
device_entry = device_registry.async_get_device(identifiers={(DOMAIN, TEST_DEVICE)})
assert device_entry is not None
result = await get_diagnostics_for_device(
hass, hass_client, config_entry, device_entry
)
assert result == snapshot(
exclude=paths(
"event_stats.soco:from_didl_string",
"sonos_group_entities",
)
)