core/tests/components/plex/test_media_search.py

303 lines
11 KiB
Python

"""Tests for Plex server."""
from unittest.mock import patch
from plexapi.exceptions import BadRequest, NotFound
import pytest
from homeassistant.components.media_player.const import (
ATTR_MEDIA_CONTENT_ID,
ATTR_MEDIA_CONTENT_TYPE,
MEDIA_TYPE_EPISODE,
MEDIA_TYPE_MOVIE,
MEDIA_TYPE_MUSIC,
MEDIA_TYPE_PLAYLIST,
MEDIA_TYPE_VIDEO,
SERVICE_PLAY_MEDIA,
)
from homeassistant.components.plex.const import DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.exceptions import HomeAssistantError
async def test_media_lookups(
hass, mock_plex_server, requests_mock, playqueue_created, caplog
):
"""Test media lookups to Plex server."""
# Plex Key searches
media_player_id = hass.states.async_entity_ids("media_player")[0]
requests_mock.post("/playqueues", text=playqueue_created)
requests_mock.get("/player/playback/playMedia", status_code=200)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: DOMAIN,
ATTR_MEDIA_CONTENT_ID: 1,
},
True,
)
with pytest.raises(HomeAssistantError) as excinfo:
with patch("plexapi.server.PlexServer.fetchItem", side_effect=NotFound):
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: DOMAIN,
ATTR_MEDIA_CONTENT_ID: 123,
},
True,
)
assert "Media could not be found: 123" in str(excinfo.value)
# TV show searches
with pytest.raises(HomeAssistantError) as excinfo:
payload = '{"library_name": "Not a Library", "show_name": "TV Show"}'
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_EPISODE,
ATTR_MEDIA_CONTENT_ID: payload,
},
True,
)
assert f"Media could not be found: {payload}" in str(excinfo.value)
with patch("plexapi.library.LibrarySection.search") as search:
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_EPISODE,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "TV Shows", "show_name": "TV Show"}',
},
True,
)
search.assert_called_with(**{"show.title": "TV Show", "libtype": "show"})
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_EPISODE,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "TV Shows", "episode_name": "An Episode"}',
},
True,
)
search.assert_called_with(
**{"episode.title": "An Episode", "libtype": "episode"}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_EPISODE,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "TV Shows", "show_name": "TV Show", "season_number": 1}',
},
True,
)
search.assert_called_with(
**{"show.title": "TV Show", "season.index": 1, "libtype": "season"}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_EPISODE,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "TV Shows", "show_name": "TV Show", "season_number": 1, "episode_number": 3}',
},
True,
)
search.assert_called_with(
**{
"show.title": "TV Show",
"season.index": 1,
"episode.index": 3,
"libtype": "episode",
}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "artist_name": "Artist"}',
},
True,
)
search.assert_called_with(**{"artist.title": "Artist", "libtype": "artist"})
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "album_name": "Album"}',
},
True,
)
search.assert_called_with(**{"album.title": "Album", "libtype": "album"})
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "artist_name": "Artist", "track_name": "Track 3"}',
},
True,
)
search.assert_called_with(
**{"artist.title": "Artist", "track.title": "Track 3", "libtype": "track"}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "artist_name": "Artist", "album_name": "Album"}',
},
True,
)
search.assert_called_with(
**{"artist.title": "Artist", "album.title": "Album", "libtype": "album"}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "artist_name": "Artist", "album_name": "Album", "track_number": 3}',
},
True,
)
search.assert_called_with(
**{
"artist.title": "Artist",
"album.title": "Album",
"track.index": 3,
"libtype": "track",
}
)
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MUSIC,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Music", "artist_name": "Artist", "album_name": "Album", "track_name": "Track 3"}',
},
True,
)
search.assert_called_with(
**{
"artist.title": "Artist",
"album.title": "Album",
"track.title": "Track 3",
"libtype": "track",
}
)
# Movie searches
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_VIDEO,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Movies", "video_name": "Movie 1"}',
},
True,
)
search.assert_called_with(**{"movie.title": "Movie 1", "libtype": None})
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE,
ATTR_MEDIA_CONTENT_ID: '{"library_name": "Movies", "title": "Movie 1"}',
},
True,
)
search.assert_called_with(**{"title": "Movie 1", "libtype": None})
# TV show searches
with pytest.raises(HomeAssistantError) as excinfo:
payload = '{"library_name": "Movies", "title": "Not a Movie"}'
with patch("plexapi.library.LibrarySection.search", side_effect=BadRequest):
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_VIDEO,
ATTR_MEDIA_CONTENT_ID: payload,
},
True,
)
assert "Problem in query" in caplog.text
assert f"Media could not be found: {payload}" in str(excinfo.value)
# Playlist searches
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_PLAYLIST,
ATTR_MEDIA_CONTENT_ID: '{"playlist_name": "Playlist 1"}',
},
True,
)
with pytest.raises(HomeAssistantError) as excinfo:
payload = '{"playlist_name": "Not a Playlist"}'
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_PLAYLIST,
ATTR_MEDIA_CONTENT_ID: payload,
},
True,
)
assert "Playlist 'Not a Playlist' not found" in caplog.text
assert f"Media could not be found: {payload}" in str(excinfo.value)
with pytest.raises(HomeAssistantError) as excinfo:
payload = "{}"
assert await hass.services.async_call(
Platform.MEDIA_PLAYER,
SERVICE_PLAY_MEDIA,
{
ATTR_ENTITY_ID: media_player_id,
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_PLAYLIST,
ATTR_MEDIA_CONTENT_ID: payload,
},
True,
)
assert "Must specify 'playlist_name' for this search" in caplog.text
assert f"Media could not be found: {payload}" in str(excinfo.value)