diff --git a/homeassistant/components/media_player/browse_media.py b/homeassistant/components/media_player/browse_media.py index 829c96671a9..6fe4683c1fc 100644 --- a/homeassistant/components/media_player/browse_media.py +++ b/homeassistant/components/media_player/browse_media.py @@ -56,6 +56,7 @@ class BrowseMedia: children: list[BrowseMedia] | None = None, children_media_class: str | None = None, thumbnail: str | None = None, + not_shown: int = 0, ) -> None: """Initialize browse media item.""" self.media_class = media_class @@ -67,12 +68,10 @@ class BrowseMedia: self.children = children self.children_media_class = children_media_class self.thumbnail = thumbnail + self.not_shown = not_shown def as_dict(self, *, parent: bool = True) -> dict: """Convert Media class to browse media dictionary.""" - if self.children_media_class is None: - self.calculate_children_class() - response = { "title": self.title, "media_class": self.media_class, @@ -80,13 +79,18 @@ class BrowseMedia: "media_content_id": self.media_content_id, "can_play": self.can_play, "can_expand": self.can_expand, - "children_media_class": self.children_media_class, "thumbnail": self.thumbnail, } if not parent: return response + if self.children_media_class is None: + self.calculate_children_class() + + response["not_shown"] = self.not_shown + response["children_media_class"] = self.children_media_class + if self.children: response["children"] = [ child.as_dict(parent=False) for child in self.children diff --git a/homeassistant/components/media_source/__init__.py b/homeassistant/components/media_source/__init__.py index d990b0b1f3d..e2bd1b4903b 100644 --- a/homeassistant/components/media_source/__init__.py +++ b/homeassistant/components/media_source/__init__.py @@ -111,9 +111,11 @@ async def async_browse_media( if content_filter is None or item.children is None: return item + old_count = len(item.children) item.children = [ child for child in item.children if child.can_expand or content_filter(child) ] + item.not_shown = old_count - len(item.children) return item diff --git a/tests/components/cast/test_media_player.py b/tests/components/cast/test_media_player.py index 4f12a2b02bb..663941de77a 100644 --- a/tests/components/cast/test_media_player.py +++ b/tests/components/cast/test_media_player.py @@ -856,7 +856,6 @@ async def test_entity_browse_media(hass: HomeAssistant, hass_ws_client): "media_content_id": "media-source://media_source/local/Epic Sax Guy 10 Hours.mp4", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_1 in response["result"]["children"] @@ -868,7 +867,6 @@ async def test_entity_browse_media(hass: HomeAssistant, hass_ws_client): "media_content_id": "media-source://media_source/local/test.mp3", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_2 in response["result"]["children"] @@ -912,7 +910,6 @@ async def test_entity_browse_media_audio_only( "media_content_id": "media-source://media_source/local/Epic Sax Guy 10 Hours.mp4", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_1 not in response["result"]["children"] @@ -924,7 +921,6 @@ async def test_entity_browse_media_audio_only( "media_content_id": "media-source://media_source/local/test.mp3", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_2 in response["result"]["children"] @@ -1861,7 +1857,6 @@ async def test_cast_platform_browse_media(hass: HomeAssistant, hass_ws_client): "media_content_id": "", "can_play": False, "can_expand": True, - "children_media_class": None, "thumbnail": "https://brands.home-assistant.io/_/spotify/logo.png", } assert expected_child in response["result"]["children"] @@ -1888,6 +1883,7 @@ async def test_cast_platform_browse_media(hass: HomeAssistant, hass_ws_client): "children_media_class": None, "thumbnail": None, "children": [], + "not_shown": 0, } assert response["result"] == expected_response diff --git a/tests/components/dlna_dmr/test_media_player.py b/tests/components/dlna_dmr/test_media_player.py index c68a311d2b6..896968557c1 100644 --- a/tests/components/dlna_dmr/test_media_player.py +++ b/tests/components/dlna_dmr/test_media_player.py @@ -960,7 +960,6 @@ async def test_browse_media( "media_content_id": "media-source://media_source/local/Epic Sax Guy 10 Hours.mp4", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_video in response["result"]["children"] @@ -972,7 +971,6 @@ async def test_browse_media( "media_content_id": "media-source://media_source/local/test.mp3", "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": None, } assert expected_child_audio in response["result"]["children"] diff --git a/tests/components/media_player/test_init.py b/tests/components/media_player/test_init.py index c1fcd510c23..a725129bed6 100644 --- a/tests/components/media_player/test_init.py +++ b/tests/components/media_player/test_init.py @@ -5,6 +5,7 @@ from http import HTTPStatus from unittest.mock import patch from homeassistant.components import media_player +from homeassistant.components.media_player.browse_media import BrowseMedia from homeassistant.components.websocket_api.const import TYPE_RESULT from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF from homeassistant.setup import async_setup_component @@ -166,7 +167,14 @@ async def test_media_browse(hass, hass_ws_client): media_player.SUPPORT_BROWSE_MEDIA, ), patch( "homeassistant.components.media_player.MediaPlayerEntity.async_browse_media", - return_value={"bla": "yo"}, + return_value=BrowseMedia( + media_class=media_player.MEDIA_CLASS_DIRECTORY, + media_content_id="mock-id", + media_content_type="mock-type", + title="Mock Title", + can_play=False, + can_expand=True, + ), ) as mock_browse_media: await client.send_json( { @@ -183,7 +191,18 @@ async def test_media_browse(hass, hass_ws_client): assert msg["id"] == 5 assert msg["type"] == TYPE_RESULT assert msg["success"] - assert msg["result"] == {"bla": "yo"} + assert msg["result"] == { + "title": "Mock Title", + "media_class": "directory", + "media_content_type": "mock-type", + "media_content_id": "mock-id", + "can_play": False, + "can_expand": True, + "children_media_class": None, + "thumbnail": None, + "not_shown": 0, + "children": [], + } assert mock_browse_media.mock_calls[0][1] == ("album", "abcd") with patch( diff --git a/tests/components/media_source/test_init.py b/tests/components/media_source/test_init.py index a32535a5657..e36ccdac931 100644 --- a/tests/components/media_source/test_init.py +++ b/tests/components/media_source/test_init.py @@ -58,6 +58,7 @@ async def test_async_browse_media(hass): assert media.title == "media" assert len(media.children) == 1, media.children media.children[0].title = "Epic Sax Guy 10 Hours" + assert media.not_shown == 1 # Test invalid media content with pytest.raises(BrowseError): diff --git a/tests/components/motioneye/test_media_source.py b/tests/components/motioneye/test_media_source.py index f2c8db3879b..ddc50fb7702 100644 --- a/tests/components/motioneye/test_media_source.py +++ b/tests/components/motioneye/test_media_source.py @@ -103,10 +103,10 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": True, - "children_media_class": "directory", "thumbnail": None, } ], + "not_shown": 0, } media = await media_source.async_browse_media( @@ -135,10 +135,10 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": True, - "children_media_class": "directory", "thumbnail": None, } ], + "not_shown": 0, } media = await media_source.async_browse_media( @@ -166,7 +166,6 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": True, - "children_media_class": "video", "thumbnail": None, }, { @@ -179,10 +178,10 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": True, - "children_media_class": "image", "thumbnail": None, }, ], + "not_shown": 0, } client.async_get_movies = AsyncMock(return_value=TEST_MOVIES) @@ -213,10 +212,10 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": True, - "children_media_class": "directory", "thumbnail": None, } ], + "not_shown": 0, } client.get_movie_url = Mock(return_value="http://movie") @@ -248,7 +247,6 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": "http://movie", }, { @@ -262,7 +260,6 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": "http://movie", }, { @@ -276,10 +273,10 @@ async def test_async_browse_media_success(hass: HomeAssistant) -> None: ), "can_play": True, "can_expand": False, - "children_media_class": None, "thumbnail": "http://movie", }, ], + "not_shown": 0, } @@ -326,10 +323,10 @@ async def test_async_browse_media_images_success(hass: HomeAssistant) -> None: ), "can_play": False, "can_expand": False, - "children_media_class": None, "thumbnail": "http://image", } ], + "not_shown": 0, } @@ -479,4 +476,5 @@ async def test_async_resolve_media_failure(hass: HomeAssistant) -> None: "children_media_class": "video", "thumbnail": None, "children": [], + "not_shown": 0, }