Improve entity test coverage for Russound RIO (#129828)

This commit is contained in:
Noah Husby 2024-11-09 11:13:57 -05:00 committed by GitHub
parent 31b505828b
commit e3315383ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 164 additions and 14 deletions

View File

@ -1 +1,13 @@
"""Tests for the Russound RIO 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()

View File

@ -1,16 +1,19 @@
"""Test fixtures for Russound RIO integration."""
from collections.abc import Generator
from unittest.mock import AsyncMock, patch
from unittest.mock import AsyncMock, Mock, patch
from aiorussound import Controller, RussoundTcpConnectionHandler, Source
from aiorussound.rio import ZoneControlSurface
from aiorussound.util import controller_device_str, zone_device_str
import pytest
from homeassistant.components.russound_rio.const import DOMAIN
from homeassistant.core import HomeAssistant
from .const import HARDWARE_MAC, MOCK_CONFIG, MOCK_CONTROLLERS, MODEL
from .const import HARDWARE_MAC, HOST, MOCK_CONFIG, MODEL, PORT
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, load_json_object_fixture
@pytest.fixture
@ -33,7 +36,7 @@ def mock_config_entry(hass: HomeAssistant) -> MockConfigEntry:
@pytest.fixture
def mock_russound() -> Generator[AsyncMock]:
def mock_russound_client() -> Generator[AsyncMock]:
"""Mock the Russound RIO client."""
with (
patch(
@ -41,8 +44,30 @@ def mock_russound() -> Generator[AsyncMock]:
) as mock_client,
patch(
"homeassistant.components.russound_rio.config_flow.RussoundClient",
return_value=mock_client,
new=mock_client,
),
):
mock_client.controllers = MOCK_CONTROLLERS
yield mock_client
client = mock_client.return_value
zones = {
int(k): ZoneControlSurface.from_dict(v)
for k, v in load_json_object_fixture("get_zones.json", DOMAIN).items()
}
client.sources = {
int(k): Source.from_dict(v)
for k, v in load_json_object_fixture("get_sources.json", DOMAIN).items()
}
for k, v in zones.items():
v.device_str = zone_device_str(1, k)
v.fetch_current_source = Mock(
side_effect=lambda current_source=v.current_source: client.sources.get(
int(current_source)
)
)
client.controllers = {
1: Controller(
1, "MCA-C5", client, controller_device_str(1), HARDWARE_MAC, None, zones
)
}
client.connection_handler = RussoundTcpConnectionHandler(HOST, PORT)
yield client

View File

@ -0,0 +1,10 @@
{
"1": {
"name": "Aux",
"type": "Miscellaneous Audio"
},
"2": {
"name": "Spotify",
"type": "Russound Media Streamer"
}
}

View File

@ -0,0 +1,22 @@
{
"1": {
"name": "Backyard",
"volume": "10",
"status": "ON",
"enabled": "True",
"current_source": "1"
},
"2": {
"name": "Kitchen",
"volume": "50",
"status": "OFF",
"enabled": "True",
"current_source": "2"
},
"3": {
"name": "Bedroom",
"volume": "10",
"status": "OFF",
"enabled": "False"
}
}

View File

@ -0,0 +1,37 @@
# serializer version: 1
# name: test_device_info
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
'configuration_url': 'http://127.0.0.1',
'connections': set({
tuple(
'mac',
'00:11:22:33:44:55',
),
}),
'disabled_by': None,
'entry_type': None,
'hw_version': None,
'id': <ANY>,
'identifiers': set({
tuple(
'russound_rio',
'00:11:22:33:44:55',
),
}),
'is_new': False,
'labels': set({
}),
'manufacturer': 'Russound',
'model': 'MCA-C5',
'model_id': None,
'name': 'MCA-C5',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': None,
'suggested_area': None,
'sw_version': None,
'via_device_id': None,
})
# ---

View File

@ -11,7 +11,7 @@ from .const import MOCK_CONFIG, MODEL
async def test_form(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound: AsyncMock
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound_client: AsyncMock
) -> None:
"""Test we get the form."""
result = await hass.config_entries.flow.async_init(
@ -32,13 +32,13 @@ async def test_form(
async def test_form_cannot_connect(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound: AsyncMock
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound_client: AsyncMock
) -> None:
"""Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
mock_russound.connect.side_effect = TimeoutError
mock_russound_client.connect.side_effect = TimeoutError
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
MOCK_CONFIG,
@ -48,7 +48,7 @@ async def test_form_cannot_connect(
assert result["errors"] == {"base": "cannot_connect"}
# Recover with correct information
mock_russound.connect.side_effect = None
mock_russound_client.connect.side_effect = None
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
MOCK_CONFIG,
@ -61,7 +61,7 @@ async def test_form_cannot_connect(
async def test_import(
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound: AsyncMock
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_russound_client: AsyncMock
) -> None:
"""Test we import a config entry."""
result = await hass.config_entries.flow.async_init(
@ -77,10 +77,10 @@ async def test_import(
async def test_import_cannot_connect(
hass: HomeAssistant, mock_russound: AsyncMock
hass: HomeAssistant, mock_russound_client: AsyncMock
) -> None:
"""Test we handle import cannot connect error."""
mock_russound.connect.side_effect = TimeoutError
mock_russound_client.connect.side_effect = TimeoutError
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=MOCK_CONFIG

View File

@ -0,0 +1,44 @@
"""Tests for the Russound RIO integration."""
from unittest.mock import AsyncMock
from syrupy import SnapshotAssertion
from homeassistant.components.russound_rio.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from . import setup_integration
from tests.common import MockConfigEntry
async def test_config_entry_not_ready(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_russound_client: AsyncMock,
) -> None:
"""Test the Cambridge Audio configuration entry not ready."""
mock_russound_client.connect.side_effect = TimeoutError
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
mock_russound_client.connect = AsyncMock(return_value=True)
async def test_device_info(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_russound_client: AsyncMock,
mock_config_entry: MockConfigEntry,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test device registry integration."""
await setup_integration(hass, mock_config_entry)
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, mock_config_entry.unique_id)}
)
assert device_entry is not None
assert device_entry == snapshot