core/tests/components/plex/test_services.py

198 lines
7.0 KiB
Python

"""Tests for various Plex services."""
from unittest.mock import patch
from plexapi.exceptions import NotFound
import pytest
from homeassistant.components.media_player.const import MEDIA_TYPE_MUSIC
from homeassistant.components.plex.const import (
CONF_SERVER,
CONF_SERVER_IDENTIFIER,
DOMAIN,
PLEX_SERVER_CONFIG,
SERVICE_REFRESH_LIBRARY,
SERVICE_SCAN_CLIENTS,
)
from homeassistant.components.plex.services import play_on_sonos
from homeassistant.const import CONF_URL
from homeassistant.exceptions import HomeAssistantError
from .const import DEFAULT_OPTIONS, SECONDARY_DATA
from tests.common import MockConfigEntry
async def test_refresh_library(
hass,
mock_plex_server,
setup_plex_server,
requests_mock,
empty_payload,
plex_server_accounts,
plex_server_base,
):
"""Test refresh_library service call."""
url = mock_plex_server.url_in_use
refresh = requests_mock.get(f"{url}/library/sections/1/refresh", status_code=200)
# Test with non-existent server
with pytest.raises(HomeAssistantError):
assert await hass.services.async_call(
DOMAIN,
SERVICE_REFRESH_LIBRARY,
{"server_name": "Not a Server", "library_name": "Movies"},
True,
)
assert not refresh.called
# Test with non-existent library
assert await hass.services.async_call(
DOMAIN,
SERVICE_REFRESH_LIBRARY,
{"library_name": "Not a Library"},
True,
)
assert not refresh.called
# Test with valid library
assert await hass.services.async_call(
DOMAIN,
SERVICE_REFRESH_LIBRARY,
{"library_name": "Movies"},
True,
)
assert refresh.call_count == 1
# Add a second configured server
secondary_url = SECONDARY_DATA[PLEX_SERVER_CONFIG][CONF_URL]
secondary_name = SECONDARY_DATA[CONF_SERVER]
secondary_id = SECONDARY_DATA[CONF_SERVER_IDENTIFIER]
requests_mock.get(
secondary_url,
text=plex_server_base.format(
name=secondary_name, machine_identifier=secondary_id
),
)
requests_mock.get(f"{secondary_url}/accounts", text=plex_server_accounts)
requests_mock.get(f"{secondary_url}/clients", text=empty_payload)
requests_mock.get(f"{secondary_url}/status/sessions", text=empty_payload)
entry_2 = MockConfigEntry(
domain=DOMAIN,
data=SECONDARY_DATA,
options=DEFAULT_OPTIONS,
unique_id=SECONDARY_DATA["server_id"],
)
await setup_plex_server(config_entry=entry_2)
# Test multiple servers available but none specified
with pytest.raises(HomeAssistantError) as excinfo:
assert await hass.services.async_call(
DOMAIN,
SERVICE_REFRESH_LIBRARY,
{"library_name": "Movies"},
True,
)
assert "Multiple Plex servers configured" in str(excinfo.value)
assert refresh.call_count == 1
async def test_scan_clients(hass, mock_plex_server):
"""Test scan_for_clients service call."""
assert await hass.services.async_call(
DOMAIN,
SERVICE_SCAN_CLIENTS,
blocking=True,
)
async def test_sonos_play_media(
hass,
entry,
setup_plex_server,
requests_mock,
empty_payload,
playqueue_1234,
playqueue_created,
plextv_account,
sonos_resources,
):
"""Test playback from a Sonos media_player.play_media call."""
media_content_id = (
'{"library_name": "Music", "artist_name": "Artist", "album_name": "Album"}'
)
sonos_speaker_name = "Zone A"
requests_mock.get("https://plex.tv/users/account", text=plextv_account)
requests_mock.post("/playqueues", text=playqueue_created)
playback_mock = requests_mock.get("/player/playback/playMedia", status_code=200)
# Test with no Plex integration available
with pytest.raises(HomeAssistantError) as excinfo:
play_on_sonos(hass, MEDIA_TYPE_MUSIC, media_content_id, sonos_speaker_name)
assert "Plex integration not configured" in str(excinfo.value)
with patch(
"homeassistant.components.plex.PlexServer.connect", side_effect=NotFound
):
# Initialize Plex integration without setting up a server
with pytest.raises(AssertionError):
await setup_plex_server()
# Test with no Plex servers available
with pytest.raises(HomeAssistantError) as excinfo:
play_on_sonos(hass, MEDIA_TYPE_MUSIC, media_content_id, sonos_speaker_name)
assert "No Plex servers available" in str(excinfo.value)
# Complete setup of a Plex server
await hass.config_entries.async_unload(entry.entry_id)
mock_plex_server = await setup_plex_server()
# Test with no speakers available
requests_mock.get("https://sonos.plex.tv/resources", text=empty_payload)
with pytest.raises(HomeAssistantError) as excinfo:
play_on_sonos(hass, MEDIA_TYPE_MUSIC, media_content_id, sonos_speaker_name)
assert f"Sonos speaker '{sonos_speaker_name}' is not associated with" in str(
excinfo.value
)
assert playback_mock.call_count == 0
# Test with speakers available
requests_mock.get("https://sonos.plex.tv/resources", text=sonos_resources)
with patch.object(mock_plex_server.account, "_sonos_cache_timestamp", 0):
play_on_sonos(hass, MEDIA_TYPE_MUSIC, media_content_id, sonos_speaker_name)
assert playback_mock.call_count == 1
# Test with speakers available and media key payload
play_on_sonos(hass, MEDIA_TYPE_MUSIC, "100", sonos_speaker_name)
assert playback_mock.call_count == 2
# Test with speakers available and Plex server specified
content_id_with_server = '{"plex_server": "Plex Server 1", "library_name": "Music", "artist_name": "Artist", "album_name": "Album"}'
play_on_sonos(hass, MEDIA_TYPE_MUSIC, content_id_with_server, sonos_speaker_name)
assert playback_mock.call_count == 3
# Test with speakers available but media not found
content_id_bad_media = '{"library_name": "Music", "artist_name": "Not an Artist"}'
with pytest.raises(HomeAssistantError) as excinfo:
play_on_sonos(hass, MEDIA_TYPE_MUSIC, content_id_bad_media, sonos_speaker_name)
assert "Plex media not found" in str(excinfo.value)
assert playback_mock.call_count == 3
# Test with speakers available and playqueue
requests_mock.get("https://1.2.3.4:32400/playQueues/1234", text=playqueue_1234)
content_id_with_playqueue = '{"playqueue_id": 1234}'
play_on_sonos(hass, MEDIA_TYPE_MUSIC, content_id_with_playqueue, sonos_speaker_name)
assert playback_mock.call_count == 4
# Test with speakers available and invalid playqueue
requests_mock.get("https://1.2.3.4:32400/playQueues/1235", status_code=404)
content_id_with_playqueue = '{"playqueue_id": 1235}'
with pytest.raises(HomeAssistantError) as excinfo:
play_on_sonos(
hass, MEDIA_TYPE_MUSIC, content_id_with_playqueue, sonos_speaker_name
)
assert "PlayQueue '1235' could not be found" in str(excinfo.value)
assert playback_mock.call_count == 4