"""Test media source helpers.""" from unittest.mock import Mock, patch import pytest from homeassistant.components import media_source from homeassistant.components.media_player import BrowseError from homeassistant.components.media_source import const, models from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component async def test_async_browse_media(hass: HomeAssistant) -> None: """Test browse media.""" assert await async_setup_component(hass, media_source.DOMAIN, {}) await hass.async_block_till_done() # Test non-media ignored (/media has test.mp3 and not_media.txt) media = await media_source.async_browse_media(hass, "") assert isinstance(media, media_source.models.BrowseMediaSource) assert media.title == "media" assert len(media.children) == 2 # Test content filter media = await media_source.async_browse_media( hass, "", content_filter=lambda item: item.media_content_type.startswith("video/"), ) assert isinstance(media, media_source.models.BrowseMediaSource) 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 content filter adds to original not_shown orig_browse = models.MediaSourceItem.async_browse async def not_shown_browse(self): """Patch browsed item to set not_shown base value.""" item = await orig_browse(self) item.not_shown = 10 return item with patch( "homeassistant.components.media_source.models.MediaSourceItem.async_browse", not_shown_browse, ): media = await media_source.async_browse_media( hass, "", content_filter=lambda item: item.media_content_type.startswith("video/"), ) assert isinstance(media, media_source.models.BrowseMediaSource) assert media.title == "media" assert len(media.children) == 1, media.children media.children[0].title = "Epic Sax Guy 10 Hours" assert media.not_shown == 11 # Test invalid media content with pytest.raises(BrowseError): await media_source.async_browse_media(hass, "invalid") # Test base URI returns all domains media = await media_source.async_browse_media(hass, const.URI_SCHEME) assert isinstance(media, media_source.models.BrowseMediaSource) assert len(media.children) == 1 assert media.children[0].title == "My media" async def test_async_resolve_media(hass: HomeAssistant) -> None: """Test browse media.""" assert await async_setup_component(hass, media_source.DOMAIN, {}) await hass.async_block_till_done() media = await media_source.async_resolve_media( hass, media_source.generate_media_source_id(media_source.DOMAIN, "local/test.mp3"), None, ) assert isinstance(media, media_source.models.PlayMedia) assert media.url == "/media/local/test.mp3" assert media.mime_type == "audio/mpeg" async def test_async_resolve_media_no_entity( hass: HomeAssistant, caplog: pytest.LogCaptureFixture ) -> None: """Test browse media.""" assert await async_setup_component(hass, media_source.DOMAIN, {}) await hass.async_block_till_done() with pytest.raises(RuntimeError): await media_source.async_resolve_media( hass, media_source.generate_media_source_id( media_source.DOMAIN, "local/test.mp3" ), ) async def test_async_unresolve_media(hass: HomeAssistant) -> None: """Test browse media.""" assert await async_setup_component(hass, media_source.DOMAIN, {}) await hass.async_block_till_done() # Test no media content with pytest.raises(media_source.Unresolvable): await media_source.async_resolve_media(hass, "", None) # Test invalid media content with pytest.raises(media_source.Unresolvable): await media_source.async_resolve_media(hass, "invalid", None) # Test invalid media source with pytest.raises(media_source.Unresolvable): await media_source.async_resolve_media( hass, "media-source://media_source2", None ) async def test_browse_resolve_without_setup() -> None: """Test browse and resolve work without being setup.""" with pytest.raises(BrowseError): await media_source.async_browse_media(Mock(data={}), None) with pytest.raises(media_source.Unresolvable): await media_source.async_resolve_media(Mock(data={}), None, None)