mirror of https://github.com/home-assistant/core
290 lines
9.4 KiB
Python
290 lines
9.4 KiB
Python
"""Setup the squeezebox tests."""
|
|
|
|
from collections.abc import Generator
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components.media_player import MediaType
|
|
from homeassistant.components.squeezebox import const
|
|
from homeassistant.components.squeezebox.browse_media import (
|
|
MEDIA_TYPE_TO_SQUEEZEBOX,
|
|
SQUEEZEBOX_ID_BY_TYPE,
|
|
)
|
|
from homeassistant.components.squeezebox.const import (
|
|
STATUS_QUERY_LIBRARYNAME,
|
|
STATUS_QUERY_MAC,
|
|
STATUS_QUERY_UUID,
|
|
STATUS_QUERY_VERSION,
|
|
STATUS_SENSOR_INFO_TOTAL_ALBUMS,
|
|
STATUS_SENSOR_INFO_TOTAL_ARTISTS,
|
|
STATUS_SENSOR_INFO_TOTAL_DURATION,
|
|
STATUS_SENSOR_INFO_TOTAL_GENRES,
|
|
STATUS_SENSOR_INFO_TOTAL_SONGS,
|
|
STATUS_SENSOR_LASTSCAN,
|
|
STATUS_SENSOR_OTHER_PLAYER_COUNT,
|
|
STATUS_SENSOR_PLAYER_COUNT,
|
|
STATUS_SENSOR_RESCAN,
|
|
)
|
|
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.device_registry import format_mac
|
|
|
|
# from homeassistant.setup import async_setup_component
|
|
from tests.common import MockConfigEntry
|
|
|
|
TEST_HOST = "1.2.3.4"
|
|
TEST_PORT = "9000"
|
|
TEST_USE_HTTPS = False
|
|
SERVER_UUIDS = [
|
|
"12345678-1234-1234-1234-123456789012",
|
|
"87654321-4321-4321-4321-210987654321",
|
|
]
|
|
TEST_MAC = ["aa:bb:cc:dd:ee:ff", "ff:ee:dd:cc:bb:aa"]
|
|
TEST_PLAYER_NAME = "Test Player"
|
|
TEST_SERVER_NAME = "Test Server"
|
|
FAKE_VALID_ITEM_ID = "1234"
|
|
FAKE_INVALID_ITEM_ID = "4321"
|
|
|
|
FAKE_IP = "42.42.42.42"
|
|
FAKE_MAC = "deadbeefdead"
|
|
FAKE_UUID = "deadbeefdeadbeefbeefdeafbeef42"
|
|
FAKE_PORT = 9000
|
|
FAKE_VERSION = "42.0"
|
|
|
|
FAKE_QUERY_RESPONSE = {
|
|
STATUS_QUERY_UUID: FAKE_UUID,
|
|
STATUS_QUERY_MAC: FAKE_MAC,
|
|
STATUS_QUERY_VERSION: FAKE_VERSION,
|
|
STATUS_SENSOR_RESCAN: 1,
|
|
STATUS_SENSOR_LASTSCAN: 0,
|
|
STATUS_QUERY_LIBRARYNAME: "FakeLib",
|
|
STATUS_SENSOR_INFO_TOTAL_ALBUMS: 4,
|
|
STATUS_SENSOR_INFO_TOTAL_ARTISTS: 2,
|
|
STATUS_SENSOR_INFO_TOTAL_DURATION: 500,
|
|
STATUS_SENSOR_INFO_TOTAL_GENRES: 1,
|
|
STATUS_SENSOR_INFO_TOTAL_SONGS: 42,
|
|
STATUS_SENSOR_PLAYER_COUNT: 10,
|
|
STATUS_SENSOR_OTHER_PLAYER_COUNT: 0,
|
|
"players_loop": [
|
|
{
|
|
"isplaying": 0,
|
|
"name": "SqueezeLite-HA-Addon",
|
|
"seq_no": 0,
|
|
"modelname": "SqueezeLite-HA-Addon",
|
|
"playerindex": "status",
|
|
"model": "squeezelite",
|
|
"uuid": FAKE_UUID,
|
|
"canpoweroff": 1,
|
|
"ip": "192.168.78.86:57700",
|
|
"displaytype": "none",
|
|
"playerid": "f9:23:cd:37:c5:ff",
|
|
"power": 0,
|
|
"isplayer": 1,
|
|
"connected": 1,
|
|
"firmware": "v2.0.0-1488",
|
|
}
|
|
],
|
|
"count": 1,
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
|
"""Override async_setup_entry."""
|
|
with patch(
|
|
"homeassistant.components.squeezebox.async_setup_entry", return_value=True
|
|
) as mock_setup_entry:
|
|
yield mock_setup_entry
|
|
|
|
|
|
@pytest.fixture
|
|
def config_entry(hass: HomeAssistant) -> MockConfigEntry:
|
|
"""Add the squeezebox mock config entry to hass."""
|
|
config_entry = MockConfigEntry(
|
|
domain=const.DOMAIN,
|
|
unique_id=SERVER_UUIDS[0],
|
|
data={
|
|
CONF_HOST: TEST_HOST,
|
|
CONF_PORT: TEST_PORT,
|
|
const.CONF_HTTPS: TEST_USE_HTTPS,
|
|
},
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
return config_entry
|
|
|
|
|
|
async def mock_async_browse(
|
|
media_type: MediaType, limit: int, browse_id: tuple | None = None
|
|
) -> dict | None:
|
|
"""Mock the async_browse method of pysqueezebox.Player."""
|
|
child_types = {
|
|
"favorites": "favorites",
|
|
"new music": "album",
|
|
"albums": "album",
|
|
"album": "track",
|
|
"genres": "genre",
|
|
"genre": "album",
|
|
"artists": "artist",
|
|
"artist": "album",
|
|
"titles": "title",
|
|
"title": "title",
|
|
"playlists": "playlist",
|
|
"playlist": "title",
|
|
}
|
|
fake_items = [
|
|
{
|
|
"title": "Fake Item 1",
|
|
"id": FAKE_VALID_ITEM_ID,
|
|
"hasitems": False,
|
|
"item_type": child_types[media_type],
|
|
"artwork_track_id": "b35bb9e9",
|
|
"url": "file:///var/lib/squeezeboxserver/music/track_1.mp3",
|
|
},
|
|
{
|
|
"title": "Fake Item 2",
|
|
"id": FAKE_VALID_ITEM_ID + "_2",
|
|
"hasitems": media_type == "favorites",
|
|
"item_type": child_types[media_type],
|
|
"image_url": "http://lms.internal:9000/html/images/favorites.png",
|
|
"url": "file:///var/lib/squeezeboxserver/music/track_2.mp3",
|
|
},
|
|
{
|
|
"title": "Fake Item 3",
|
|
"id": FAKE_VALID_ITEM_ID + "_3",
|
|
"hasitems": media_type == "favorites",
|
|
"album_id": FAKE_VALID_ITEM_ID if media_type == "favorites" else None,
|
|
"url": "file:///var/lib/squeezeboxserver/music/track_3.mp3",
|
|
},
|
|
]
|
|
|
|
if browse_id:
|
|
search_type, search_id = browse_id
|
|
if search_id:
|
|
if search_type == "playlist_id":
|
|
return (
|
|
{
|
|
"title": "Fake Item 1",
|
|
"items": fake_items,
|
|
}
|
|
if search_id == FAKE_VALID_ITEM_ID
|
|
else None
|
|
)
|
|
if search_type in SQUEEZEBOX_ID_BY_TYPE.values():
|
|
for item in fake_items:
|
|
if item["id"] == search_id:
|
|
return {
|
|
"title": item["title"],
|
|
"items": [item],
|
|
}
|
|
return None
|
|
if search_type in SQUEEZEBOX_ID_BY_TYPE.values():
|
|
return {
|
|
"title": search_type,
|
|
"items": fake_items,
|
|
}
|
|
return None
|
|
if media_type in MEDIA_TYPE_TO_SQUEEZEBOX.values():
|
|
return {
|
|
"title": media_type,
|
|
"items": fake_items,
|
|
}
|
|
return None
|
|
|
|
|
|
@pytest.fixture
|
|
def player() -> MagicMock:
|
|
"""Return a mock player."""
|
|
return mock_pysqueezebox_player()
|
|
|
|
|
|
@pytest.fixture
|
|
def player_factory() -> MagicMock:
|
|
"""Return a factory for creating mock players."""
|
|
return mock_pysqueezebox_player
|
|
|
|
|
|
def mock_pysqueezebox_player(uuid: str) -> MagicMock:
|
|
"""Mock a Lyrion Media Server player."""
|
|
with patch(
|
|
"homeassistant.components.squeezebox.Player", autospec=True
|
|
) as mock_player:
|
|
mock_player.async_browse = AsyncMock(side_effect=mock_async_browse)
|
|
mock_player.generate_image_url_from_track_id = MagicMock(
|
|
return_value="http://lms.internal:9000/html/images/favorites.png"
|
|
)
|
|
mock_player.name = TEST_PLAYER_NAME
|
|
mock_player.player_id = uuid
|
|
mock_player.mode = "stop"
|
|
mock_player.playlist = None
|
|
mock_player.album = None
|
|
mock_player.artist = None
|
|
mock_player.remote_title = None
|
|
mock_player.title = None
|
|
mock_player.image_url = None
|
|
mock_player.model = "SqueezeLite"
|
|
|
|
return mock_player
|
|
|
|
|
|
@pytest.fixture
|
|
def lms_factory(player_factory: MagicMock) -> MagicMock:
|
|
"""Return a factory for creating mock Lyrion Media Servers with arbitrary number of players."""
|
|
return lambda player_count, uuid: mock_pysqueezebox_server(
|
|
player_factory, player_count, uuid
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def lms(player_factory: MagicMock) -> MagicMock:
|
|
"""Mock a Lyrion Media Server with one mock player attached."""
|
|
return mock_pysqueezebox_server(player_factory, 1, uuid=TEST_MAC[0])
|
|
|
|
|
|
def mock_pysqueezebox_server(
|
|
player_factory: MagicMock, player_count: int, uuid: str
|
|
) -> MagicMock:
|
|
"""Create a mock Lyrion Media Server with the given number of mock players attached."""
|
|
with patch("homeassistant.components.squeezebox.Server", autospec=True) as mock_lms:
|
|
players = [player_factory(TEST_MAC[index]) for index in range(player_count)]
|
|
mock_lms.async_get_players = AsyncMock(return_value=players)
|
|
|
|
mock_lms.uuid = uuid
|
|
mock_lms.name = TEST_SERVER_NAME
|
|
mock_lms.async_query = AsyncMock(return_value={"uuid": format_mac(uuid)})
|
|
mock_lms.async_status = AsyncMock(return_value={"uuid": format_mac(uuid)})
|
|
return mock_lms
|
|
|
|
|
|
async def configure_squeezebox_media_player_platform(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
lms: MagicMock,
|
|
) -> None:
|
|
"""Configure a squeezebox config entry with appropriate mocks for media_player."""
|
|
with (
|
|
patch("homeassistant.components.squeezebox.PLATFORMS", [Platform.MEDIA_PLAYER]),
|
|
patch("homeassistant.components.squeezebox.Server", return_value=lms),
|
|
):
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done(wait_background_tasks=True)
|
|
|
|
|
|
@pytest.fixture
|
|
async def configured_player(
|
|
hass: HomeAssistant, config_entry: MockConfigEntry, lms: MagicMock
|
|
) -> MagicMock:
|
|
"""Fixture mocking calls to pysqueezebox Player from a configured squeezebox."""
|
|
await configure_squeezebox_media_player_platform(hass, config_entry, lms)
|
|
return (await lms.async_get_players())[0]
|
|
|
|
|
|
@pytest.fixture
|
|
async def configured_players(
|
|
hass: HomeAssistant, config_entry: MockConfigEntry, lms_factory: MagicMock
|
|
) -> list[MagicMock]:
|
|
"""Fixture mocking calls to two pysqueezebox Players from a configured squeezebox."""
|
|
lms = lms_factory(2, uuid=SERVER_UUIDS[0])
|
|
await configure_squeezebox_media_player_platform(hass, config_entry, lms)
|
|
return await lms.async_get_players()
|