Handle not found playlists in Spotify (#132033)
* Handle not found playlists * Handle not found playlists * Handle not found playlists * Handle not found playlists * Handle not found playlists * Update homeassistant/components/spotify/coordinator.py --------- Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>pull/132040/head
parent
b6458ff9b8
commit
782fff198c
|
@ -11,6 +11,7 @@ from spotifyaio import (
|
|||
Playlist,
|
||||
SpotifyClient,
|
||||
SpotifyConnectionError,
|
||||
SpotifyNotFoundError,
|
||||
UserProfile,
|
||||
)
|
||||
|
||||
|
@ -62,6 +63,7 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]):
|
|||
)
|
||||
self.client = client
|
||||
self._playlist: Playlist | None = None
|
||||
self._checked_playlist_id: str | None = None
|
||||
|
||||
async def _async_setup(self) -> None:
|
||||
"""Set up the coordinator."""
|
||||
|
@ -87,15 +89,29 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]):
|
|||
|
||||
dj_playlist = False
|
||||
if (context := current.context) is not None:
|
||||
if self._playlist is None or self._playlist.uri != context.uri:
|
||||
dj_playlist = context.uri == SPOTIFY_DJ_PLAYLIST_URI
|
||||
if not (
|
||||
context.uri
|
||||
in (
|
||||
self._checked_playlist_id,
|
||||
SPOTIFY_DJ_PLAYLIST_URI,
|
||||
)
|
||||
or (self._playlist is None and context.uri == self._checked_playlist_id)
|
||||
):
|
||||
self._checked_playlist_id = context.uri
|
||||
self._playlist = None
|
||||
if context.uri == SPOTIFY_DJ_PLAYLIST_URI:
|
||||
dj_playlist = True
|
||||
elif context.context_type == ContextType.PLAYLIST:
|
||||
if context.context_type == ContextType.PLAYLIST:
|
||||
# Make sure any playlist lookups don't break the current
|
||||
# playback state update
|
||||
try:
|
||||
self._playlist = await self.client.get_playlist(context.uri)
|
||||
except SpotifyNotFoundError:
|
||||
_LOGGER.debug(
|
||||
"Spotify playlist '%s' not found. "
|
||||
"Most likely a Spotify-created playlist",
|
||||
context.uri,
|
||||
)
|
||||
self._playlist = None
|
||||
except SpotifyConnectionError:
|
||||
_LOGGER.debug(
|
||||
"Unable to load spotify playlist '%s'. "
|
||||
|
@ -103,6 +119,7 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]):
|
|||
context.uri,
|
||||
)
|
||||
self._playlist = None
|
||||
self._checked_playlist_id = None
|
||||
return SpotifyCoordinatorData(
|
||||
current_playback=current,
|
||||
position_updated_at=position_updated_at,
|
||||
|
|
|
@ -10,6 +10,7 @@ from spotifyaio import (
|
|||
ProductType,
|
||||
RepeatMode as SpotifyRepeatMode,
|
||||
SpotifyConnectionError,
|
||||
SpotifyNotFoundError,
|
||||
)
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
|
@ -142,6 +143,7 @@ async def test_spotify_dj_list(
|
|||
hass: HomeAssistant,
|
||||
mock_spotify: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test the Spotify entities with a Spotify DJ playlist."""
|
||||
mock_spotify.return_value.get_playback.return_value.context.uri = (
|
||||
|
@ -152,12 +154,67 @@ async def test_spotify_dj_list(
|
|||
assert state
|
||||
assert state.attributes["media_playlist"] == "DJ"
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_not_called()
|
||||
|
||||
freezer.tick(timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("media_player.spotify_spotify_1")
|
||||
assert state
|
||||
assert state.attributes["media_playlist"] == "DJ"
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_credentials")
|
||||
async def test_normal_playlist(
|
||||
hass: HomeAssistant,
|
||||
mock_spotify: MagicMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test normal playlist switching."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
state = hass.states.get("media_player.spotify_spotify_1")
|
||||
assert state
|
||||
assert state.attributes["media_playlist"] == "Spotify Web API Testing playlist"
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_once_with(
|
||||
"spotify:user:rushofficial:playlist:2r35vbe6hHl6yDSMfjKgmm"
|
||||
)
|
||||
|
||||
freezer.tick(timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("media_player.spotify_spotify_1")
|
||||
assert state
|
||||
assert state.attributes["media_playlist"] == "Spotify Web API Testing playlist"
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_once_with(
|
||||
"spotify:user:rushofficial:playlist:2r35vbe6hHl6yDSMfjKgmm"
|
||||
)
|
||||
|
||||
mock_spotify.return_value.get_playback.return_value.context.uri = (
|
||||
"spotify:playlist:123123123123123"
|
||||
)
|
||||
|
||||
freezer.tick(timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_with(
|
||||
"spotify:playlist:123123123123123"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_credentials")
|
||||
async def test_fetching_playlist_does_not_fail(
|
||||
hass: HomeAssistant,
|
||||
mock_spotify: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test failing fetching playlist does not fail update."""
|
||||
mock_spotify.return_value.get_playlist.side_effect = SpotifyConnectionError
|
||||
|
@ -166,6 +223,42 @@ async def test_fetching_playlist_does_not_fail(
|
|||
assert state
|
||||
assert "media_playlist" not in state.attributes
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_once()
|
||||
|
||||
freezer.tick(timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_spotify.return_value.get_playlist.call_count == 2
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_credentials")
|
||||
async def test_fetching_playlist_once(
|
||||
hass: HomeAssistant,
|
||||
mock_spotify: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test that not being able to find a playlist doesn't retry."""
|
||||
mock_spotify.return_value.get_playlist.side_effect = SpotifyNotFoundError
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
state = hass.states.get("media_player.spotify_spotify_1")
|
||||
assert state
|
||||
assert "media_playlist" not in state.attributes
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_once()
|
||||
|
||||
freezer.tick(timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("media_player.spotify_spotify_1")
|
||||
assert state
|
||||
assert "media_playlist" not in state.attributes
|
||||
|
||||
mock_spotify.return_value.get_playlist.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_credentials")
|
||||
async def test_idle(
|
||||
|
|
Loading…
Reference in New Issue