diff options
author | Mike Crute <mike@crute.us> | 2017-10-07 04:10:14 +0000 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2017-10-07 04:37:42 +0000 |
commit | eac047b29356b98c368a0a420d1abcd089ac8b09 (patch) | |
tree | 9623091845d0beb91abb86df7af31118d7b6ab8c | |
parent | e473c68962a616e2d6b53fc07cead6856c8128a7 (diff) | |
download | pydora-eac047b29356b98c368a0a420d1abcd089ac8b09.tar.bz2 pydora-eac047b29356b98c368a0a420d1abcd089ac8b09.tar.xz pydora-eac047b29356b98c368a0a420d1abcd089ac8b09.zip |
Add tests
-rw-r--r-- | tests/test_pandora/test_client.py | 59 | ||||
-rw-r--r-- | tests/test_pandora/test_clientbuilder.py | 4 | ||||
-rw-r--r-- | tests/test_pandora/test_models.py | 155 |
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 @@ | |||
1 | from unittest import TestCase | 1 | from unittest import TestCase |
2 | 2 | ||
3 | from pandora import errors | 3 | from pandora import errors |
4 | from pandora.models.pandora import AdItem | ||
4 | from pandora.client import APIClient, BaseAPIClient | 5 | from pandora.client import APIClient, BaseAPIClient |
5 | from pandora.py2compat import Mock, call, patch | 6 | from pandora.py2compat import Mock, call, patch |
6 | from tests.test_pandora.test_models import TestAdItem | 7 | from 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 | |||
147 | class 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 | |||
173 | class 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 | ||
168 | class TestPydoraConfigFileBuilder(TestCase): | 172 | class 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 | ||
5 | from pandora.client import APIClient | 5 | from pandora.client import APIClient |
6 | from pandora.errors import ParameterMissing | 6 | from pandora.errors import ParameterMissing |
7 | from pandora.models.pandora import SearchResult | ||
8 | from pandora.models.pandora import AdItem, PlaylistModel, SearchResultItem | ||
9 | 7 | ||
10 | import pandora.models as m | 8 | import pandora.models as m |
9 | import pandora.models.pandora as pm | ||
11 | 10 | ||
12 | 11 | ||
13 | class TestField(TestCase): | 12 | class 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 | ||
206 | class 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 | |||
231 | class 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 | |||
207 | class TestAdItem(TestCase): | 246 | class 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 | ||
343 | class TestArtistSearchResultItem(TestCase): | 397 | class 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 | |||
530 | class 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 | |||
547 | class 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 | |||
562 | class 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") | ||