Fix typing errors in HEOS tests (#136795)

* Correct typing errors of mocked heos

* Fix player related typing issues

* Sort mocks
This commit is contained in:
Andrew Sayre 2025-01-28 21:44:57 -06:00 committed by GitHub
parent 9f586ea547
commit bc7c5fbc86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 343 additions and 270 deletions

View File

@ -1 +1,58 @@
"""Tests for the Heos component."""
from unittest.mock import AsyncMock
from pyheos import Heos, HeosGroup, HeosOptions, HeosPlayer
class MockHeos(Heos):
"""Defines a mocked HEOS API."""
def __init__(self, options: HeosOptions) -> None:
"""Initialize the mock."""
super().__init__(options)
# Overwrite the methods with async mocks, changing type
self.add_to_queue: AsyncMock = AsyncMock()
self.connect: AsyncMock = AsyncMock()
self.disconnect: AsyncMock = AsyncMock()
self.get_favorites: AsyncMock = AsyncMock()
self.get_groups: AsyncMock = AsyncMock()
self.get_input_sources: AsyncMock = AsyncMock()
self.get_playlists: AsyncMock = AsyncMock()
self.get_players: AsyncMock = AsyncMock()
self.load_players: AsyncMock = AsyncMock()
self.play_media: AsyncMock = AsyncMock()
self.play_preset_station: AsyncMock = AsyncMock()
self.play_url: AsyncMock = AsyncMock()
self.player_clear_queue: AsyncMock = AsyncMock()
self.player_get_quick_selects: AsyncMock = AsyncMock()
self.player_play_next: AsyncMock = AsyncMock()
self.player_play_previous: AsyncMock = AsyncMock()
self.player_play_quick_select: AsyncMock = AsyncMock()
self.player_set_mute: AsyncMock = AsyncMock()
self.player_set_play_mode: AsyncMock = AsyncMock()
self.player_set_play_state: AsyncMock = AsyncMock()
self.player_set_volume: AsyncMock = AsyncMock()
self.set_group: AsyncMock = AsyncMock()
self.sign_in: AsyncMock = AsyncMock()
self.sign_out: AsyncMock = AsyncMock()
def mock_set_players(self, players: dict[int, HeosPlayer]) -> None:
"""Set the players on the mock instance."""
for player in players.values():
player.heos = self
self._players = players
self._players_loaded = bool(players)
self.get_players.return_value = players
def mock_set_groups(self, groups: dict[int, HeosGroup]) -> None:
"""Set the groups on the mock instance."""
for group in groups.values():
group.heos = self
self._groups = groups
self._groups_loaded = bool(groups)
self.get_groups.return_value = groups
def mock_set_signed_in_username(self, signed_in_username: str | None) -> None:
"""Set the signed in status on the mock instance."""
self._signed_in_username = signed_in_username

View File

@ -2,11 +2,10 @@
from __future__ import annotations
from collections.abc import AsyncIterator
from unittest.mock import AsyncMock, Mock, patch
from collections.abc import Iterator
from unittest.mock import Mock, patch
from pyheos import (
Heos,
HeosGroup,
HeosHost,
HeosNowPlayingMedia,
@ -38,6 +37,8 @@ from homeassistant.helpers.service_info.ssdp import (
SsdpServiceInfo,
)
from . import MockHeos
from tests.common import MockConfigEntry
@ -64,6 +65,17 @@ def config_entry_options_fixture() -> MockConfigEntry:
)
@pytest.fixture(name="new_mock", autouse=True)
def new_heos_mock_fixture(controller: MockHeos) -> Iterator[Mock]:
"""Patch the Heos class to return the mock instance."""
new_mock = Mock(return_value=controller)
with (
patch("homeassistant.components.heos.coordinator.Heos", new=new_mock),
patch("homeassistant.components.heos.config_flow.Heos", new=new_mock),
):
yield new_mock
@pytest_asyncio.fixture(name="controller", autouse=True)
async def controller_fixture(
players: dict[int, HeosPlayer],
@ -72,49 +84,38 @@ async def controller_fixture(
playlists: list[MediaItem],
change_data: PlayerUpdateResult,
group: dict[int, HeosGroup],
) -> AsyncIterator[Heos]:
quick_selects: dict[int, str],
) -> MockHeos:
"""Create a mock Heos controller fixture."""
mock_heos = Heos(HeosOptions(host="127.0.0.1"))
for player in players.values():
player.heos = mock_heos
mock_heos.connect = AsyncMock()
mock_heos.disconnect = AsyncMock()
mock_heos.sign_in = AsyncMock()
mock_heos.sign_out = AsyncMock()
mock_heos.get_players = AsyncMock(return_value=players)
mock_heos._players = players
mock_heos.get_favorites = AsyncMock(return_value=favorites)
mock_heos.get_input_sources = AsyncMock(return_value=input_sources)
mock_heos.get_playlists = AsyncMock(return_value=playlists)
mock_heos.load_players = AsyncMock(return_value=change_data)
mock_heos._signed_in_username = "user@user.com"
mock_heos.get_groups = AsyncMock(return_value=group)
mock_heos._groups = group
mock_heos.set_group = AsyncMock(return_value=None)
new_mock = Mock(return_value=mock_heos)
mock_heos.new_mock = new_mock
with (
patch("homeassistant.components.heos.coordinator.Heos", new=new_mock),
patch("homeassistant.components.heos.config_flow.Heos", new=new_mock),
):
yield mock_heos
mock_heos = MockHeos(HeosOptions(host="127.0.0.1"))
mock_heos.mock_set_signed_in_username("user@user.com")
mock_heos.mock_set_players(players)
mock_heos.mock_set_groups(group)
mock_heos.get_favorites.return_value = favorites
mock_heos.get_input_sources.return_value = input_sources
mock_heos.get_playlists.return_value = playlists
mock_heos.load_players.return_value = change_data
mock_heos.player_get_quick_selects.return_value = quick_selects
return mock_heos
@pytest.fixture(name="system")
def system_info_fixture() -> dict[str, str]:
def system_info_fixture() -> HeosSystem:
"""Create a system info fixture."""
main_host = HeosHost(
"Test Player",
"HEOS Drive HS2",
"123456",
"1.0.0",
"127.0.0.1",
NetworkType.WIRED,
)
return HeosSystem(
"user@user.com",
"127.0.0.1",
main_host,
hosts=[
HeosHost(
"Test Player",
"HEOS Drive HS2",
"123456",
"1.0.0",
"127.0.0.1",
NetworkType.WIRED,
),
main_host,
HeosHost(
"Test Player 2",
"Speaker",
@ -128,7 +129,7 @@ def system_info_fixture() -> dict[str, str]:
@pytest.fixture(name="players")
def players_fixture(quick_selects: dict[int, str]) -> dict[int, HeosPlayer]:
def players_fixture() -> dict[int, HeosPlayer]:
"""Create two mock HeosPlayers."""
players = {}
for i in (1, 2):
@ -148,7 +149,6 @@ def players_fixture(quick_selects: dict[int, str]) -> dict[int, HeosPlayer]:
shuffle=False,
repeat=RepeatType.OFF,
volume=25,
heos=None,
)
player.now_playing_media = HeosNowPlayingMedia(
type=MediaType.STATION,
@ -162,24 +162,6 @@ def players_fixture(quick_selects: dict[int, str]) -> dict[int, HeosPlayer]:
queue_id=1,
source_id=10,
)
player.add_to_queue = AsyncMock()
player.clear_queue = AsyncMock()
player.get_quick_selects = AsyncMock(return_value=quick_selects)
player.mute = AsyncMock()
player.pause = AsyncMock()
player.play = AsyncMock()
player.play_media = AsyncMock()
player.play_next = AsyncMock()
player.play_previous = AsyncMock()
player.play_preset_station = AsyncMock()
player.play_quick_select = AsyncMock()
player.play_url = AsyncMock()
player.set_mute = AsyncMock()
player.set_play_mode = AsyncMock()
player.set_quick_select = AsyncMock()
player.set_volume = AsyncMock()
player.stop = AsyncMock()
player.unmute = AsyncMock()
players[player.player_id] = player
return players

View File

@ -98,8 +98,15 @@
'Speaker - Line In 1',
]),
'system': dict({
'connected_to_preferred_host': False,
'host': '127.0.0.1',
'connected_to_preferred_host': True,
'host': dict({
'ip_address': '127.0.0.1',
'model': 'HEOS Drive HS2',
'name': 'Test Player',
'network': 'wired',
'serial': '**REDACTED**',
'version': '1.0.0',
}),
'hosts': list([
dict({
'ip_address': '127.0.0.1',

View File

@ -1,6 +1,8 @@
"""Tests for the Heos config flow module."""
from pyheos import CommandAuthenticationError, CommandFailedError, Heos, HeosError
from typing import Any
from pyheos import CommandAuthenticationError, CommandFailedError, HeosError
import pytest
from homeassistant.components.heos.const import DOMAIN
@ -10,6 +12,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers.service_info.ssdp import SsdpServiceInfo
from . import MockHeos
from tests.common import MockConfigEntry
@ -38,7 +42,7 @@ async def test_no_host_shows_form(hass: HomeAssistant) -> None:
async def test_cannot_connect_shows_error_form(
hass: HomeAssistant, controller: Heos
hass: HomeAssistant, controller: MockHeos
) -> None:
"""Test form is shown with error when cannot connect."""
controller.connect.side_effect = HeosError()
@ -47,13 +51,15 @@ async def test_cannot_connect_shows_error_form(
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"][CONF_HOST] == "cannot_connect"
errors = result["errors"]
assert errors is not None
assert errors[CONF_HOST] == "cannot_connect"
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
async def test_create_entry_when_host_valid(
hass: HomeAssistant, controller: Heos
hass: HomeAssistant, controller: MockHeos
) -> None:
"""Test result type is create entry when host is valid."""
data = {CONF_HOST: "127.0.0.1"}
@ -70,7 +76,7 @@ async def test_create_entry_when_host_valid(
async def test_create_entry_when_friendly_name_valid(
hass: HomeAssistant, controller: Heos
hass: HomeAssistant, controller: MockHeos
) -> None:
"""Test result type is create entry when friendly name is valid."""
hass.data[DOMAIN] = {"Office (127.0.0.1)": "127.0.0.1"}
@ -131,7 +137,7 @@ async def test_discovery_flow_aborts_already_setup(
async def test_reconfigure_validates_and_updates_config(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test reconfigure validates host and successfully updates."""
config_entry.add_to_hass(hass)
@ -139,9 +145,9 @@ async def test_reconfigure_validates_and_updates_config(
assert config_entry.data[CONF_HOST] == "127.0.0.1"
# Test reconfigure initially shows form with current host value.
host = next(
key.default() for key in result["data_schema"].schema if key == CONF_HOST
)
schema = result["data_schema"]
assert schema is not None
host = next(key.default() for key in schema.schema if key == CONF_HOST)
assert host == "127.0.0.1"
assert result["errors"] == {}
assert result["step_id"] == "reconfigure"
@ -161,7 +167,7 @@ async def test_reconfigure_validates_and_updates_config(
async def test_reconfigure_cannot_connect_recovers(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test reconfigure cannot connect and recovers."""
controller.connect.side_effect = HeosError()
@ -176,11 +182,13 @@ async def test_reconfigure_cannot_connect_recovers(
assert controller.connect.call_count == 1
assert controller.disconnect.call_count == 1
host = next(
key.default() for key in result["data_schema"].schema if key == CONF_HOST
)
schema = result["data_schema"]
assert schema is not None
host = next(key.default() for key in schema.schema if key == CONF_HOST)
assert host == "127.0.0.2"
assert result["errors"][CONF_HOST] == "cannot_connect"
errors = result["errors"]
assert errors is not None
assert errors[CONF_HOST] == "cannot_connect"
assert result["step_id"] == "reconfigure"
assert result["type"] is FlowResultType.FORM
@ -214,7 +222,7 @@ async def test_reconfigure_cannot_connect_recovers(
async def test_options_flow_signs_in(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
error: HeosError,
expected_error_key: str,
) -> None:
@ -255,7 +263,7 @@ async def test_options_flow_signs_in(
async def test_options_flow_signs_out(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test options flow signs-out when credentials cleared."""
config_entry.add_to_hass(hass)
@ -268,7 +276,7 @@ async def test_options_flow_signs_out(
assert result["type"] is FlowResultType.FORM
# Fail to sign-out, show error
user_input = {}
user_input: dict[str, Any] = {}
controller.sign_out.side_effect = HeosError()
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input
@ -301,7 +309,7 @@ async def test_options_flow_signs_out(
async def test_options_flow_missing_one_param_recovers(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
user_input: dict[str, str],
expected_errors: dict[str, str],
) -> None:
@ -350,7 +358,7 @@ async def test_options_flow_missing_one_param_recovers(
async def test_reauth_signs_in_aborts(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
error: HeosError,
expected_error_key: str,
) -> None:
@ -391,7 +399,7 @@ async def test_reauth_signs_in_aborts(
async def test_reauth_signs_out(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test reauth flow signs-out when credentials cleared and aborts."""
config_entry.add_to_hass(hass)
@ -404,7 +412,7 @@ async def test_reauth_signs_out(
assert result["type"] is FlowResultType.FORM
# Fail to sign-out, show error
user_input = {}
user_input: dict[str, Any] = {}
controller.sign_out.side_effect = HeosError()
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input
@ -439,7 +447,7 @@ async def test_reauth_signs_out(
async def test_reauth_flow_missing_one_param_recovers(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
user_input: dict[str, str],
expected_errors: dict[str, str],
) -> None:

View File

@ -2,15 +2,17 @@
from unittest import mock
from pyheos import Heos, HeosSystem
from pyheos import HeosSystem
import pytest
from syrupy import SnapshotAssertion
from syrupy.assertion import SnapshotAssertion
from syrupy.filters import props
from homeassistant.components.heos.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from . import MockHeos
from tests.common import MockConfigEntry
from tests.components.diagnostics import (
get_diagnostics_for_config_entry,
@ -23,7 +25,7 @@ async def test_config_entry_diagnostics(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
system: HeosSystem,
snapshot: SnapshotAssertion,
) -> None:
@ -77,7 +79,7 @@ async def test_device_diagnostics(
assert await hass.config_entries.async_setup(config_entry.entry_id)
device_registry = dr.async_get(hass)
device = device_registry.async_get_device({(DOMAIN, "1")})
assert device is not None
diagnostics = await get_diagnostics_for_device(
hass, hass_client, config_entry, device
)

View File

@ -1,8 +1,9 @@
"""Tests for the init module."""
from typing import cast
from unittest.mock import Mock
from pyheos import Heos, HeosError, HeosOptions, SignalHeosEvent, SignalType
from pyheos import HeosError, HeosOptions, SignalHeosEvent, SignalType
import pytest
from homeassistant.components.heos.const import DOMAIN
@ -11,13 +12,15 @@ from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from . import MockHeos
from tests.common import MockConfigEntry
async def test_async_setup_entry_loads_platforms(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
) -> None:
"""Test load connects to heos, retrieves players, and loads platforms."""
config_entry.add_to_hass(hass)
@ -32,7 +35,10 @@ async def test_async_setup_entry_loads_platforms(
async def test_async_setup_entry_with_options_loads_platforms(
hass: HomeAssistant, config_entry_options: MockConfigEntry, controller: Heos
hass: HomeAssistant,
config_entry_options: MockConfigEntry,
controller: MockHeos,
new_mock: Mock,
) -> None:
"""Test load connects to heos with options, retrieves players, and loads platforms."""
config_entry_options.add_to_hass(hass)
@ -40,8 +46,9 @@ async def test_async_setup_entry_with_options_loads_platforms(
# Assert options passed and methods called
assert config_entry_options.state is ConfigEntryState.LOADED
options = cast(HeosOptions, controller.new_mock.call_args[0][0])
options = cast(HeosOptions, new_mock.call_args[0][0])
assert options.host == config_entry_options.data[CONF_HOST]
assert options.credentials is not None
assert options.credentials.username == config_entry_options.options[CONF_USERNAME]
assert options.credentials.password == config_entry_options.options[CONF_PASSWORD]
assert controller.connect.call_count == 1
@ -54,14 +61,14 @@ async def test_async_setup_entry_with_options_loads_platforms(
async def test_async_setup_entry_auth_failure_starts_reauth(
hass: HomeAssistant,
config_entry_options: MockConfigEntry,
controller: Heos,
controller: MockHeos,
) -> None:
"""Test load with auth failure starts reauth, loads platforms."""
config_entry_options.add_to_hass(hass)
# Simulates what happens when the controller can't sign-in during connection
async def connect_send_auth_failure() -> None:
controller._signed_in_username = None
controller.mock_set_signed_in_username(None)
await controller.dispatcher.wait_send(
SignalType.HEOS_EVENT, SignalHeosEvent.USER_CREDENTIALS_INVALID
)
@ -76,19 +83,19 @@ async def test_async_setup_entry_auth_failure_starts_reauth(
controller.disconnect.assert_not_called()
assert config_entry_options.state is ConfigEntryState.LOADED
assert any(
config_entry_options.async_get_active_flows(hass, sources=[SOURCE_REAUTH])
config_entry_options.async_get_active_flows(hass, sources={SOURCE_REAUTH})
)
async def test_async_setup_entry_not_signed_in_loads_platforms(
hass: HomeAssistant,
config_entry: MockConfigEntry,
controller: Heos,
controller: MockHeos,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test setup does not retrieve favorites when not logged in."""
config_entry.add_to_hass(hass)
controller._signed_in_username = None
controller.mock_set_signed_in_username(None)
assert await hass.config_entries.async_setup(config_entry.entry_id)
assert controller.connect.call_count == 1
assert controller.get_players.call_count == 1
@ -102,7 +109,7 @@ async def test_async_setup_entry_not_signed_in_loads_platforms(
async def test_async_setup_entry_connect_failure(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Connection failure raises ConfigEntryNotReady."""
config_entry.add_to_hass(hass)
@ -114,7 +121,7 @@ async def test_async_setup_entry_connect_failure(
async def test_async_setup_entry_player_failure(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Failure to retrieve players raises ConfigEntryNotReady."""
config_entry.add_to_hass(hass)
@ -126,7 +133,7 @@ async def test_async_setup_entry_player_failure(
async def test_async_setup_entry_favorites_failure(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Failure to retrieve favorites loads."""
config_entry.add_to_hass(hass)
@ -136,7 +143,7 @@ async def test_async_setup_entry_favorites_failure(
async def test_async_setup_entry_inputs_failure(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Failure to retrieve inputs loads."""
config_entry.add_to_hass(hass)
@ -146,7 +153,7 @@ async def test_async_setup_entry_inputs_failure(
async def test_unload_entry(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test entries are unloaded correctly."""
config_entry.add_to_hass(hass)
@ -164,12 +171,14 @@ async def test_device_info(
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
device = device_registry.async_get_device({(DOMAIN, "1")})
assert device is not None
assert device.manufacturer == "HEOS"
assert device.model == "Drive HS2"
assert device.name == "Test Player"
assert device.serial_number == "123456"
assert device.sw_version == "1.0.0"
device = device_registry.async_get_device({(DOMAIN, "2")})
assert device is not None
assert device.manufacturer == "HEOS"
assert device.model == "Speaker"
@ -183,12 +192,14 @@ async def test_device_id_migration(
config_entry.add_to_hass(hass)
# Create a device with a legacy identifier
device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id, identifiers={(DOMAIN, 1)}
config_entry_id=config_entry.entry_id,
identifiers={(DOMAIN, 1)}, # type: ignore[arg-type]
)
device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id, identifiers={("Other", 1)}
config_entry_id=config_entry.entry_id,
identifiers={("Other", 1)}, # type: ignore[arg-type]
)
assert await hass.config_entries.async_setup(config_entry.entry_id)
assert device_registry.async_get_device({("Other", 1)}) is not None
assert device_registry.async_get_device({(DOMAIN, 1)}) is None
assert device_registry.async_get_device({("Other", 1)}) is not None # type: ignore[arg-type]
assert device_registry.async_get_device({(DOMAIN, 1)}) is None # type: ignore[arg-type]
assert device_registry.async_get_device({(DOMAIN, "1")}) is not None

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
"""Tests for the services module."""
from pyheos import CommandAuthenticationError, Heos, HeosError
from pyheos import CommandAuthenticationError, HeosError
import pytest
from homeassistant.components.heos.const import (
@ -13,11 +13,13 @@ from homeassistant.components.heos.const import (
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from . import MockHeos
from tests.common import MockConfigEntry
async def test_sign_in(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test the sign-in service."""
config_entry.add_to_hass(hass)
@ -34,7 +36,7 @@ async def test_sign_in(
async def test_sign_in_failed(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test sign-in service logs error when not connected."""
config_entry.add_to_hass(hass)
@ -56,7 +58,7 @@ async def test_sign_in_failed(
async def test_sign_in_unknown_error(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test sign-in service logs error for failure."""
config_entry.add_to_hass(hass)
@ -93,7 +95,7 @@ async def test_sign_in_not_loaded_raises(
async def test_sign_out(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test the sign-out service."""
config_entry.add_to_hass(hass)
@ -117,7 +119,7 @@ async def test_sign_out_not_loaded_raises(
async def test_sign_out_unknown_error(
hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
hass: HomeAssistant, config_entry: MockConfigEntry, controller: MockHeos
) -> None:
"""Test the sign-out service."""
config_entry.add_to_hass(hass)