mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Fix Sonos album artwork performance (#116391)
This commit is contained in:
parent
5c263b039e
commit
1ad2e4951d
@ -53,14 +53,16 @@ def get_thumbnail_url_full(
|
||||
media_content_type: str,
|
||||
media_content_id: str,
|
||||
media_image_id: str | None = None,
|
||||
item: MusicServiceItem | None = None,
|
||||
) -> str | None:
|
||||
"""Get thumbnail URL."""
|
||||
if is_internal:
|
||||
item = get_media(
|
||||
media.library,
|
||||
media_content_id,
|
||||
media_content_type,
|
||||
)
|
||||
if not item:
|
||||
item = get_media(
|
||||
media.library,
|
||||
media_content_id,
|
||||
media_content_type,
|
||||
)
|
||||
return urllib.parse.unquote(getattr(item, "album_art_uri", ""))
|
||||
|
||||
return urllib.parse.unquote(
|
||||
@ -255,7 +257,7 @@ def item_payload(item: DidlObject, get_thumbnail_url=None) -> BrowseMedia:
|
||||
content_id = get_content_id(item)
|
||||
thumbnail = None
|
||||
if getattr(item, "album_art_uri", None):
|
||||
thumbnail = get_thumbnail_url(media_class, content_id)
|
||||
thumbnail = get_thumbnail_url(media_class, content_id, item=item)
|
||||
|
||||
return BrowseMedia(
|
||||
title=item.title,
|
||||
|
@ -316,12 +316,35 @@ def sonos_favorites_fixture() -> SearchResult:
|
||||
class MockMusicServiceItem:
|
||||
"""Mocks a Soco MusicServiceItem."""
|
||||
|
||||
def __init__(self, title: str, item_id: str, parent_id: str, item_class: str):
|
||||
def __init__(
|
||||
self,
|
||||
title: str,
|
||||
item_id: str,
|
||||
parent_id: str,
|
||||
item_class: str,
|
||||
album_art_uri: None | str = None,
|
||||
):
|
||||
"""Initialize the mock item."""
|
||||
self.title = title
|
||||
self.item_id = item_id
|
||||
self.item_class = item_class
|
||||
self.parent_id = parent_id
|
||||
self.album_art_uri: None | str = album_art_uri
|
||||
|
||||
|
||||
def list_from_json_fixture(file_name: str) -> list[MockMusicServiceItem]:
|
||||
"""Create a list of music service items from a json fixture file."""
|
||||
item_list = load_json_value_fixture(file_name, "sonos")
|
||||
return [
|
||||
MockMusicServiceItem(
|
||||
item.get("title"),
|
||||
item.get("item_id"),
|
||||
item.get("parent_id"),
|
||||
item.get("item_class"),
|
||||
item.get("album_art_uri"),
|
||||
)
|
||||
for item in item_list
|
||||
]
|
||||
|
||||
|
||||
def mock_browse_by_idstring(
|
||||
@ -398,6 +421,10 @@ def mock_browse_by_idstring(
|
||||
"object.container.album.musicAlbum",
|
||||
),
|
||||
]
|
||||
if search_type == "tracks":
|
||||
return list_from_json_fixture("music_library_tracks.json")
|
||||
if search_type == "albums" and idstring == "A:ALBUM":
|
||||
return list_from_json_fixture("music_library_albums.json")
|
||||
return []
|
||||
|
||||
|
||||
@ -416,13 +443,23 @@ def mock_get_music_library_information(
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(name="music_library_browse_categories")
|
||||
def music_library_browse_categories() -> list[MockMusicServiceItem]:
|
||||
"""Create fixture for top-level music library categories."""
|
||||
return list_from_json_fixture("music_library_categories.json")
|
||||
|
||||
|
||||
@pytest.fixture(name="music_library")
|
||||
def music_library_fixture(sonos_favorites: SearchResult) -> Mock:
|
||||
def music_library_fixture(
|
||||
sonos_favorites: SearchResult,
|
||||
music_library_browse_categories: list[MockMusicServiceItem],
|
||||
) -> Mock:
|
||||
"""Create music_library fixture."""
|
||||
music_library = MagicMock()
|
||||
music_library.get_sonos_favorites.return_value = sonos_favorites
|
||||
music_library.browse_by_idstring = mock_browse_by_idstring
|
||||
music_library.browse_by_idstring = Mock(side_effect=mock_browse_by_idstring)
|
||||
music_library.get_music_library_information = mock_get_music_library_information
|
||||
music_library.browse = Mock(return_value=music_library_browse_categories)
|
||||
return music_library
|
||||
|
||||
|
||||
|
23
tests/components/sonos/fixtures/music_library_albums.json
Normal file
23
tests/components/sonos/fixtures/music_library_albums.json
Normal file
@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"title": "A Hard Day's Night",
|
||||
"item_id": "A:ALBUM/A%20Hard%20Day's%20Night",
|
||||
"parent_id": "A:ALBUM",
|
||||
"item_class": "object.container.album.musicAlbum",
|
||||
"album_art_uri": "http://192.168.42.2:1400/getaa?u=x-file-cifs%3a%2f%2f192.168.42.100%2fmusic%2fThe%2520Beatles%2fA%2520Hard%2520Day's%2520Night%2f01%2520A%2520Hard%2520Day's%2520Night%25201.m4a&v=53"
|
||||
},
|
||||
{
|
||||
"title": "Abbey Road",
|
||||
"item_id": "A:ALBUM/Abbey%20Road",
|
||||
"parent_id": "A:ALBUM",
|
||||
"item_class": "object.container.album.musicAlbum",
|
||||
"album_art_uri": "http://192.168.42.2:1400/getaa?u=x-file-cifs%3a%2f%2f192.168.42.100%2fmusic%2fThe%2520Beatles%2fAbbeyA%2520Road%2f01%2520Come%2520Together.m4a&v=53"
|
||||
},
|
||||
{
|
||||
"title": "Between Good And Evil",
|
||||
"item_id": "A:ALBUM/Between%20Good%20And%20Evil",
|
||||
"parent_id": "A:ALBUM",
|
||||
"item_class": "object.container.album.musicAlbum",
|
||||
"album_art_uri": "http://192.168.42.2:1400/getaa?u=x-file-cifs%3a%2f%2f192.168.42.100%2fmusic%2fSantana%2fA%2520Between%2520Good%2520And%2520Evil%2f02%2520A%2520Persuasion.m4a&v=53"
|
||||
}
|
||||
]
|
@ -0,0 +1,44 @@
|
||||
[
|
||||
{
|
||||
"title": "Contributing Artists",
|
||||
"item_id": "A:ARTIST",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
},
|
||||
{
|
||||
"title": "Artists",
|
||||
"item_id": "A:ALBUMARTIST",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
},
|
||||
{
|
||||
"title": "Albums",
|
||||
"item_id": "A:ALBUM",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
},
|
||||
{
|
||||
"title": "Genres",
|
||||
"item_id": "A:GENRE",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
},
|
||||
{
|
||||
"title": "Composers",
|
||||
"item_id": "A:COMPOSER",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
},
|
||||
{
|
||||
"title": "Tracks",
|
||||
"item_id": "A:TRACKS",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container.playlistContainer"
|
||||
},
|
||||
{
|
||||
"title": "Playlists",
|
||||
"item_id": "A:PLAYLISTS",
|
||||
"parent_id": "A:",
|
||||
"item_class": "object.container"
|
||||
}
|
||||
]
|
14
tests/components/sonos/fixtures/music_library_tracks.json
Normal file
14
tests/components/sonos/fixtures/music_library_tracks.json
Normal file
@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"title": "A Hard Day's Night",
|
||||
"item_id": "S://192.168.42.100/music/iTunes/The%20Beatles/A%20Hard%20Day%2fs%20Night/A%20Hard%20Day%2fs%20Night.mp3",
|
||||
"parent_id": "A:ALBUMARTIST/Beatles/A%20Hard%20Day's%20Night",
|
||||
"item_class": "object.container.album.musicTrack"
|
||||
},
|
||||
{
|
||||
"title": "I Should Have Known Better",
|
||||
"item_id": "S://192.168.42.100/music/iTunes/The%20Beatles/A%20Hard%20Day%2fs%I%20Should%20Have%20Known%20Better.mp3",
|
||||
"parent_id": "A:ALBUMARTIST/Beatles/A%20Hard%20Day's%20Night",
|
||||
"item_class": "object.container.album.musicTrack"
|
||||
}
|
||||
]
|
133
tests/components/sonos/snapshots/test_media_browser.ambr
Normal file
133
tests/components/sonos/snapshots/test_media_browser.ambr
Normal file
@ -0,0 +1,133 @@
|
||||
# serializer version: 1
|
||||
# name: test_browse_media_library
|
||||
list([
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'contributing_artist',
|
||||
'media_content_id': 'A:ARTIST',
|
||||
'media_content_type': 'contributing_artist',
|
||||
'thumbnail': None,
|
||||
'title': 'Contributing Artists',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'artist',
|
||||
'media_content_id': 'A:ALBUMARTIST',
|
||||
'media_content_type': 'artist',
|
||||
'thumbnail': None,
|
||||
'title': 'Artists',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'album',
|
||||
'media_content_id': 'A:ALBUM',
|
||||
'media_content_type': 'album',
|
||||
'thumbnail': None,
|
||||
'title': 'Albums',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'genre',
|
||||
'media_content_id': 'A:GENRE',
|
||||
'media_content_type': 'genre',
|
||||
'thumbnail': None,
|
||||
'title': 'Genres',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'composer',
|
||||
'media_content_id': 'A:COMPOSER',
|
||||
'media_content_type': 'composer',
|
||||
'thumbnail': None,
|
||||
'title': 'Composers',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': True,
|
||||
'children_media_class': None,
|
||||
'media_class': 'track',
|
||||
'media_content_id': 'A:TRACKS',
|
||||
'media_content_type': 'track',
|
||||
'thumbnail': None,
|
||||
'title': 'Tracks',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'playlist',
|
||||
'media_content_id': 'A:PLAYLISTS',
|
||||
'media_content_type': 'playlist',
|
||||
'thumbnail': None,
|
||||
'title': 'Playlists',
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_browse_media_library_albums
|
||||
list([
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': True,
|
||||
'children_media_class': None,
|
||||
'media_class': 'album',
|
||||
'media_content_id': "A:ALBUM/A%20Hard%20Day's%20Night",
|
||||
'media_content_type': 'album',
|
||||
'thumbnail': "http://192.168.42.2:1400/getaa?u=x-file-cifs://192.168.42.100/music/The%20Beatles/A%20Hard%20Day's%20Night/01%20A%20Hard%20Day's%20Night%201.m4a&v=53",
|
||||
'title': "A Hard Day's Night",
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': True,
|
||||
'children_media_class': None,
|
||||
'media_class': 'album',
|
||||
'media_content_id': 'A:ALBUM/Abbey%20Road',
|
||||
'media_content_type': 'album',
|
||||
'thumbnail': 'http://192.168.42.2:1400/getaa?u=x-file-cifs://192.168.42.100/music/The%20Beatles/AbbeyA%20Road/01%20Come%20Together.m4a&v=53',
|
||||
'title': 'Abbey Road',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': True,
|
||||
'children_media_class': None,
|
||||
'media_class': 'album',
|
||||
'media_content_id': 'A:ALBUM/Between%20Good%20And%20Evil',
|
||||
'media_content_type': 'album',
|
||||
'thumbnail': 'http://192.168.42.2:1400/getaa?u=x-file-cifs://192.168.42.100/music/Santana/A%20Between%20Good%20And%20Evil/02%20A%20Persuasion.m4a&v=53',
|
||||
'title': 'Between Good And Evil',
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
# name: test_browse_media_root
|
||||
list([
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'directory',
|
||||
'media_content_id': '',
|
||||
'media_content_type': 'favorites',
|
||||
'thumbnail': 'https://brands.home-assistant.io/_/sonos/logo.png',
|
||||
'title': 'Favorites',
|
||||
}),
|
||||
dict({
|
||||
'can_expand': True,
|
||||
'can_play': False,
|
||||
'children_media_class': None,
|
||||
'media_class': 'directory',
|
||||
'media_content_id': '',
|
||||
'media_content_type': 'library',
|
||||
'thumbnail': 'https://brands.home-assistant.io/_/sonos/logo.png',
|
||||
'title': 'Music Library',
|
||||
}),
|
||||
])
|
||||
# ---
|
@ -2,6 +2,8 @@
|
||||
|
||||
from functools import partial
|
||||
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.media_player.browse_media import BrowseMedia
|
||||
from homeassistant.components.media_player.const import MediaClass, MediaType
|
||||
from homeassistant.components.sonos.media_browser import (
|
||||
@ -12,6 +14,8 @@ from homeassistant.core import HomeAssistant
|
||||
|
||||
from .conftest import SoCoMockFactory
|
||||
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
class MockMusicServiceItem:
|
||||
"""Mocks a Soco MusicServiceItem."""
|
||||
@ -95,3 +99,81 @@ async def test_build_item_response(
|
||||
browse_item.children[1].media_content_id
|
||||
== "x-file-cifs://192.168.42.10/music/The%20Beatles/Abbey%20Road/03%20Something.mp3"
|
||||
)
|
||||
|
||||
|
||||
async def test_browse_media_root(
|
||||
hass: HomeAssistant,
|
||||
soco_factory: SoCoMockFactory,
|
||||
async_autosetup_sonos,
|
||||
soco,
|
||||
discover,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the async_browse_media method."""
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "media_player/browse_media",
|
||||
"entity_id": "media_player.zone_a",
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
assert response["result"]["children"] == snapshot
|
||||
|
||||
|
||||
async def test_browse_media_library(
|
||||
hass: HomeAssistant,
|
||||
soco_factory: SoCoMockFactory,
|
||||
async_autosetup_sonos,
|
||||
soco,
|
||||
discover,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the async_browse_media method."""
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "media_player/browse_media",
|
||||
"entity_id": "media_player.zone_a",
|
||||
"media_content_id": "",
|
||||
"media_content_type": "library",
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
assert response["result"]["children"] == snapshot
|
||||
|
||||
|
||||
async def test_browse_media_library_albums(
|
||||
hass: HomeAssistant,
|
||||
soco_factory: SoCoMockFactory,
|
||||
async_autosetup_sonos,
|
||||
soco,
|
||||
discover,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test the async_browse_media method."""
|
||||
soco_mock = soco_factory.mock_list.get("192.168.42.2")
|
||||
|
||||
client = await hass_ws_client()
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "media_player/browse_media",
|
||||
"entity_id": "media_player.zone_a",
|
||||
"media_content_id": "A:ALBUM",
|
||||
"media_content_type": "album",
|
||||
}
|
||||
)
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
assert response["result"]["children"] == snapshot
|
||||
assert soco_mock.music_library.browse_by_idstring.call_count == 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user