Update HEOS tests to not interact directly with integration internals (#136177)

This commit is contained in:
Andrew Sayre 2025-01-21 09:00:34 -06:00 committed by GitHub
parent b11b36b523
commit 9bf2996ea0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 71 additions and 132 deletions

View File

@ -2,12 +2,11 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Sequence from collections.abc import AsyncIterator
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
from pyheos import ( from pyheos import (
CONTROLS_ALL, CONTROLS_ALL,
Dispatcher,
Heos, Heos,
HeosGroup, HeosGroup,
HeosOptions, HeosOptions,
@ -24,15 +23,8 @@ from pyheos import (
import pytest import pytest
import pytest_asyncio import pytest_asyncio
from homeassistant.components.heos import ( from homeassistant.components.heos import DOMAIN
CONF_PASSWORD, from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
DOMAIN,
ControllerManager,
GroupManager,
HeosRuntimeData,
SourceManager,
)
from homeassistant.const import CONF_HOST, CONF_USERNAME
from homeassistant.helpers.service_info.ssdp import ( from homeassistant.helpers.service_info.ssdp import (
ATTR_UPNP_DEVICE_TYPE, ATTR_UPNP_DEVICE_TYPE,
ATTR_UPNP_FRIENDLY_NAME, ATTR_UPNP_FRIENDLY_NAME,
@ -48,54 +40,39 @@ from tests.common import MockConfigEntry
@pytest.fixture(name="config_entry") @pytest.fixture(name="config_entry")
def config_entry_fixture(heos_runtime_data): def config_entry_fixture() -> MockConfigEntry:
"""Create a mock HEOS config entry.""" """Create a mock HEOS config entry."""
entry = MockConfigEntry( return MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data={CONF_HOST: "127.0.0.1"}, data={CONF_HOST: "127.0.0.1"},
title="HEOS System (via 127.0.0.1)", title="HEOS System (via 127.0.0.1)",
unique_id=DOMAIN, unique_id=DOMAIN,
) )
entry.runtime_data = heos_runtime_data
return entry
@pytest.fixture(name="config_entry_options") @pytest.fixture(name="config_entry_options")
def config_entry_options_fixture(heos_runtime_data): def config_entry_options_fixture() -> MockConfigEntry:
"""Create a mock HEOS config entry with options.""" """Create a mock HEOS config entry with options."""
entry = MockConfigEntry( return MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data={CONF_HOST: "127.0.0.1"}, data={CONF_HOST: "127.0.0.1"},
title="HEOS System (via 127.0.0.1)", title="HEOS System (via 127.0.0.1)",
options={CONF_USERNAME: "user", CONF_PASSWORD: "pass"}, options={CONF_USERNAME: "user", CONF_PASSWORD: "pass"},
unique_id=DOMAIN, unique_id=DOMAIN,
) )
entry.runtime_data = heos_runtime_data
return entry
@pytest.fixture(name="heos_runtime_data") @pytest_asyncio.fixture(name="controller", autouse=True)
def heos_runtime_data_fixture(controller_manager, players): async def controller_fixture(
"""Create a mock HeosRuntimeData fixture.""" players: dict[int, HeosPlayer],
return HeosRuntimeData( favorites: dict[int, MediaItem],
controller_manager, Mock(GroupManager), Mock(SourceManager), players input_sources: list[MediaItem],
) playlists: list[MediaItem],
change_data: PlayerUpdateResult,
group: dict[int, HeosGroup],
@pytest.fixture(name="controller_manager") ) -> AsyncIterator[Heos]:
def controller_manager_fixture(controller):
"""Create a mock controller manager fixture."""
mock_controller_manager = Mock(ControllerManager)
mock_controller_manager.controller = controller
return mock_controller_manager
@pytest.fixture(name="controller")
def controller_fixture(
players, favorites, input_sources, playlists, change_data, dispatcher, group
):
"""Create a mock Heos controller fixture.""" """Create a mock Heos controller fixture."""
mock_heos = Heos(HeosOptions(host="127.0.0.1", dispatcher=dispatcher)) mock_heos = Heos(HeosOptions(host="127.0.0.1"))
for player in players.values(): for player in players.values():
player.heos = mock_heos player.heos = mock_heos
mock_heos.connect = AsyncMock() mock_heos.connect = AsyncMock()
@ -121,7 +98,7 @@ def controller_fixture(
@pytest.fixture(name="players") @pytest.fixture(name="players")
def player_fixture(quick_selects): def players_fixture(quick_selects: dict[int, str]) -> dict[int, HeosPlayer]:
"""Create two mock HeosPlayers.""" """Create two mock HeosPlayers."""
players = {} players = {}
for i in (1, 2): for i in (1, 2):
@ -179,12 +156,11 @@ def player_fixture(quick_selects):
@pytest.fixture(name="group") @pytest.fixture(name="group")
def group_fixture(): def group_fixture() -> dict[int, HeosGroup]:
"""Create a HEOS group consisting of two players.""" """Create a HEOS group consisting of two players."""
group = HeosGroup( group = HeosGroup(
name="Group", group_id=999, lead_player_id=1, member_player_ids=[2] name="Group", group_id=999, lead_player_id=1, member_player_ids=[2]
) )
return {group.group_id: group} return {group.group_id: group}
@ -215,7 +191,7 @@ def favorites_fixture() -> dict[int, MediaItem]:
@pytest.fixture(name="input_sources") @pytest.fixture(name="input_sources")
def input_sources_fixture() -> Sequence[MediaItem]: def input_sources_fixture() -> list[MediaItem]:
"""Create a set of input sources for testing.""" """Create a set of input sources for testing."""
source = MediaItem( source = MediaItem(
source_id=1, source_id=1,
@ -230,14 +206,8 @@ def input_sources_fixture() -> Sequence[MediaItem]:
return [source] return [source]
@pytest_asyncio.fixture(name="dispatcher")
async def dispatcher_fixture() -> Dispatcher:
"""Create a dispatcher for testing."""
return Dispatcher()
@pytest.fixture(name="discovery_data") @pytest.fixture(name="discovery_data")
def discovery_data_fixture() -> dict: def discovery_data_fixture() -> SsdpServiceInfo:
"""Return mock discovery data for testing.""" """Return mock discovery data for testing."""
return SsdpServiceInfo( return SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
@ -256,7 +226,7 @@ def discovery_data_fixture() -> dict:
@pytest.fixture(name="discovery_data_bedroom") @pytest.fixture(name="discovery_data_bedroom")
def discovery_data_fixture_bedroom() -> dict: def discovery_data_fixture_bedroom() -> SsdpServiceInfo:
"""Return mock discovery data for testing.""" """Return mock discovery data for testing."""
return SsdpServiceInfo( return SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
@ -288,7 +258,7 @@ def quick_selects_fixture() -> dict[int, str]:
@pytest.fixture(name="playlists") @pytest.fixture(name="playlists")
def playlists_fixture() -> Sequence[MediaItem]: def playlists_fixture() -> list[MediaItem]:
"""Create favorites fixture.""" """Create favorites fixture."""
playlist = MediaItem( playlist = MediaItem(
source_id=const.MUSIC_SOURCE_PLAYLISTS, source_id=const.MUSIC_SOURCE_PLAYLISTS,

View File

@ -220,6 +220,7 @@ async def test_options_flow_signs_in(
) -> None: ) -> None:
"""Test options flow signs-in with entered credentials.""" """Test options flow signs-in with entered credentials."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
# Start the options flow. Entry has not current options. # Start the options flow. Entry has not current options.
assert CONF_USERNAME not in config_entry.options assert CONF_USERNAME not in config_entry.options
@ -258,6 +259,7 @@ async def test_options_flow_signs_out(
) -> None: ) -> None:
"""Test options flow signs-out when credentials cleared.""" """Test options flow signs-out when credentials cleared."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
# Start the options flow. Entry has not current options. # Start the options flow. Entry has not current options.
result = await hass.config_entries.options.async_init(config_entry.entry_id) result = await hass.config_entries.options.async_init(config_entry.entry_id)
@ -305,6 +307,7 @@ async def test_options_flow_missing_one_param_recovers(
) -> None: ) -> None:
"""Test options flow signs-in after recovering from only username or password being entered.""" """Test options flow signs-in after recovering from only username or password being entered."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
# Start the options flow. Entry has not current options. # Start the options flow. Entry has not current options.
assert CONF_USERNAME not in config_entry.options assert CONF_USERNAME not in config_entry.options
@ -353,6 +356,7 @@ async def test_reauth_signs_in_aborts(
) -> None: ) -> None:
"""Test reauth flow signs-in with entered credentials and aborts.""" """Test reauth flow signs-in with entered credentials and aborts."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
result = await config_entry.start_reauth_flow(hass) result = await config_entry.start_reauth_flow(hass)
assert result["step_id"] == "reauth_confirm" assert result["step_id"] == "reauth_confirm"
@ -390,6 +394,7 @@ async def test_reauth_signs_out(
) -> None: ) -> None:
"""Test reauth flow signs-out when credentials cleared and aborts.""" """Test reauth flow signs-out when credentials cleared and aborts."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
result = await config_entry.start_reauth_flow(hass) result = await config_entry.start_reauth_flow(hass)
assert result["step_id"] == "reauth_confirm" assert result["step_id"] == "reauth_confirm"
@ -438,6 +443,7 @@ async def test_reauth_flow_missing_one_param_recovers(
) -> None: ) -> None:
"""Test reauth flow signs-in after recovering from only username or password being entered.""" """Test reauth flow signs-in after recovering from only username or password being entered."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
# Start the options flow. Entry has not current options. # Start the options flow. Entry has not current options.
result = await config_entry.start_reauth_flow(hass) result = await config_entry.start_reauth_flow(hass)

View File

@ -1,6 +1,5 @@
"""Tests for the init module.""" """Tests for the init module."""
import asyncio
from typing import cast from typing import cast
from pyheos import ( from pyheos import (
@ -71,7 +70,7 @@ async def test_async_setup_entry_auth_failure_starts_reauth(
# Simulates what happens when the controller can't sign-in during connection # Simulates what happens when the controller can't sign-in during connection
async def connect_send_auth_failure() -> None: async def connect_send_auth_failure() -> None:
controller._signed_in_username = None controller._signed_in_username = None
controller.dispatcher.send( await controller.dispatcher.wait_send(
SignalType.HEOS_EVENT, SignalHeosEvent.USER_CREDENTIALS_INVALID SignalType.HEOS_EVENT, SignalHeosEvent.USER_CREDENTIALS_INVALID
) )
@ -151,7 +150,6 @@ async def test_update_sources_retry(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
controller: Heos, controller: Heos,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test update sources retries on failures to max attempts.""" """Test update sources retries on failures to max attempts."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -162,12 +160,10 @@ async def test_update_sources_retry(
source_manager.retry_delay = 0 source_manager.retry_delay = 0
source_manager.max_retry_attempts = 1 source_manager.max_retry_attempts = 1
controller.get_favorites.side_effect = CommandFailedError("Test", "test", 0) controller.get_favorites.side_effect = CommandFailedError("Test", "test", 0)
controller.dispatcher.send( await controller.dispatcher.wait_send(
SignalType.CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {} SignalType.CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {}
) )
# Wait until it's finished await hass.async_block_till_done()
while "Unable to update sources" not in caplog.text:
await asyncio.sleep(0.1)
assert controller.get_favorites.call_count == 2 assert controller.get_favorites.call_count == 2

View File

@ -1,7 +1,5 @@
"""Tests for the Heos Media Player platform.""" """Tests for the Heos Media Player platform."""
import asyncio
from collections.abc import Sequence
import re import re
from typing import Any from typing import Any
@ -21,7 +19,7 @@ import pytest
from syrupy.assertion import SnapshotAssertion from syrupy.assertion import SnapshotAssertion
from syrupy.filters import props from syrupy.filters import props
from homeassistant.components.heos.const import DOMAIN, SIGNAL_HEOS_UPDATED from homeassistant.components.heos.const import DOMAIN
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
ATTR_GROUP_MEMBERS, ATTR_GROUP_MEMBERS,
ATTR_INPUT_SOURCE, ATTR_INPUT_SOURCE,
@ -60,12 +58,10 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@pytest.mark.usefixtures("controller")
async def test_state_attributes( async def test_state_attributes(
hass: HomeAssistant, config_entry: MockConfigEntry, snapshot: SnapshotAssertion hass: HomeAssistant, config_entry: MockConfigEntry, snapshot: SnapshotAssertion
) -> None: ) -> None:
@ -94,7 +90,7 @@ async def test_updates_from_signals(
# Test player does not update for other players # Test player does not update for other players
player.state = PlayState.PLAY player.state = PlayState.PLAY
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, 2, const.EVENT_PLAYER_STATE_CHANGED SignalType.PLAYER_EVENT, 2, const.EVENT_PLAYER_STATE_CHANGED
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -103,7 +99,7 @@ async def test_updates_from_signals(
# Test player_update standard events # Test player_update standard events
player.state = PlayState.PLAY player.state = PlayState.PLAY
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -114,7 +110,7 @@ async def test_updates_from_signals(
# Test player_update progress events # Test player_update progress events
player.now_playing_media.duration = 360000 player.now_playing_media.duration = 360000
player.now_playing_media.current_position = 1000 player.now_playing_media.current_position = 1000
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, SignalType.PLAYER_EVENT,
player.player_id, player.player_id,
const.EVENT_PLAYER_NOW_PLAYING_PROGRESS, const.EVENT_PLAYER_NOW_PLAYING_PROGRESS,
@ -136,38 +132,36 @@ async def test_updates_from_connection_event(
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
player = controller.players[1] player = controller.players[1]
event = asyncio.Event()
async def set_signal():
event.set()
async_dispatcher_connect(hass, SIGNAL_HEOS_UPDATED, set_signal)
# Connected # Connected
player.available = True player.available = True
player.heos.dispatcher.send(SignalType.HEOS_EVENT, SignalHeosEvent.CONNECTED) await player.heos.dispatcher.wait_send(
await event.wait() SignalType.HEOS_EVENT, SignalHeosEvent.CONNECTED
)
await hass.async_block_till_done()
state = hass.states.get("media_player.test_player") state = hass.states.get("media_player.test_player")
assert state.state == STATE_IDLE assert state.state == STATE_IDLE
assert controller.load_players.call_count == 1 assert controller.load_players.call_count == 1
# Disconnected # Disconnected
event.clear()
controller.load_players.reset_mock() controller.load_players.reset_mock()
player.available = False player.available = False
player.heos.dispatcher.send(SignalType.HEOS_EVENT, SignalHeosEvent.DISCONNECTED) await player.heos.dispatcher.wait_send(
await event.wait() SignalType.HEOS_EVENT, SignalHeosEvent.DISCONNECTED
)
await hass.async_block_till_done()
state = hass.states.get("media_player.test_player") state = hass.states.get("media_player.test_player")
assert state.state == STATE_UNAVAILABLE assert state.state == STATE_UNAVAILABLE
assert controller.load_players.call_count == 0 assert controller.load_players.call_count == 0
# Connected handles refresh failure # Connected handles refresh failure
event.clear()
controller.load_players.reset_mock() controller.load_players.reset_mock()
controller.load_players.side_effect = CommandFailedError(None, "Failure", 1) controller.load_players.side_effect = CommandFailedError(None, "Failure", 1)
player.available = True player.available = True
player.heos.dispatcher.send(SignalType.HEOS_EVENT, SignalHeosEvent.CONNECTED) await player.heos.dispatcher.wait_send(
await event.wait() SignalType.HEOS_EVENT, SignalHeosEvent.CONNECTED
)
await hass.async_block_till_done()
state = hass.states.get("media_player.test_player") state = hass.states.get("media_player.test_player")
assert state.state == STATE_IDLE assert state.state == STATE_IDLE
assert controller.load_players.call_count == 1 assert controller.load_players.call_count == 1
@ -178,28 +172,23 @@ async def test_updates_from_sources_updated(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
controller: Heos, controller: Heos,
input_sources: Sequence[MediaItem], input_sources: list[MediaItem],
) -> None: ) -> None:
"""Tests player updates from changes in sources list.""" """Tests player updates from changes in sources list."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
player = controller.players[1] player = controller.players[1]
event = asyncio.Event()
async def set_signal():
event.set()
async_dispatcher_connect(hass, SIGNAL_HEOS_UPDATED, set_signal)
input_sources.clear() input_sources.clear()
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {} SignalType.CONTROLLER_EVENT, const.EVENT_SOURCES_CHANGED, {}
) )
await event.wait() await hass.async_block_till_done()
source_list = config_entry.runtime_data.source_manager.source_list
assert len(source_list) == 2
state = hass.states.get("media_player.test_player") state = hass.states.get("media_player.test_player")
assert state.attributes[ATTR_INPUT_SOURCE_LIST] == source_list assert state.attributes[ATTR_INPUT_SOURCE_LIST] == [
"Today's Hits Radio",
"Classical MPR (Classical Music)",
]
async def test_updates_from_players_changed( async def test_updates_from_players_changed(
@ -212,19 +201,12 @@ async def test_updates_from_players_changed(
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
player = controller.players[1] player = controller.players[1]
event = asyncio.Event()
async def set_signal():
event.set()
async_dispatcher_connect(hass, SIGNAL_HEOS_UPDATED, set_signal)
assert hass.states.get("media_player.test_player").state == STATE_IDLE assert hass.states.get("media_player.test_player").state == STATE_IDLE
player.state = PlayState.PLAY player.state = PlayState.PLAY
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.CONTROLLER_EVENT, const.EVENT_PLAYERS_CHANGED, change_data SignalType.CONTROLLER_EVENT, const.EVENT_PLAYERS_CHANGED, change_data
) )
await event.wait()
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("media_player.test_player").state == STATE_PLAYING assert hass.states.get("media_player.test_player").state == STATE_PLAYING
@ -241,7 +223,6 @@ async def test_updates_from_players_changed_new_ids(
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
player = controller.players[1] player = controller.players[1]
event = asyncio.Event()
# Assert device registry matches current id # Assert device registry matches current id
assert device_registry.async_get_device(identifiers={(DOMAIN, "1")}) assert device_registry.async_get_device(identifiers={(DOMAIN, "1")})
@ -251,17 +232,12 @@ async def test_updates_from_players_changed_new_ids(
== "media_player.test_player" == "media_player.test_player"
) )
# Trigger update await player.heos.dispatcher.wait_send(
async def set_signal():
event.set()
async_dispatcher_connect(hass, SIGNAL_HEOS_UPDATED, set_signal)
player.heos.dispatcher.send(
SignalType.CONTROLLER_EVENT, SignalType.CONTROLLER_EVENT,
const.EVENT_PLAYERS_CHANGED, const.EVENT_PLAYERS_CHANGED,
change_data_mapped_ids, change_data_mapped_ids,
) )
await event.wait() await hass.async_block_till_done()
# Assert device registry identifiers were updated # Assert device registry identifiers were updated
assert len(device_registry.devices) == 2 assert len(device_registry.devices) == 2
@ -275,28 +251,23 @@ async def test_updates_from_players_changed_new_ids(
async def test_updates_from_user_changed( async def test_updates_from_user_changed(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
) -> None: ) -> None:
"""Tests player updates from changes in user.""" """Tests player updates from changes in user."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
player = controller.players[1] player = controller.players[1]
event = asyncio.Event()
async def set_signal():
event.set()
async_dispatcher_connect(hass, SIGNAL_HEOS_UPDATED, set_signal)
controller._signed_in_username = None controller._signed_in_username = None
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.CONTROLLER_EVENT, const.EVENT_USER_CHANGED, None SignalType.CONTROLLER_EVENT, const.EVENT_USER_CHANGED, None
) )
await event.wait() await hass.async_block_till_done()
source_list = config_entry.runtime_data.source_manager.source_list
assert len(source_list) == 1
state = hass.states.get("media_player.test_player") state = hass.states.get("media_player.test_player")
assert state.attributes[ATTR_INPUT_SOURCE_LIST] == source_list assert state.attributes[ATTR_INPUT_SOURCE_LIST] == ["HEOS Drive - Line In 1"]
async def test_clear_playlist( async def test_clear_playlist(
@ -650,7 +621,7 @@ async def test_select_favorite(
player.play_preset_station.assert_called_once_with(1) player.play_preset_station.assert_called_once_with(1)
# Test state is matched by station name # Test state is matched by station name
player.now_playing_media.station = favorite.name player.now_playing_media.station = favorite.name
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -680,7 +651,7 @@ async def test_select_radio_favorite(
# Test state is matched by album id # Test state is matched by album id
player.now_playing_media.station = "Classical" player.now_playing_media.station = "Classical"
player.now_playing_media.album_id = favorite.media_id player.now_playing_media.album_id = favorite.media_id
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -721,7 +692,7 @@ async def test_select_input_source(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
controller: Heos, controller: Heos,
input_sources: Sequence[MediaItem], input_sources: list[MediaItem],
) -> None: ) -> None:
"""Tests selecting input source and state.""" """Tests selecting input source and state."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -742,7 +713,7 @@ async def test_select_input_source(
# Test state is matched by media id # Test state is matched by media id
player.now_playing_media.source_id = const.MUSIC_SOURCE_AUX_INPUT player.now_playing_media.source_id = const.MUSIC_SOURCE_AUX_INPUT
player.now_playing_media.media_id = const.INPUT_AUX_IN_1 player.now_playing_media.media_id = const.INPUT_AUX_IN_1
player.heos.dispatcher.send( await player.heos.dispatcher.wait_send(
SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED SignalType.PLAYER_EVENT, player.player_id, const.EVENT_PLAYER_STATE_CHANGED
) )
await hass.async_block_till_done() await hass.async_block_till_done()
@ -750,7 +721,6 @@ async def test_select_input_source(
assert state.attributes[ATTR_INPUT_SOURCE] == input_source.name assert state.attributes[ATTR_INPUT_SOURCE] == input_source.name
@pytest.mark.usefixtures("controller")
async def test_select_input_unknown_raises( async def test_select_input_unknown_raises(
hass: HomeAssistant, config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:
@ -773,7 +743,7 @@ async def test_select_input_command_error(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
controller: Heos, controller: Heos,
input_sources: Sequence[MediaItem], input_sources: list[MediaItem],
) -> None: ) -> None:
"""Tests selecting an unknown input.""" """Tests selecting an unknown input."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@ -797,7 +767,6 @@ async def test_select_input_command_error(
player.play_input_source.assert_called_once_with(input_source.media_id) player.play_input_source.assert_called_once_with(input_source.media_id)
@pytest.mark.usefixtures("controller")
async def test_unload_config_entry( async def test_unload_config_entry(
hass: HomeAssistant, config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:
@ -926,7 +895,7 @@ async def test_play_media_playlist(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
controller: Heos, controller: Heos,
playlists: Sequence[MediaItem], playlists: list[MediaItem],
enqueue: Any, enqueue: Any,
criteria: AddCriteriaType, criteria: AddCriteriaType,
) -> None: ) -> None:
@ -1026,7 +995,6 @@ async def test_play_media_favorite_error(
assert player.play_preset_station.call_count == 0 assert player.play_preset_station.call_count == 0
@pytest.mark.usefixtures("controller")
async def test_play_media_invalid_type( async def test_play_media_invalid_type(
hass: HomeAssistant, config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:

View File

@ -81,7 +81,6 @@ async def test_sign_in_unknown_error(
assert "Unable to sign in" in caplog.text assert "Unable to sign in" in caplog.text
@pytest.mark.usefixtures("controller")
async def test_sign_in_not_loaded_raises( async def test_sign_in_not_loaded_raises(
hass: HomeAssistant, config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None: