aboutsummaryrefslogtreecommitdiff
path: root/tests/test_pandora/test_client.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_pandora/test_client.py')
-rw-r--r--tests/test_pandora/test_client.py237
1 files changed, 144 insertions, 93 deletions
diff --git a/tests/test_pandora/test_client.py b/tests/test_pandora/test_client.py
index 8144f42..1c5a229 100644
--- a/tests/test_pandora/test_client.py
+++ b/tests/test_pandora/test_client.py
@@ -13,7 +13,6 @@ from tests.test_pandora.test_models import TestAdItem
13 13
14 14
15class TestAPIClientLogin(TestCase): 15class TestAPIClientLogin(TestCase):
16
17 class StubTransport: 16 class StubTransport:
18 17
19 API_VERSION = None 18 API_VERSION = None
@@ -56,7 +55,6 @@ class TestAPIClientLogin(TestCase):
56 55
57 56
58class TestCallingAPIClient(TestCase): 57class TestCallingAPIClient(TestCase):
59
60 def test_call_should_retry_on_token_error(self): 58 def test_call_should_retry_on_token_error(self):
61 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 59 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
62 60
@@ -70,37 +68,44 @@ class TestCallingAPIClient(TestCase):
70 transport.assert_has_calls([call("method"), call("method")]) 68 transport.assert_has_calls([call("method"), call("method")])
71 69
72 def test_playlist_fetches_ads(self): 70 def test_playlist_fetches_ads(self):
73 fake_playlist = {"items": [ 71 fake_playlist = {
74 {"songName": "test"}, 72 "items": [
75 {"adToken": "foo"}, 73 {"songName": "test"},
76 {"songName": "test"}, 74 {"adToken": "foo"},
77 ]} 75 {"songName": "test"},
78 with patch.object(APIClient, '__call__', return_value=fake_playlist): 76 ]
77 }
78 with patch.object(APIClient, "__call__", return_value=fake_playlist):
79 client = APIClient(Mock(), None, None, None, None) 79 client = APIClient(Mock(), None, None, None, None)
80 client._authenticate = Mock() 80 client._authenticate = Mock()
81 81
82 items = client.get_playlist('token_mock') 82 items = client.get_playlist("token_mock")
83 self.assertIsInstance(items[1], AdItem) 83 self.assertIsInstance(items[1], AdItem)
84 84
85 def test_ad_support_enabled_parameters(self): 85 def test_ad_support_enabled_parameters(self):
86 with patch.object(APIClient, '__call__') as playlist_mock: 86 with patch.object(APIClient, "__call__") as playlist_mock:
87 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 87 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
88 88
89 client = APIClient(transport, None, None, None, None) 89 client = APIClient(transport, None, None, None, None)
90 client._authenticate = Mock() 90 client._authenticate = Mock()
91 91
92 client.get_playlist('token_mock') 92 client.get_playlist("token_mock")
93 93
94 playlist_mock.assert_has_calls([call("station.getPlaylist", 94 playlist_mock.assert_has_calls(
95 additionalAudioUrl='', 95 [
96 audioAdPodCapable=True, 96 call(
97 includeTrackLength=True, 97 "station.getPlaylist",
98 stationToken='token_mock', 98 additionalAudioUrl="",
99 xplatformAdCapable=True)]) 99 audioAdPodCapable=True,
100 includeTrackLength=True,
101 stationToken="token_mock",
102 xplatformAdCapable=True,
103 )
104 ]
105 )
100 106
101 107
102class TestGettingQualities(TestCase): 108class TestGettingQualities(TestCase):
103
104 def test_with_invalid_quality_returning_all(self): 109 def test_with_invalid_quality_returning_all(self):
105 result = BaseAPIClient.get_qualities("foo", True) 110 result = BaseAPIClient.get_qualities("foo", True)
106 self.assertEqual(BaseAPIClient.ALL_QUALITIES, result) 111 self.assertEqual(BaseAPIClient.ALL_QUALITIES, result)
@@ -111,20 +116,22 @@ class TestGettingQualities(TestCase):
111 116
112 def test_with_valid_quality(self): 117 def test_with_valid_quality(self):
113 result = BaseAPIClient.get_qualities( 118 result = BaseAPIClient.get_qualities(
114 BaseAPIClient.MED_AUDIO_QUALITY, False) 119 BaseAPIClient.MED_AUDIO_QUALITY, False
120 )
115 121
116 expected = [ 122 expected = [
117 BaseAPIClient.LOW_AUDIO_QUALITY, 123 BaseAPIClient.LOW_AUDIO_QUALITY,
118 BaseAPIClient.MED_AUDIO_QUALITY] 124 BaseAPIClient.MED_AUDIO_QUALITY,
125 ]
119 126
120 self.assertEqual(expected, result) 127 self.assertEqual(expected, result)
121 128
122 129
123class TestGettingAds(TestCase): 130class TestGettingAds(TestCase):
124
125 def test_get_ad_item_(self): 131 def test_get_ad_item_(self):
126 metamock = patch.object( 132 metamock = patch.object(
127 APIClient, '__call__', return_value=TestAdItem.JSON_DATA) 133 APIClient, "__call__", return_value=TestAdItem.JSON_DATA
134 )
128 135
129 with metamock as ad_metadata_mock: 136 with metamock as ad_metadata_mock:
130 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 137 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
@@ -132,13 +139,20 @@ class TestGettingAds(TestCase):
132 client = APIClient(transport, None, None, None, None) 139 client = APIClient(transport, None, None, None, None)
133 client._authenticate = Mock() 140 client._authenticate = Mock()
134 141
135 ad_item = client.get_ad_item('id_mock', 'token_mock') 142 ad_item = client.get_ad_item("id_mock", "token_mock")
136 assert ad_item.station_id == 'id_mock' 143 assert ad_item.station_id == "id_mock"
137 assert ad_item.ad_token == 'token_mock' 144 assert ad_item.ad_token == "token_mock"
138 145
139 ad_metadata_mock.assert_has_calls([ 146 ad_metadata_mock.assert_has_calls(
140 call("ad.getAdMetadata", adToken='token_mock', 147 [
141 returnAdTrackingTokens=True, supportAudioAds=True)]) 148 call(
149 "ad.getAdMetadata",
150 adToken="token_mock",
151 returnAdTrackingTokens=True,
152 supportAudioAds=True,
153 )
154 ]
155 )
142 156
143 def test_get_ad_item_with_no_station_id_specified_raises_exception(self): 157 def test_get_ad_item_with_no_station_id_specified_raises_exception(self):
144 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 158 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
@@ -147,28 +161,31 @@ class TestGettingAds(TestCase):
147 client.get_ad_metadata = Mock() 161 client.get_ad_metadata = Mock()
148 162
149 self.assertRaises( 163 self.assertRaises(
150 errors.ParameterMissing, client.get_ad_item, '', 'token_mock') 164 errors.ParameterMissing, client.get_ad_item, "", "token_mock"
165 )
151 166
152 167
153class TestCreatingStation(TestCase): 168class TestCreatingStation(TestCase):
154
155 def test_using_search_token(self): 169 def test_using_search_token(self):
156 client = APIClient(Mock(return_value={}), None, None, None, None) 170 client = APIClient(Mock(return_value={}), None, None, None, None)
157 client.create_station(search_token="foo") 171 client.create_station(search_token="foo")
158 client.transport.assert_called_with( 172 client.transport.assert_called_with(
159 "station.createStation", musicToken="foo") 173 "station.createStation", musicToken="foo"
174 )
160 175
161 def test_using_artist_token(self): 176 def test_using_artist_token(self):
162 client = APIClient(Mock(return_value={}), None, None, None, None) 177 client = APIClient(Mock(return_value={}), None, None, None, None)
163 client.create_station(artist_token="foo") 178 client.create_station(artist_token="foo")
164 client.transport.assert_called_with( 179 client.transport.assert_called_with(
165 "station.createStation", trackToken="foo", musicType="artist") 180 "station.createStation", trackToken="foo", musicType="artist"
181 )
166 182
167 def test_using_track_token(self): 183 def test_using_track_token(self):
168 client = APIClient(Mock(return_value={}), None, None, None, None) 184 client = APIClient(Mock(return_value={}), None, None, None, None)
169 client.create_station(track_token="foo") 185 client.create_station(track_token="foo")
170 client.transport.assert_called_with( 186 client.transport.assert_called_with(
171 "station.createStation", trackToken="foo", musicType="song") 187 "station.createStation", trackToken="foo", musicType="song"
188 )
172 189
173 def test_with_no_token(self): 190 def test_with_no_token(self):
174 with self.assertRaises(KeyError): 191 with self.assertRaises(KeyError):
@@ -177,25 +194,20 @@ class TestCreatingStation(TestCase):
177 194
178 195
179class TestCreatingGenreStation(TestCase): 196class TestCreatingGenreStation(TestCase):
180
181 def test_has_initial_checksum(self): 197 def test_has_initial_checksum(self):
182 fake_data = { 198 fake_data = {
183 "categories": [ 199 "categories": [{"categoryName": "foo", "stations": []},],
184 {"categoryName": "foo", "stations": []},
185 ],
186
187 # Not actually part of the genre station response but is needed to 200 # Not actually part of the genre station response but is needed to
188 # fake out the mock for get_genre_stations_checksum 201 # fake out the mock for get_genre_stations_checksum
189 "checksum": "foo" 202 "checksum": "foo",
190 } 203 }
191 with patch.object(APIClient, '__call__', return_value=fake_data): 204 with patch.object(APIClient, "__call__", return_value=fake_data):
192 client = APIClient(Mock(), None, None, None, None) 205 client = APIClient(Mock(), None, None, None, None)
193 station = client.get_genre_stations() 206 station = client.get_genre_stations()
194 self.assertEqual(station.checksum, "foo") 207 self.assertEqual(station.checksum, "foo")
195 208
196 209
197class TestAdditionalUrls(TestCase): 210class TestAdditionalUrls(TestCase):
198
199 def test_non_iterable_string(self): 211 def test_non_iterable_string(self):
200 with self.assertRaises(TypeError): 212 with self.assertRaises(TypeError):
201 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 213 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
@@ -203,7 +215,7 @@ class TestAdditionalUrls(TestCase):
203 client = APIClient(transport, None, None, None, None) 215 client = APIClient(transport, None, None, None, None)
204 client._authenticate = Mock() 216 client._authenticate = Mock()
205 217
206 client.get_playlist('token_mock', additional_urls='') 218 client.get_playlist("token_mock", additional_urls="")
207 219
208 def test_non_iterable_other(self): 220 def test_non_iterable_other(self):
209 with self.assertRaises(TypeError): 221 with self.assertRaises(TypeError):
@@ -212,50 +224,64 @@ class TestAdditionalUrls(TestCase):
212 client = APIClient(transport, None, None, None, None) 224 client = APIClient(transport, None, None, None, None)
213 client._authenticate = Mock() 225 client._authenticate = Mock()
214 226
215 client.get_playlist('token_mock', 227 client.get_playlist(
216 additional_urls=AdditionalAudioUrl.HTTP_32_WMA) 228 "token_mock", additional_urls=AdditionalAudioUrl.HTTP_32_WMA
229 )
217 230
218 def test_without_enum(self): 231 def test_without_enum(self):
219 with patch.object(APIClient, '__call__') as playlist_mock: 232 with patch.object(APIClient, "__call__") as playlist_mock:
220 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 233 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
221 234
222 client = APIClient(transport, None, None, None, None) 235 client = APIClient(transport, None, None, None, None)
223 client._authenticate = Mock() 236 client._authenticate = Mock()
224 237
225 urls = ['HTTP_128_MP3', 238 urls = ["HTTP_128_MP3", "HTTP_24_AACPLUS_ADTS"]
226 'HTTP_24_AACPLUS_ADTS']
227 239
228 desired = 'HTTP_128_MP3,HTTP_24_AACPLUS_ADTS' 240 desired = "HTTP_128_MP3,HTTP_24_AACPLUS_ADTS"
229 241
230 client.get_playlist('token_mock', additional_urls=urls) 242 client.get_playlist("token_mock", additional_urls=urls)
231 243
232 playlist_mock.assert_has_calls([call("station.getPlaylist", 244 playlist_mock.assert_has_calls(
233 additionalAudioUrl=desired, 245 [
234 audioAdPodCapable=True, 246 call(
235 includeTrackLength=True, 247 "station.getPlaylist",
236 stationToken='token_mock', 248 additionalAudioUrl=desired,
237 xplatformAdCapable=True)]) 249 audioAdPodCapable=True,
250 includeTrackLength=True,
251 stationToken="token_mock",
252 xplatformAdCapable=True,
253 )
254 ]
255 )
238 256
239 def test_with_enum(self): 257 def test_with_enum(self):
240 with patch.object(APIClient, '__call__') as playlist_mock: 258 with patch.object(APIClient, "__call__") as playlist_mock:
241 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 259 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
242 260
243 client = APIClient(transport, None, None, None, None) 261 client = APIClient(transport, None, None, None, None)
244 client._authenticate = Mock() 262 client._authenticate = Mock()
245 263
246 urls = [AdditionalAudioUrl.HTTP_128_MP3, 264 urls = [
247 AdditionalAudioUrl.HTTP_24_AACPLUS_ADTS] 265 AdditionalAudioUrl.HTTP_128_MP3,
266 AdditionalAudioUrl.HTTP_24_AACPLUS_ADTS,
267 ]
248 268
249 desired = 'HTTP_128_MP3,HTTP_24_AACPLUS_ADTS' 269 desired = "HTTP_128_MP3,HTTP_24_AACPLUS_ADTS"
250 270
251 client.get_playlist('token_mock', additional_urls=urls) 271 client.get_playlist("token_mock", additional_urls=urls)
252 272
253 playlist_mock.assert_has_calls([call("station.getPlaylist", 273 playlist_mock.assert_has_calls(
254 additionalAudioUrl=desired, 274 [
255 audioAdPodCapable=True, 275 call(
256 includeTrackLength=True, 276 "station.getPlaylist",
257 stationToken='token_mock', 277 additionalAudioUrl=desired,
258 xplatformAdCapable=True)]) 278 audioAdPodCapable=True,
279 includeTrackLength=True,
280 stationToken="token_mock",
281 xplatformAdCapable=True,
282 )
283 ]
284 )
259 285
260 286
261# On the surface this test class seems dumb because it's mostly just exercising 287# On the surface this test class seems dumb because it's mostly just exercising
@@ -263,7 +289,6 @@ class TestAdditionalUrls(TestCase):
263# introduced to API client methods that will only be spotted at runtime (import 289# introduced to API client methods that will only be spotted at runtime (import
264# errors, etc...) 290# errors, etc...)
265class TestAPIClientExhaustive(TestCase): 291class TestAPIClientExhaustive(TestCase):
266
267 def setUp(self): 292 def setUp(self):
268 self.transport = Mock() 293 self.transport = Mock()
269 self.api = APIClient(self.transport, "puser", "ppass", "device") 294 self.api = APIClient(self.transport, "puser", "ppass", "device")
@@ -271,23 +296,29 @@ class TestAPIClientExhaustive(TestCase):
271 def test_register_ad(self): 296 def test_register_ad(self):
272 self.api.register_ad("sid", "tokens") 297 self.api.register_ad("sid", "tokens")
273 self.transport.assert_called_with( 298 self.transport.assert_called_with(
274 "ad.registerAd", stationId="sid", adTrackingTokens="tokens") 299 "ad.registerAd", stationId="sid", adTrackingTokens="tokens"
300 )
275 301
276 def test_share_music(self): 302 def test_share_music(self):
277 self.api.share_music("token", "foo@example.com") 303 self.api.share_music("token", "foo@example.com")
278 self.transport.assert_called_with( 304 self.transport.assert_called_with(
279 "music.shareMusic", musicToken="token", email="foo@example.com") 305 "music.shareMusic", musicToken="token", email="foo@example.com"
306 )
280 307
281 def test_transform_shared_station(self): 308 def test_transform_shared_station(self):
282 self.api.transform_shared_station("token") 309 self.api.transform_shared_station("token")
283 self.transport.assert_called_with( 310 self.transport.assert_called_with(
284 "station.transformSharedStation", stationToken="token") 311 "station.transformSharedStation", stationToken="token"
312 )
285 313
286 def test_share_station(self): 314 def test_share_station(self):
287 self.api.share_station("sid", "token", "foo@example.com") 315 self.api.share_station("sid", "token", "foo@example.com")
288 self.transport.assert_called_with( 316 self.transport.assert_called_with(
289 "station.shareStation", stationId="sid", stationToken="token", 317 "station.shareStation",
290 emails=("foo@example.com",)) 318 stationId="sid",
319 stationToken="token",
320 emails=("foo@example.com",),
321 )
291 322
292 def test_sleep_song(self): 323 def test_sleep_song(self):
293 self.api.sleep_song("token") 324 self.api.sleep_song("token")
@@ -296,22 +327,26 @@ class TestAPIClientExhaustive(TestCase):
296 def test_set_quick_mix(self): 327 def test_set_quick_mix(self):
297 self.api.set_quick_mix("id") 328 self.api.set_quick_mix("id")
298 self.transport.assert_called_with( 329 self.transport.assert_called_with(
299 "user.setQuickMix", quickMixStationIds=("id",)) 330 "user.setQuickMix", quickMixStationIds=("id",)
331 )
300 332
301 def test_explain_track(self): 333 def test_explain_track(self):
302 self.api.explain_track("token") 334 self.api.explain_track("token")
303 self.transport.assert_called_with( 335 self.transport.assert_called_with(
304 "track.explainTrack", trackToken="token") 336 "track.explainTrack", trackToken="token"
337 )
305 338
306 def test_rename_station(self): 339 def test_rename_station(self):
307 self.api.rename_station("token", "name") 340 self.api.rename_station("token", "name")
308 self.transport.assert_called_with( 341 self.transport.assert_called_with(
309 "station.renameStation", stationToken="token", stationName="name") 342 "station.renameStation", stationToken="token", stationName="name"
343 )
310 344
311 def test_delete_station(self): 345 def test_delete_station(self):
312 self.api.delete_station("token") 346 self.api.delete_station("token")
313 self.transport.assert_called_with( 347 self.transport.assert_called_with(
314 "station.deleteStation", stationToken="token") 348 "station.deleteStation", stationToken="token"
349 )
315 350
316 def test_delete_music(self): 351 def test_delete_music(self):
317 self.api.delete_music("seed") 352 self.api.delete_music("seed")
@@ -320,37 +355,44 @@ class TestAPIClientExhaustive(TestCase):
320 def test_delete_feedback(self): 355 def test_delete_feedback(self):
321 self.api.delete_feedback("id") 356 self.api.delete_feedback("id")
322 self.transport.assert_called_with( 357 self.transport.assert_called_with(
323 "station.deleteFeedback", feedbackId="id") 358 "station.deleteFeedback", feedbackId="id"
359 )
324 360
325 def test_add_music(self): 361 def test_add_music(self):
326 self.api.add_music("mt", "st") 362 self.api.add_music("mt", "st")
327 self.transport.assert_called_with( 363 self.transport.assert_called_with(
328 "station.addMusic", musicToken="mt", stationToken="st") 364 "station.addMusic", musicToken="mt", stationToken="st"
365 )
329 366
330 def test_add_feedback(self): 367 def test_add_feedback(self):
331 self.api.add_feedback("token", False) 368 self.api.add_feedback("token", False)
332 self.transport.assert_called_with( 369 self.transport.assert_called_with(
333 "station.addFeedback", trackToken="token", isPositive=False) 370 "station.addFeedback", trackToken="token", isPositive=False
371 )
334 372
335 def test_add_artist_bookmark(self): 373 def test_add_artist_bookmark(self):
336 self.api.add_artist_bookmark("tt") 374 self.api.add_artist_bookmark("tt")
337 self.transport.assert_called_with( 375 self.transport.assert_called_with(
338 "bookmark.addArtistBookmark", trackToken="tt") 376 "bookmark.addArtistBookmark", trackToken="tt"
377 )
339 378
340 def test_add_song_bookmark(self): 379 def test_add_song_bookmark(self):
341 self.api.add_song_bookmark("tt") 380 self.api.add_song_bookmark("tt")
342 self.transport.assert_called_with( 381 self.transport.assert_called_with(
343 "bookmark.addSongBookmark", trackToken="tt") 382 "bookmark.addSongBookmark", trackToken="tt"
383 )
344 384
345 def test_delete_song_bookmark(self): 385 def test_delete_song_bookmark(self):
346 self.api.delete_song_bookmark("bt") 386 self.api.delete_song_bookmark("bt")
347 self.transport.assert_called_with( 387 self.transport.assert_called_with(
348 "bookmark.deleteSongBookmark", bookmarkToken="bt") 388 "bookmark.deleteSongBookmark", bookmarkToken="bt"
389 )
349 390
350 def test_delete_artist_bookmark(self): 391 def test_delete_artist_bookmark(self):
351 self.api.delete_artist_bookmark("bt") 392 self.api.delete_artist_bookmark("bt")
352 self.transport.assert_called_with( 393 self.transport.assert_called_with(
353 "bookmark.deleteArtistBookmark", bookmarkToken="bt") 394 "bookmark.deleteArtistBookmark", bookmarkToken="bt"
395 )
354 396
355 def test_get_station_list_checksum(self): 397 def test_get_station_list_checksum(self):
356 self.transport.return_value = {"checksum": "foo"} 398 self.transport.return_value = {"checksum": "foo"}
@@ -364,7 +406,8 @@ class TestAPIClientExhaustive(TestCase):
364 self.transport.return_value = {"stations": []} 406 self.transport.return_value = {"stations": []}
365 self.assertIsInstance(self.api.get_station_list(), StationList) 407 self.assertIsInstance(self.api.get_station_list(), StationList)
366 self.transport.assert_called_with( 408 self.transport.assert_called_with(
367 "user.getStationList", includeStationArtUrl=True) 409 "user.getStationList", includeStationArtUrl=True
410 )
368 411
369 def test_get_bookmarks(self): 412 def test_get_bookmarks(self):
370 self.transport.return_value = {} 413 self.transport.return_value = {}
@@ -375,14 +418,22 @@ class TestAPIClientExhaustive(TestCase):
375 self.transport.return_value = {} 418 self.transport.return_value = {}
376 self.assertIsInstance(self.api.get_station("st"), Station) 419 self.assertIsInstance(self.api.get_station("st"), Station)
377 self.transport.assert_called_with( 420 self.transport.assert_called_with(
378 "station.getStation", stationToken="st", 421 "station.getStation",
379 includeExtendedAttributes=True) 422 stationToken="st",
423 includeExtendedAttributes=True,
424 )
380 425
381 def test_search(self): 426 def test_search(self):
382 self.transport.return_value = {} 427 self.transport.return_value = {}
383 self.assertIsInstance(self.api.search( 428 self.assertIsInstance(
384 "text", include_near_matches=True, include_genre_stations=True), 429 self.api.search(
385 SearchResult) 430 "text", include_near_matches=True, include_genre_stations=True
431 ),
432 SearchResult,
433 )
386 self.transport.assert_called_with( 434 self.transport.assert_called_with(
387 "music.search", searchText="text", includeNearMatches=True, 435 "music.search",
388 includeGenreStations=True) 436 searchText="text",
437 includeNearMatches=True,
438 includeGenreStations=True,
439 )