music-assistant-server

7.7 KBPY
test_media.py
7.7 KB237 lines • python
1"""Test Tidal Media Manager."""
2
3from typing import Any
4from unittest.mock import AsyncMock, MagicMock, Mock, patch
5
6import pytest
7from music_assistant_models.enums import MediaType
8from music_assistant_models.media_items import ItemMapping
9
10from music_assistant.providers.tidal.media import TidalMediaManager
11
12
13@pytest.fixture
14def provider_mock() -> Mock:
15    """Return a mock provider."""
16    provider = Mock()
17    provider.domain = "tidal"
18    provider.instance_id = "tidal_instance"
19    provider.auth.user_id = "12345"
20    provider.auth.country_code = "US"
21    provider.api = AsyncMock()
22    provider.api.get_data.return_value = {}
23    provider.api.paginate = MagicMock()
24
25    async def async_iter(*_args: Any, **_kwargs: Any) -> Any:
26        for item in provider.api.paginate.return_value:
27            yield item
28
29    provider.api.paginate.side_effect = async_iter
30    provider.api.paginate.return_value = []
31
32    provider.logger = Mock()
33
34    def get_item_mapping(media_type: MediaType, key: str, name: str) -> ItemMapping:
35        return ItemMapping(
36            media_type=media_type,
37            item_id=key,
38            provider=provider.instance_id,
39            name=name,
40        )
41
42    provider.get_item_mapping.side_effect = get_item_mapping
43
44    return provider
45
46
47@pytest.fixture
48def media_manager(provider_mock: Mock) -> TidalMediaManager:
49    """Return a TidalMediaManager instance."""
50    return TidalMediaManager(provider_mock)
51
52
53@patch("music_assistant.providers.tidal.media.parse_artist")
54@patch("music_assistant.providers.tidal.media.parse_album")
55@patch("music_assistant.providers.tidal.media.parse_track")
56@patch("music_assistant.providers.tidal.media.parse_playlist")
57async def test_search(
58    mock_parse_playlist: Mock,
59    mock_parse_track: Mock,
60    mock_parse_album: Mock,
61    mock_parse_artist: Mock,
62    media_manager: TidalMediaManager,
63    provider_mock: Mock,
64) -> None:
65    """Test search."""
66    provider_mock.api.get_data.return_value = {
67        "artists": {"items": [{"id": 1}]},
68        "albums": {"items": [{"id": 1}]},
69        "tracks": {"items": [{"id": 1}]},
70        "playlists": {"items": [{"uuid": "1"}]},
71    }
72
73    mock_parse_artist.return_value = Mock(item_id="1", media_type=MediaType.ARTIST)
74    mock_parse_album.return_value = Mock(item_id="1", media_type=MediaType.ALBUM)
75    mock_parse_track.return_value = Mock(item_id="1", media_type=MediaType.TRACK)
76    mock_parse_playlist.return_value = Mock(item_id="1", media_type=MediaType.PLAYLIST)
77
78    results = await media_manager.search(
79        "query", [MediaType.ARTIST, MediaType.ALBUM, MediaType.TRACK, MediaType.PLAYLIST]
80    )
81
82    assert len(results.artists) == 1
83    assert len(results.albums) == 1
84    assert len(results.tracks) == 1
85    assert len(results.playlists) == 1
86
87    mock_parse_artist.assert_called()
88    mock_parse_album.assert_called()
89    mock_parse_track.assert_called()
90    mock_parse_playlist.assert_called()
91
92    provider_mock.api.get_data.assert_called_with(
93        "search",
94        params={
95            "query": "query",
96            "types": "artists,albums,tracks,playlists",
97            "limit": 5,
98        },
99    )
100
101
102@patch("music_assistant.providers.tidal.media.parse_artist")
103async def test_get_artist(
104    mock_parse_artist: Mock, media_manager: TidalMediaManager, provider_mock: Mock
105) -> None:
106    """Test get_artist."""
107    provider_mock.api.get_data.return_value = {"id": 1, "name": "Test Artist"}
108    mock_parse_artist.return_value = Mock(item_id="1")
109
110    artist = await media_manager.get_artist("1")
111
112    assert artist.item_id == "1"
113    provider_mock.api.get_data.assert_called_with("artists/1")
114    mock_parse_artist.assert_called_once()
115
116
117@patch("music_assistant.providers.tidal.media.parse_album")
118async def test_get_album(
119    mock_parse_album: Mock, media_manager: TidalMediaManager, provider_mock: Mock
120) -> None:
121    """Test get_album."""
122    provider_mock.api.get_data.return_value = {"id": 1, "title": "Test Album"}
123    mock_parse_album.return_value = Mock(item_id="1")
124
125    album = await media_manager.get_album("1")
126
127    assert album.item_id == "1"
128    provider_mock.api.get_data.assert_called_with("albums/1")
129    mock_parse_album.assert_called_once()
130
131
132@patch("music_assistant.providers.tidal.media.parse_track")
133async def test_get_track(
134    mock_parse_track: Mock, media_manager: TidalMediaManager, provider_mock: Mock
135) -> None:
136    """Test get_track."""
137    provider_mock.api.get_data.side_effect = [
138        {"id": 1, "title": "Test Track"},  # Track data
139        {"lyrics": "Test Lyrics"},  # Lyrics data
140    ]
141    mock_parse_track.return_value = Mock(item_id="1")
142
143    track = await media_manager.get_track("1")
144
145    assert track.item_id == "1"
146    assert provider_mock.api.get_data.call_count == 2
147    provider_mock.api.get_data.assert_any_call("tracks/1")
148    provider_mock.api.get_data.assert_any_call("tracks/1/lyrics")
149    mock_parse_track.assert_called_once()
150
151
152@patch("music_assistant.providers.tidal.media.parse_playlist")
153async def test_get_playlist(
154    mock_parse_playlist: Mock, media_manager: TidalMediaManager, provider_mock: Mock
155) -> None:
156    """Test get_playlist."""
157    provider_mock.api.get_data.return_value = {"uuid": "1", "title": "Test Playlist"}
158    mock_parse_playlist.return_value = Mock(item_id="1")
159
160    playlist = await media_manager.get_playlist("1")
161
162    assert playlist.item_id == "1"
163    provider_mock.api.get_data.assert_called_with("playlists/1")
164    mock_parse_playlist.assert_called_once()
165
166
167@patch("music_assistant.providers.tidal.media.parse_track")
168async def test_get_album_tracks(
169    mock_parse_track: Mock, media_manager: TidalMediaManager, provider_mock: Mock
170) -> None:
171    """Test get_album_tracks."""
172    provider_mock.api.get_data.return_value = {"items": [{"id": 1}]}
173    mock_parse_track.return_value = Mock(item_id="1")
174
175    tracks = await media_manager.get_album_tracks("1")
176
177    assert len(tracks) == 1
178    assert tracks[0].item_id == "1"
179    provider_mock.api.get_data.assert_called_with(
180        "albums/1/tracks",
181        params={"limit": 250},
182    )
183
184
185@patch("music_assistant.providers.tidal.media.parse_album")
186async def test_get_artist_albums(
187    mock_parse_album: Mock, media_manager: TidalMediaManager, provider_mock: Mock
188) -> None:
189    """Test get_artist_albums."""
190    provider_mock.api.get_data.return_value = {"items": [{"id": 1}]}
191    mock_parse_album.return_value = Mock(item_id="1")
192
193    albums = await media_manager.get_artist_albums("1")
194
195    assert len(albums) == 1
196    assert albums[0].item_id == "1"
197    provider_mock.api.get_data.assert_called_with(
198        "artists/1/albums",
199        params={"limit": 250},
200    )
201
202
203@patch("music_assistant.providers.tidal.media.parse_track")
204async def test_get_artist_toptracks(
205    mock_parse_track: Mock, media_manager: TidalMediaManager, provider_mock: Mock
206) -> None:
207    """Test get_artist_toptracks."""
208    provider_mock.api.get_data.return_value = {"items": [{"id": 1}]}
209    mock_parse_track.return_value = Mock(item_id="1")
210
211    tracks = await media_manager.get_artist_toptracks("1")
212
213    assert len(tracks) == 1
214    assert tracks[0].item_id == "1"
215    provider_mock.api.get_data.assert_called_with(
216        "artists/1/toptracks",
217        params={"limit": 10, "offset": 0},
218    )
219
220
221@patch("music_assistant.providers.tidal.media.parse_track")
222async def test_get_playlist_tracks(
223    mock_parse_track: Mock, media_manager: TidalMediaManager, provider_mock: Mock
224) -> None:
225    """Test get_playlist_tracks."""
226    provider_mock.api.get_data.return_value = {"items": [{"id": 1}]}
227    mock_parse_track.return_value = Mock(item_id="1")
228
229    tracks = await media_manager.get_playlist_tracks("1")
230
231    assert len(tracks) == 1
232    assert tracks[0].item_id == "1"
233    provider_mock.api.get_data.assert_called_with(
234        "playlists/1/tracks",
235        params={"limit": 200, "offset": 0},
236    )
237