"""Tests for Plex player playback methods/services.""" from http import HTTPStatus from unittest.mock import patch import pytest from homeassistant.components.media_player.const import ( ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE, DOMAIN as MP_DOMAIN, MEDIA_TYPE_MOVIE, SERVICE_PLAY_MEDIA, ) from homeassistant.const import ATTR_ENTITY_ID from homeassistant.exceptions import HomeAssistantError class MockPlexMedia: """Minimal mock of plexapi media object.""" key = "key" def __init__(self, title, mediatype): """Initialize the instance.""" self.listType = mediatype self.title = title self.type = mediatype def section(self): """Return the LibrarySection.""" return MockPlexLibrarySection() class MockPlexLibrarySection: """Minimal mock of plexapi LibrarySection.""" uuid = "00000000-0000-0000-0000-000000000000" async def test_media_player_playback( hass, setup_plex_server, requests_mock, playqueue_created, player_plexweb_resources, caplog, ): """Test playing media on a Plex media_player.""" requests_mock.get("http://1.2.3.5:32400/resources", text=player_plexweb_resources) await setup_plex_server() media_player = "media_player.plex_plex_web_chrome" requests_mock.post("/playqueues", text=playqueue_created) requests_mock.get("/player/playback/playMedia", status_code=HTTPStatus.OK) # Test media lookup failure payload = '{"library_name": "Movies", "title": "Movie 1" }' with patch("plexapi.library.LibrarySection.search", return_value=None): with pytest.raises(HomeAssistantError) as excinfo: assert await hass.services.async_call( MP_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: media_player, ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE, ATTR_MEDIA_CONTENT_ID: payload, }, True, ) assert f"Media could not be found: {payload}" in str(excinfo.value) movie1 = MockPlexMedia("Movie", "movie") movie2 = MockPlexMedia("Movie II", "movie") movie3 = MockPlexMedia("Movie III", "movie") # Test movie success movies = [movie1] with patch("plexapi.library.LibrarySection.search", return_value=movies): assert await hass.services.async_call( MP_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: media_player, ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE, ATTR_MEDIA_CONTENT_ID: '{"library_name": "Movies", "title": "Movie 1" }', }, True, ) # Test multiple choices with exact match movies = [movie1, movie2] with patch("plexapi.library.LibrarySection.search", return_value=movies), patch( "homeassistant.components.plex.server.PlexServer.create_playqueue" ) as mock_create_playqueue: assert await hass.services.async_call( MP_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: media_player, ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE, ATTR_MEDIA_CONTENT_ID: '{"library_name": "Movies", "title": "Movie" }', }, True, ) assert mock_create_playqueue.call_args.args == (movie1,) # Test multiple choices without exact match movies = [movie2, movie3] with pytest.raises(HomeAssistantError) as excinfo: payload = '{"library_name": "Movies", "title": "Movie" }' with patch("plexapi.library.LibrarySection.search", return_value=movies): assert await hass.services.async_call( MP_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: media_player, ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE, ATTR_MEDIA_CONTENT_ID: payload, }, True, ) assert f"Media could not be found: {payload}" in str(excinfo.value) assert "Multiple matches, make content_id more specific" in caplog.text # Test multiple choices with allow_multiple movies = [movie1, movie2, movie3] with patch("plexapi.library.LibrarySection.search", return_value=movies), patch( "homeassistant.components.plex.server.PlexServer.create_playqueue" ) as mock_create_playqueue: assert await hass.services.async_call( MP_DOMAIN, SERVICE_PLAY_MEDIA, { ATTR_ENTITY_ID: media_player, ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_MOVIE, ATTR_MEDIA_CONTENT_ID: '{"library_name": "Movies", "title": "Movie", "allow_multiple": true }', }, True, ) assert mock_create_playqueue.call_args.args == (movies,)