mirror of
https://github.com/home-assistant/core.git
synced 2026-07-01 11:46:40 +01:00
171 lines
4.9 KiB
Python
171 lines
4.9 KiB
Python
"""Test fixtures for the Denon RS-232 integration."""
|
|
|
|
from typing import Literal
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
from denon_rs232 import (
|
|
DenonReceiver,
|
|
DigitalInputMode,
|
|
InputSource,
|
|
MainZoneState,
|
|
ReceiverState,
|
|
TunerBand,
|
|
TunerMode,
|
|
ZoneState,
|
|
)
|
|
from denon_rs232.models import MODELS
|
|
import pytest
|
|
|
|
from homeassistant.components.denon_rs232.config_flow import CONF_MODEL_NAME
|
|
from homeassistant.components.denon_rs232.const import DOMAIN
|
|
from homeassistant.const import CONF_DEVICE, CONF_MODEL
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from . import MOCK_DEVICE, MOCK_MODEL
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
type ZoneName = Literal["main", "zone_2", "zone_3"]
|
|
|
|
|
|
class MockState(ReceiverState):
|
|
"""Receiver state with helpers for zone-oriented tests."""
|
|
|
|
def get_zone(self, zone: ZoneName) -> ZoneState:
|
|
"""Return the requested zone state."""
|
|
if zone == "main":
|
|
return self.main_zone
|
|
return getattr(self, zone)
|
|
|
|
|
|
class MockReceiver(DenonReceiver):
|
|
"""Receiver test double built on the real receiver/player objects."""
|
|
|
|
def __init__(self, state: MockState) -> None:
|
|
"""Initialize the mock receiver."""
|
|
super().__init__(MOCK_DEVICE, model=MODELS[MOCK_MODEL])
|
|
self._connected = True
|
|
self._load_state(state)
|
|
self._send_command = AsyncMock()
|
|
self._query = AsyncMock()
|
|
self.connect = AsyncMock(side_effect=self._mock_connect)
|
|
self.query_state = AsyncMock()
|
|
self.disconnect = AsyncMock(side_effect=self._mock_disconnect)
|
|
|
|
def get_zone(self, zone: ZoneName):
|
|
"""Return the matching live player object."""
|
|
if zone == "main":
|
|
return self.main
|
|
if zone == "zone_2":
|
|
return self.zone_2
|
|
return self.zone_3
|
|
|
|
def mock_state(self, state: MockState | None) -> None:
|
|
"""Push a state update through the receiver."""
|
|
self._connected = state is not None
|
|
if state is not None:
|
|
self._load_state(state)
|
|
self._notify_subscribers()
|
|
|
|
async def _mock_connect(self) -> None:
|
|
"""Pretend to open the serial connection."""
|
|
self._connected = True
|
|
|
|
async def _mock_disconnect(self) -> None:
|
|
"""Pretend to close the serial connection."""
|
|
self._connected = False
|
|
self._notify_subscribers()
|
|
|
|
def _load_state(self, state: MockState) -> None:
|
|
"""Swap in a new state object and rebind the live players to it."""
|
|
self._state = state
|
|
self.main._state = state.main_zone
|
|
self.zone_2._state = state.zone_2
|
|
self.zone_3._state = state.zone_3
|
|
|
|
|
|
def _default_state() -> MockState:
|
|
"""Return a ReceiverState with typical defaults."""
|
|
return MockState(
|
|
power=True,
|
|
main_zone=MainZoneState(
|
|
power=True,
|
|
volume=-30.0,
|
|
volume_min=-80,
|
|
volume_max=10,
|
|
mute=False,
|
|
input_source=InputSource.CD,
|
|
surround_mode="STEREO",
|
|
digital_input=DigitalInputMode.AUTO,
|
|
tuner_band=TunerBand.FM,
|
|
tuner_mode=TunerMode.AUTO,
|
|
),
|
|
zone_2=ZoneState(
|
|
power=True,
|
|
input_source=InputSource.TUNER,
|
|
volume=-20.0,
|
|
),
|
|
zone_3=ZoneState(
|
|
power=False,
|
|
input_source=InputSource.CD,
|
|
volume=-35.0,
|
|
),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def initial_receiver_state(request: pytest.FixtureRequest) -> MockState:
|
|
"""Return the initial receiver state for a test."""
|
|
state = _default_state()
|
|
|
|
if getattr(request, "param", None) == "main_only":
|
|
state.zone_2 = ZoneState()
|
|
state.zone_3 = ZoneState()
|
|
|
|
return state
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_receiver(initial_receiver_state: MockState) -> MockReceiver:
|
|
"""Create a mock DenonReceiver."""
|
|
return MockReceiver(initial_receiver_state)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_config_entry(hass: HomeAssistant) -> MockConfigEntry:
|
|
"""Create a mock config entry."""
|
|
entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
CONF_DEVICE: MOCK_DEVICE,
|
|
CONF_MODEL: MOCK_MODEL,
|
|
CONF_MODEL_NAME: "AVR-3805",
|
|
},
|
|
title="AVR-3805",
|
|
entry_id="01KPBBPM6WCQ8148EFR0TCG1WW",
|
|
)
|
|
entry.add_to_hass(hass)
|
|
return entry
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
async def mock_usb_component(hass: HomeAssistant) -> None:
|
|
"""Mock the USB component to prevent setup failures."""
|
|
hass.config.components.add("usb")
|
|
|
|
|
|
@pytest.fixture
|
|
async def init_components(
|
|
hass: HomeAssistant,
|
|
mock_usb_component: None,
|
|
mock_receiver: MockReceiver,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Initialize the Denon component."""
|
|
with patch(
|
|
"homeassistant.components.denon_rs232.DenonReceiver",
|
|
return_value=mock_receiver,
|
|
):
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|