mirror of https://github.com/home-assistant/core
181 lines
6.3 KiB
Python
181 lines
6.3 KiB
Python
"""Tests for the Sonos Media Player platform."""
|
|
|
|
import json
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components.media_player import (
|
|
ATTR_MEDIA_CONTENT_ID,
|
|
ATTR_MEDIA_CONTENT_TYPE,
|
|
ATTR_MEDIA_ENQUEUE,
|
|
DOMAIN as MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
MediaPlayerEnqueue,
|
|
MediaType,
|
|
)
|
|
from homeassistant.components.plex import DOMAIN as PLEX_DOMAIN, PLEX_URI_SCHEME
|
|
from homeassistant.components.sonos.media_player import LONG_SERVICE_TIMEOUT
|
|
from homeassistant.const import ATTR_ENTITY_ID
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import HomeAssistantError
|
|
|
|
from .conftest import MockSoCo
|
|
|
|
|
|
async def test_plex_play_media(
|
|
hass: HomeAssistant, soco: MockSoCo, async_autosetup_sonos
|
|
) -> None:
|
|
"""Test playing media via the Plex integration."""
|
|
mock_plex_server = Mock()
|
|
mock_lookup = mock_plex_server.lookup_media
|
|
|
|
media_player = "media_player.zone_a"
|
|
media_content_id = (
|
|
'{"library_name": "Music", "artist_name": "Artist", "album_name": "Album"}'
|
|
)
|
|
|
|
with (
|
|
patch(
|
|
"homeassistant.components.plex.services.get_plex_server",
|
|
return_value=mock_plex_server,
|
|
),
|
|
patch("soco.plugins.plex.PlexPlugin.add_to_queue") as mock_add_to_queue,
|
|
patch(
|
|
"homeassistant.components.sonos.media_player.SonosMediaPlayerEntity.set_shuffle"
|
|
) as mock_shuffle,
|
|
):
|
|
# Test successful Plex service call
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: f"{PLEX_URI_SCHEME}{media_content_id}",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert len(mock_lookup.mock_calls) == 1
|
|
assert len(mock_add_to_queue.mock_calls) == 1
|
|
assert not mock_shuffle.called
|
|
assert mock_lookup.mock_calls[0][1][0] == MediaType.MUSIC
|
|
assert mock_lookup.mock_calls[0][2] == json.loads(media_content_id)
|
|
assert soco.clear_queue.call_count == 1
|
|
assert soco.play_from_queue.call_count == 1
|
|
soco.play_from_queue.assert_called_with(0)
|
|
|
|
# Test handling shuffle in payload
|
|
mock_lookup.reset_mock()
|
|
mock_add_to_queue.reset_mock()
|
|
shuffle_media_content_id = (
|
|
'{"library_name": "Music", "artist_name": "Artist", '
|
|
'"album_name": "Album", "shuffle": 1}'
|
|
)
|
|
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: f"{PLEX_URI_SCHEME}{shuffle_media_content_id}",
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert mock_shuffle.called
|
|
assert len(mock_lookup.mock_calls) == 1
|
|
assert len(mock_add_to_queue.mock_calls) == 1
|
|
assert mock_lookup.mock_calls[0][1][0] == MediaType.MUSIC
|
|
assert mock_lookup.mock_calls[0][2] == json.loads(media_content_id)
|
|
|
|
# Test failed Plex service call
|
|
mock_lookup.reset_mock()
|
|
mock_lookup.side_effect = HomeAssistantError
|
|
mock_add_to_queue.reset_mock()
|
|
|
|
with pytest.raises(HomeAssistantError):
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: f"{PLEX_URI_SCHEME}{media_content_id}",
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert mock_lookup.called
|
|
assert not mock_add_to_queue.called
|
|
|
|
# Test new media browser payload format
|
|
mock_lookup.reset_mock()
|
|
mock_lookup.side_effect = None
|
|
mock_add_to_queue.reset_mock()
|
|
|
|
server_id = "unique_id_123"
|
|
plex_item_key = 300
|
|
|
|
with patch(
|
|
"homeassistant.components.plex.services.get_plex_server",
|
|
return_value=mock_plex_server,
|
|
):
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: (
|
|
f"{PLEX_URI_SCHEME}{server_id}/{plex_item_key}?shuffle=1"
|
|
),
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert len(mock_lookup.mock_calls) == 1
|
|
assert len(mock_add_to_queue.mock_calls) == 1
|
|
assert mock_shuffle.called
|
|
assert mock_lookup.mock_calls[0][1][0] == PLEX_DOMAIN
|
|
assert mock_lookup.mock_calls[0][2] == {"plex_key": plex_item_key}
|
|
|
|
mock_add_to_queue.reset_mock()
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: f"{PLEX_URI_SCHEME}{media_content_id}",
|
|
ATTR_MEDIA_ENQUEUE: MediaPlayerEnqueue.ADD,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert mock_add_to_queue.call_count == 1
|
|
mock_add_to_queue.assert_called_with(
|
|
mock_lookup(), timeout=LONG_SERVICE_TIMEOUT
|
|
)
|
|
|
|
soco.play_from_queue.reset_mock()
|
|
mock_add_to_queue.reset_mock()
|
|
mock_add_to_queue.return_value = 9
|
|
await hass.services.async_call(
|
|
MP_DOMAIN,
|
|
SERVICE_PLAY_MEDIA,
|
|
{
|
|
ATTR_ENTITY_ID: media_player,
|
|
ATTR_MEDIA_CONTENT_TYPE: MediaType.MUSIC,
|
|
ATTR_MEDIA_CONTENT_ID: f"{PLEX_URI_SCHEME}{media_content_id}",
|
|
ATTR_MEDIA_ENQUEUE: MediaPlayerEnqueue.PLAY,
|
|
},
|
|
blocking=True,
|
|
)
|
|
assert mock_add_to_queue.call_count == 1
|
|
mock_add_to_queue.assert_called_with(
|
|
mock_lookup(), position=1, timeout=LONG_SERVICE_TIMEOUT
|
|
)
|
|
assert soco.play_from_queue.call_count == 1
|
|
soco.play_from_queue.assert_called_with(mock_add_to_queue.return_value - 1)
|