aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2017-10-07 04:10:14 +0000
committerMike Crute <mike@crute.us>2017-10-07 04:37:42 +0000
commiteac047b29356b98c368a0a420d1abcd089ac8b09 (patch)
tree9623091845d0beb91abb86df7af31118d7b6ab8c
parente473c68962a616e2d6b53fc07cead6856c8128a7 (diff)
downloadpydora-eac047b29356b98c368a0a420d1abcd089ac8b09.tar.bz2
pydora-eac047b29356b98c368a0a420d1abcd089ac8b09.tar.xz
pydora-eac047b29356b98c368a0a420d1abcd089ac8b09.zip
Add tests
-rw-r--r--tests/test_pandora/test_client.py59
-rw-r--r--tests/test_pandora/test_clientbuilder.py4
-rw-r--r--tests/test_pandora/test_models.py155
3 files changed, 199 insertions, 19 deletions
diff --git a/tests/test_pandora/test_client.py b/tests/test_pandora/test_client.py
index ce91e21..8d93e4c 100644
--- a/tests/test_pandora/test_client.py
+++ b/tests/test_pandora/test_client.py
@@ -1,6 +1,7 @@
1from unittest import TestCase 1from unittest import TestCase
2 2
3from pandora import errors 3from pandora import errors
4from pandora.models.pandora import AdItem
4from pandora.client import APIClient, BaseAPIClient 5from pandora.client import APIClient, BaseAPIClient
5from pandora.py2compat import Mock, call, patch 6from pandora.py2compat import Mock, call, patch
6from tests.test_pandora.test_models import TestAdItem 7from tests.test_pandora.test_models import TestAdItem
@@ -63,6 +64,20 @@ class TestCallingAPIClient(TestCase):
63 client._authenticate.assert_called_with() 64 client._authenticate.assert_called_with()
64 transport.assert_has_calls([call("method"), call("method")]) 65 transport.assert_has_calls([call("method"), call("method")])
65 66
67 def test_playlist_fetches_ads(self):
68 fake_playlist = { "items": [
69 { "songName": "test" },
70 { "adToken": "foo" },
71 { "songName": "test" },
72 ]}
73 with patch.object(
74 APIClient, '__call__', return_value=fake_playlist) as mock:
75 client = APIClient(Mock(), None, None, None, None)
76 client._authenticate = Mock()
77
78 items = client.get_playlist('token_mock')
79 self.assertIsInstance(items[1], AdItem)
80
66 def test_ad_support_enabled_parameters(self): 81 def test_ad_support_enabled_parameters(self):
67 with patch.object(APIClient, '__call__') as playlist_mock: 82 with patch.object(APIClient, '__call__') as playlist_mock:
68 transport = Mock(side_effect=[errors.InvalidAuthToken(), None]) 83 transport = Mock(side_effect=[errors.InvalidAuthToken(), None])
@@ -127,3 +142,47 @@ class TestGettingAds(TestCase):
127 142
128 self.assertRaises( 143 self.assertRaises(
129 errors.ParameterMissing, client.get_ad_item, '', 'token_mock') 144 errors.ParameterMissing, client.get_ad_item, '', 'token_mock')
145
146
147class TestCreatingStation(TestCase):
148
149 def test_using_search_token(self):
150 client = APIClient(Mock(), None, None, None, None)
151 client.create_station(search_token="foo")
152 client.transport.assert_called_with(
153 "station.createStation", musicToken="foo")
154
155 def test_using_artist_token(self):
156 client = APIClient(Mock(), None, None, None, None)
157 client.create_station(artist_token="foo")
158 client.transport.assert_called_with(
159 "station.createStation", trackToken="foo", musicType="artist")
160
161 def test_using_track_token(self):
162 client = APIClient(Mock(), None, None, None, None)
163 client.create_station(track_token="foo")
164 client.transport.assert_called_with(
165 "station.createStation", trackToken="foo", musicType="song")
166
167 def test_with_no_token(self):
168 with self.assertRaises(KeyError):
169 client = APIClient(Mock(), None, None, None, None)
170 client.create_station()
171
172
173class TestCreatingGenreStation(TestCase):
174
175 def test_has_initial_checksum(self):
176 fake_data = {
177 "categories": [
178 { "categoryName": "foo", "stations": [] },
179 ],
180
181 # Not actually part of the genre station response but is needed to
182 # fake out the mock for get_genre_stations_checksum
183 "checksum": "foo"
184 }
185 with patch.object(APIClient, '__call__', return_value=fake_data):
186 client = APIClient(Mock(), None, None, None, None)
187 station = client.get_genre_stations()
188 self.assertEqual(station.checksum, "foo")
diff --git a/tests/test_pandora/test_clientbuilder.py b/tests/test_pandora/test_clientbuilder.py
index aaccdf8..b02a4d1 100644
--- a/tests/test_pandora/test_clientbuilder.py
+++ b/tests/test_pandora/test_clientbuilder.py
@@ -164,6 +164,10 @@ class TestFileBasedBuilder(TestCase):
164 client = self.StubBuilder(__file__, False).build() 164 client = self.StubBuilder(__file__, False).build()
165 self.assertFalse(client.login.called) 165 self.assertFalse(client.login.called)
166 166
167 def test_abstract_class_does_not_parse_config(self):
168 with self.assertRaises(NotImplementedError):
169 cb.FileBasedClientBuilder().parse_config()
170
167 171
168class TestPydoraConfigFileBuilder(TestCase): 172class TestPydoraConfigFileBuilder(TestCase):
169 173
diff --git a/tests/test_pandora/test_models.py b/tests/test_pandora/test_models.py
index 2ae7d11..42f1fbd 100644
--- a/tests/test_pandora/test_models.py
+++ b/tests/test_pandora/test_models.py
@@ -4,10 +4,9 @@ from pandora.py2compat import Mock, patch
4 4
5from pandora.client import APIClient 5from pandora.client import APIClient
6from pandora.errors import ParameterMissing 6from pandora.errors import ParameterMissing
7from pandora.models.pandora import SearchResult
8from pandora.models.pandora import AdItem, PlaylistModel, SearchResultItem
9 7
10import pandora.models as m 8import pandora.models as m
9import pandora.models.pandora as pm
11 10
12 11
13class TestField(TestCase): 12class TestField(TestCase):
@@ -204,6 +203,46 @@ class TestPandoraDictListModel(TestCase):
204 self.assertEqual(expected, repr(self.result)) 203 self.assertEqual(expected, repr(self.result))
205 204
206 205
206class TestPlaylistItemModel(TestCase):
207
208 AUDIO_URL_NO_MAP = { "audioUrl": "foo" }
209 WEIRD_FORMAT = { "audioUrlMap": {
210 "highQuality": {
211 }
212 }}
213
214 def test_audio_url_without_map(self):
215 item = pm.PlaylistItem.from_json(Mock(), self.AUDIO_URL_NO_MAP)
216 self.assertEqual(item.bitrate, 64)
217 self.assertEqual(item.encoding, "aacplus")
218 self.assertEqual(item.audio_url, "foo")
219
220 # I don't think this case makes a lot of sense because you should always
221 # return None if you make it all the way through the loop without finding a
222 # valid url... but I didn't add the original code so just going to test it
223 # and leave it alone for now ~mcrute
224 def test_empty_quality_map_url_is_map(self):
225 item = pm.PlaylistItem.from_json(Mock(), self.WEIRD_FORMAT)
226 self.assertIsNone(item.bitrate)
227 self.assertIsNone(item.encoding)
228 self.assertIsNone(item.audio_url)
229
230
231class TestPlaylistModel(TestCase):
232
233 def test_unplayable_get_is_playable(self):
234 playlist = pm.PlaylistModel(Mock())
235 playlist.audio_url = ""
236 self.assertFalse(playlist.get_is_playable())
237
238 def test_playable_get_is_playable(self):
239 client = Mock()
240 playlist = pm.PlaylistModel(client)
241 playlist.audio_url = "foo"
242 playlist.get_is_playable()
243 client.transport.test_url.assert_called_with("foo")
244
245
207class TestAdItem(TestCase): 246class TestAdItem(TestCase):
208 247
209 JSON_DATA = { 248 JSON_DATA = {
@@ -227,7 +266,7 @@ class TestAdItem(TestCase):
227 def setUp(self): 266 def setUp(self):
228 api_client_mock = Mock(spec=APIClient) 267 api_client_mock = Mock(spec=APIClient)
229 api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 268 api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
230 self.result = AdItem.from_json(api_client_mock, self.JSON_DATA) 269 self.result = pm.AdItem.from_json(api_client_mock, self.JSON_DATA)
231 self.result.station_id = 'station_id_mock' 270 self.result.station_id = 'station_id_mock'
232 self.result.ad_token = 'token_mock' 271 self.result.ad_token = 'token_mock'
233 272
@@ -243,14 +282,14 @@ class TestAdItem(TestCase):
243 def test_register_ad_raises_exception_if_no_tracking_tokens_available(self): 282 def test_register_ad_raises_exception_if_no_tracking_tokens_available(self):
244 with self.assertRaises(ParameterMissing): 283 with self.assertRaises(ParameterMissing):
245 self.result.tracking_tokens = [] 284 self.result.tracking_tokens = []
246 self.result._api_client.register_ad = Mock(spec=AdItem) 285 self.result._api_client.register_ad = Mock(spec=pm.AdItem)
247 286
248 self.result.register_ad('id_mock') 287 self.result.register_ad('id_mock')
249 288
250 assert self.result._api_client.register_ad.called 289 assert self.result._api_client.register_ad.called
251 290
252 def test_prepare_playback(self): 291 def test_prepare_playback(self):
253 with patch.object(PlaylistModel, 'prepare_playback') as super_mock: 292 with patch.object(pm.PlaylistModel, 'prepare_playback') as super_mock:
254 293
255 self.result.register_ad = Mock() 294 self.result.register_ad = Mock()
256 self.result.prepare_playback() 295 self.result.prepare_playback()
@@ -258,7 +297,7 @@ class TestAdItem(TestCase):
258 assert super_mock.called 297 assert super_mock.called
259 298
260 def test_prepare_playback_raises_paramater_missing(self): 299 def test_prepare_playback_raises_paramater_missing(self):
261 with patch.object(PlaylistModel, 'prepare_playback') as super_mock: 300 with patch.object(pm.PlaylistModel, 'prepare_playback') as super_mock:
262 301
263 self.result.register_ad = Mock(side_effect=ParameterMissing('No ad tracking tokens provided for ' 302 self.result.register_ad = Mock(side_effect=ParameterMissing('No ad tracking tokens provided for '
264 'registration.') 303 'registration.')
@@ -268,7 +307,7 @@ class TestAdItem(TestCase):
268 assert not super_mock.called 307 assert not super_mock.called
269 308
270 def test_prepare_playback_handles_paramater_missing_if_no_tokens(self): 309 def test_prepare_playback_handles_paramater_missing_if_no_tokens(self):
271 with patch.object(PlaylistModel, 'prepare_playback') as super_mock: 310 with patch.object(pm.PlaylistModel, 'prepare_playback') as super_mock:
272 311
273 self.result.tracking_tokens = [] 312 self.result.tracking_tokens = []
274 self.result.register_ad = Mock(side_effect=ParameterMissing('No ad tracking tokens provided for ' 313 self.result.register_ad = Mock(side_effect=ParameterMissing('No ad tracking tokens provided for '
@@ -307,38 +346,53 @@ class TestSearchResultItem(TestCase):
307 "score": 100 346 "score": 100
308 } 347 }
309 348
349 UNKNOWN_JSON_DATA = {
350 "stationName": "unknown_name_mock",
351 "musicToken": "U0000000",
352 "score": 100
353 }
354
310 def setUp(self): 355 def setUp(self):
311 self.api_client_mock = Mock(spec=APIClient) 356 self.api_client_mock = Mock(spec=APIClient)
312 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 357 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
313 358
314 def test_is_song(self): 359 def test_is_song(self):
315 result = SearchResultItem.from_json(self.api_client_mock, self.SONG_JSON_DATA) 360 result = pm.SearchResultItem.from_json(
361 self.api_client_mock, self.SONG_JSON_DATA)
316 assert result.is_song 362 assert result.is_song
317 assert not result.is_artist 363 assert not result.is_artist
318 assert not result.is_composer 364 assert not result.is_composer
319 assert not result.is_genre_station 365 assert not result.is_genre_station
320 366
321 def test_is_artist(self): 367 def test_is_artist(self):
322 result = SearchResultItem.from_json(self.api_client_mock, self.ARTIST_JSON_DATA) 368 result = pm.SearchResultItem.from_json(
369 self.api_client_mock, self.ARTIST_JSON_DATA)
323 assert not result.is_song 370 assert not result.is_song
324 assert result.is_artist 371 assert result.is_artist
325 assert not result.is_composer 372 assert not result.is_composer
326 assert not result.is_genre_station 373 assert not result.is_genre_station
327 374
328 def test_is_composer(self): 375 def test_is_composer(self):
329 result = SearchResultItem.from_json(self.api_client_mock, self.COMPOSER_JSON_DATA) 376 result = pm.SearchResultItem.from_json(
377 self.api_client_mock, self.COMPOSER_JSON_DATA)
330 assert not result.is_song 378 assert not result.is_song
331 assert not result.is_artist 379 assert not result.is_artist
332 assert result.is_composer 380 assert result.is_composer
333 assert not result.is_genre_station 381 assert not result.is_genre_station
334 382
335 def test_is_genre_station(self): 383 def test_is_genre_station(self):
336 result = SearchResultItem.from_json(self.api_client_mock, self.GENRE_JSON_DATA) 384 result = pm.SearchResultItem.from_json(
385 self.api_client_mock, self.GENRE_JSON_DATA)
337 assert not result.is_song 386 assert not result.is_song
338 assert not result.is_artist 387 assert not result.is_artist
339 assert not result.is_composer 388 assert not result.is_composer
340 assert result.is_genre_station 389 assert result.is_genre_station
341 390
391 def test_fails_if_unknown(self):
392 with self.assertRaises(NotImplementedError):
393 pm.SearchResultItem.from_json(
394 self.api_client_mock, self.UNKNOWN_JSON_DATA)
395
342 396
343class TestArtistSearchResultItem(TestCase): 397class TestArtistSearchResultItem(TestCase):
344 398
@@ -361,16 +415,19 @@ class TestArtistSearchResultItem(TestCase):
361 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 415 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
362 416
363 def test_repr(self): 417 def test_repr(self):
364 result = SearchResultItem.from_json(self.api_client_mock, self.ARTIST_JSON_DATA) 418 result = pm.SearchResultItem.from_json(
419 self.api_client_mock, self.ARTIST_JSON_DATA)
365 expected = ("ArtistSearchResultItem(artist='artist_name_mock', likely_match=False, score=100, token='R0000000')") 420 expected = ("ArtistSearchResultItem(artist='artist_name_mock', likely_match=False, score=100, token='R0000000')")
366 self.assertEqual(expected, repr(result)) 421 self.assertEqual(expected, repr(result))
367 422
368 result = SearchResultItem.from_json(self.api_client_mock, self.COMPOSER_JSON_DATA) 423 result = pm.SearchResultItem.from_json(
424 self.api_client_mock, self.COMPOSER_JSON_DATA)
369 expected = ("ArtistSearchResultItem(artist='composer_name_mock', likely_match=False, score=100, token='C0000000')") 425 expected = ("ArtistSearchResultItem(artist='composer_name_mock', likely_match=False, score=100, token='C0000000')")
370 self.assertEqual(expected, repr(result)) 426 self.assertEqual(expected, repr(result))
371 427
372 def test_create_station(self): 428 def test_create_station(self):
373 result = SearchResultItem.from_json(self.api_client_mock, self.ARTIST_JSON_DATA) 429 result = pm.SearchResultItem.from_json(
430 self.api_client_mock, self.ARTIST_JSON_DATA)
374 result._api_client.create_station = Mock() 431 result._api_client.create_station = Mock()
375 432
376 result.create_station() 433 result.create_station()
@@ -391,12 +448,14 @@ class TestSongSearchResultItem(TestCase):
391 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 448 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
392 449
393 def test_repr(self): 450 def test_repr(self):
394 result = SearchResultItem.from_json(self.api_client_mock, self.SONG_JSON_DATA) 451 result = pm.SearchResultItem.from_json(
452 self.api_client_mock, self.SONG_JSON_DATA)
395 expected = ("SongSearchResultItem(artist='artist_name_mock', score=100, song_name='song_name_mock', token='S0000000')") 453 expected = ("SongSearchResultItem(artist='artist_name_mock', score=100, song_name='song_name_mock', token='S0000000')")
396 self.assertEqual(expected, repr(result)) 454 self.assertEqual(expected, repr(result))
397 455
398 def test_create_station(self): 456 def test_create_station(self):
399 result = SearchResultItem.from_json(self.api_client_mock, self.SONG_JSON_DATA) 457 result = pm.SearchResultItem.from_json(
458 self.api_client_mock, self.SONG_JSON_DATA)
400 result._api_client.create_station = Mock() 459 result._api_client.create_station = Mock()
401 460
402 result.create_station() 461 result.create_station()
@@ -416,12 +475,14 @@ class TestGenreStationSearchResultItem(TestCase):
416 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 475 self.api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
417 476
418 def test_repr(self): 477 def test_repr(self):
419 result = SearchResultItem.from_json(self.api_client_mock, self.GENRE_JSON_DATA) 478 result = pm.SearchResultItem.from_json(
479 self.api_client_mock, self.GENRE_JSON_DATA)
420 expected = ("GenreStationSearchResultItem(score=100, station_name='station_name_mock', token='G0000000')") 480 expected = ("GenreStationSearchResultItem(score=100, station_name='station_name_mock', token='G0000000')")
421 self.assertEqual(expected, repr(result)) 481 self.assertEqual(expected, repr(result))
422 482
423 def test_create_station(self): 483 def test_create_station(self):
424 result = SearchResultItem.from_json(self.api_client_mock, self.GENRE_JSON_DATA) 484 result = pm.SearchResultItem.from_json(
485 self.api_client_mock, self.GENRE_JSON_DATA)
425 result._api_client.create_station = Mock() 486 result._api_client.create_station = Mock()
426 487
427 result.create_station() 488 result.create_station()
@@ -455,7 +516,7 @@ class TestSearchResult(TestCase):
455 def setUp(self): 516 def setUp(self):
456 api_client_mock = Mock(spec=APIClient) 517 api_client_mock = Mock(spec=APIClient)
457 api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY 518 api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY
458 self.result = SearchResult.from_json(api_client_mock, self.JSON_DATA) 519 self.result = pm.SearchResult.from_json(api_client_mock, self.JSON_DATA)
459 520
460 def test_repr(self): 521 def test_repr(self):
461 expected = ("SearchResult(artists=[ArtistSearchResultItem(artist='artist_mock', likely_match=False, score=80, " 522 expected = ("SearchResult(artists=[ArtistSearchResultItem(artist='artist_mock', likely_match=False, score=80, "
@@ -464,3 +525,59 @@ class TestSearchResult(TestCase):
464 "songs=[SongSearchResultItem(artist='song_artist_mock', score=100, song_name='song_name_mock', " 525 "songs=[SongSearchResultItem(artist='song_artist_mock', score=100, song_name='song_name_mock', "
465 "token='S0000000')])") 526 "token='S0000000')])")
466 self.assertEqual(expected, repr(self.result)) 527 self.assertEqual(expected, repr(self.result))
528
529
530class TestGenreStationList(TestCase):
531
532 TEST_DATA = {
533 "checksum": "bar",
534 "categories": [
535 { "categoryName": "foo", "stations": [] },
536 ]
537 }
538
539 def test_has_changed(self):
540 api_client = Mock()
541 api_client.get_station_list_checksum.return_value = "foo"
542
543 stations = pm.GenreStationList.from_json(api_client, self.TEST_DATA)
544 self.assertTrue(stations.has_changed())
545
546
547class TestStationList(TestCase):
548
549 TEST_DATA = {
550 "checksum": "bar",
551 "stations": [],
552 }
553
554 def test_has_changed(self):
555 api_client = Mock()
556 api_client.get_station_list_checksum.return_value = "foo"
557
558 stations = pm.StationList.from_json(api_client, self.TEST_DATA)
559 self.assertTrue(stations.has_changed())
560
561
562class TestBookmark(TestCase):
563
564 SONG_BOOKMARK = { "songName": "foo", "bookmarkToken": "token" }
565 ARTIST_BOOKMARK = { "artistName": "foo", "bookmarkToken": "token" }
566
567 def setUp(self):
568 self.client = Mock()
569
570 def test_is_song_bookmark(self):
571 s = pm.Bookmark.from_json(self.client, self.SONG_BOOKMARK)
572 a = pm.Bookmark.from_json(self.client, self.ARTIST_BOOKMARK)
573
574 self.assertTrue(s.is_song_bookmark)
575 self.assertFalse(a.is_song_bookmark)
576
577 def test_delete_song_bookmark(self):
578 pm.Bookmark.from_json(self.client, self.SONG_BOOKMARK).delete()
579 self.client.delete_song_bookmark.assert_called_with("token")
580
581 def test_delete_artist_bookmark(self):
582 pm.Bookmark.from_json(self.client, self.ARTIST_BOOKMARK).delete()
583 self.client.delete_artist_bookmark.assert_called_with("token")