/
/
/
1"""Tests for the AriaCast Receiver provider."""
2
3from __future__ import annotations
4
5from typing import Any
6from unittest.mock import MagicMock
7
8import pytest
9from music_assistant_models.errors import SetupFailedError
10
11from music_assistant.providers.ariacast_receiver import (
12 CONF_MASS_PLAYER_ID,
13 DEFAULT_ARIACAST_NAME,
14 AriaCastReceiver,
15)
16
17
18def _make_provider(
19 player_id: str = "player1", registered_player_ids: frozenset[str] = frozenset()
20) -> AriaCastReceiver:
21 """Create an AriaCastReceiver with mock dependencies."""
22 values: dict[str, Any] = {CONF_MASS_PLAYER_ID: player_id, "log_level": "GLOBAL"}
23 config = MagicMock()
24 config.get_value.side_effect = values.get
25 config.instance_id = "ariacast_receiver"
26 config.name = "AriaCast Receiver"
27 manifest = MagicMock()
28 manifest.domain = "ariacast_receiver"
29 mass = MagicMock()
30 # setup values resolve through the (empty) stored setup_data to config.get_value
31 mass.config.get.return_value = {}
32 mass.config.get_raw_provider_config_value.return_value = None
33 mass.players.get_player.side_effect = lambda pid: (
34 MagicMock() if pid in registered_player_ids else None
35 )
36 return AriaCastReceiver(mass, manifest, config)
37
38
39async def test_handle_async_init_requires_connected_player() -> None:
40 """Loading without a connected player fails with a translated setup error."""
41 provider = _make_provider(player_id="")
42
43 with pytest.raises(SetupFailedError) as excinfo:
44 await provider.handle_async_init()
45 assert excinfo.value.translation_key == "no_connected_player"
46 assert excinfo.value.translation_owner == "provider.ariacast_receiver"
47
48
49def test_advertised_name_follows_connected_player() -> None:
50 """The advertised receiver name is the connected player's display name."""
51 provider = _make_provider()
52 player = MagicMock()
53 player.display_name = "Living Room"
54 provider.mass.players.get_player.side_effect = None # type: ignore[attr-defined]
55 provider.mass.players.get_player.return_value = player # type: ignore[attr-defined]
56
57 assert provider._ariacast_name == "Living Room"
58
59
60def test_advertised_name_falls_back_while_player_unregistered() -> None:
61 """The default name applies while the connected player is not registered."""
62 provider = _make_provider()
63
64 assert provider._ariacast_name == DEFAULT_ARIACAST_NAME
65
66
67def test_target_player_is_the_configured_player() -> None:
68 """Without an active player the configured (registered) player is the target."""
69 provider = _make_provider(registered_player_ids=frozenset({"player1"}))
70
71 assert provider._get_target_player_id() == "player1"
72
73
74def test_target_player_is_none_while_configured_player_unavailable() -> None:
75 """An unregistered configured player yields no target instead of a dead queue."""
76 provider = _make_provider()
77
78 assert provider._get_target_player_id() is None
79