diff options
Diffstat (limited to 'tests/test_pandora')
-rw-r--r-- | tests/test_pandora/test_client.py | 237 | ||||
-rw-r--r-- | tests/test_pandora/test_clientbuilder.py | 112 | ||||
-rw-r--r-- | tests/test_pandora/test_errors.py | 1 | ||||
-rw-r--r-- | tests/test_pandora/test_models.py | 303 | ||||
-rw-r--r-- | tests/test_pandora/test_transport.py | 60 |
5 files changed, 397 insertions, 316 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 | ||
15 | class TestAPIClientLogin(TestCase): | 15 | class 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 | ||
58 | class TestCallingAPIClient(TestCase): | 57 | class 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 | ||
102 | class TestGettingQualities(TestCase): | 108 | class 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 | ||
123 | class TestGettingAds(TestCase): | 130 | class 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 | ||
153 | class TestCreatingStation(TestCase): | 168 | class 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 | ||
179 | class TestCreatingGenreStation(TestCase): | 196 | class 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 | ||
197 | class TestAdditionalUrls(TestCase): | 210 | class 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...) |
265 | class TestAPIClientExhaustive(TestCase): | 291 | class 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 | ) | ||
diff --git a/tests/test_pandora/test_clientbuilder.py b/tests/test_pandora/test_clientbuilder.py index af0e219..17a4036 100644 --- a/tests/test_pandora/test_clientbuilder.py +++ b/tests/test_pandora/test_clientbuilder.py | |||
@@ -8,7 +8,6 @@ from pandora.transport import DEFAULT_API_HOST | |||
8 | 8 | ||
9 | 9 | ||
10 | class TestTranslatingDict(TestCase): | 10 | class TestTranslatingDict(TestCase): |
11 | |||
12 | class TestDict(cb.TranslatingDict): | 11 | class TestDict(cb.TranslatingDict): |
13 | 12 | ||
14 | KEY_TRANSLATIONS = {"FOO": "BAR"} | 13 | KEY_TRANSLATIONS = {"FOO": "BAR"} |
@@ -62,29 +61,32 @@ class TestTranslatingDict(TestCase): | |||
62 | 61 | ||
63 | 62 | ||
64 | class TestSettingsDictBuilder(TestCase): | 63 | class TestSettingsDictBuilder(TestCase): |
65 | |||
66 | @classmethod | 64 | @classmethod |
67 | def _build_minimal(self): | 65 | def _build_minimal(self): |
68 | return cb.SettingsDictBuilder({ | 66 | return cb.SettingsDictBuilder( |
69 | "DECRYPTION_KEY": "blowfishkey", | 67 | { |
70 | "ENCRYPTION_KEY": "blowfishkey", | 68 | "DECRYPTION_KEY": "blowfishkey", |
71 | "PARTNER_USER": "user", | 69 | "ENCRYPTION_KEY": "blowfishkey", |
72 | "PARTNER_PASSWORD": "pass", | 70 | "PARTNER_USER": "user", |
73 | "DEVICE": "dev", | 71 | "PARTNER_PASSWORD": "pass", |
74 | }).build() | 72 | "DEVICE": "dev", |
73 | } | ||
74 | ).build() | ||
75 | 75 | ||
76 | @classmethod | 76 | @classmethod |
77 | def _build_maximal(self): | 77 | def _build_maximal(self): |
78 | return cb.SettingsDictBuilder({ | 78 | return cb.SettingsDictBuilder( |
79 | "DECRYPTION_KEY": "blowfishkey", | 79 | { |
80 | "ENCRYPTION_KEY": "blowfishkey", | 80 | "DECRYPTION_KEY": "blowfishkey", |
81 | "PARTNER_USER": "user", | 81 | "ENCRYPTION_KEY": "blowfishkey", |
82 | "PARTNER_PASSWORD": "pass", | 82 | "PARTNER_USER": "user", |
83 | "DEVICE": "dev", | 83 | "PARTNER_PASSWORD": "pass", |
84 | "PROXY": "proxy.example.com", | 84 | "DEVICE": "dev", |
85 | "AUDIO_QUALITY": "high", | 85 | "PROXY": "proxy.example.com", |
86 | "API_HOST": "example.com", | 86 | "AUDIO_QUALITY": "high", |
87 | }).build() | 87 | "API_HOST": "example.com", |
88 | } | ||
89 | ).build() | ||
88 | 90 | ||
89 | def test_building(self): | 91 | def test_building(self): |
90 | client = TestSettingsDictBuilder._build_minimal() | 92 | client = TestSettingsDictBuilder._build_minimal() |
@@ -97,14 +99,15 @@ class TestSettingsDictBuilder(TestCase): | |||
97 | self.assertEqual({}, client.transport._http.proxies) | 99 | self.assertEqual({}, client.transport._http.proxies) |
98 | self.assertEqual(DEFAULT_API_HOST, client.transport.api_host) | 100 | self.assertEqual(DEFAULT_API_HOST, client.transport.api_host) |
99 | self.assertEqual( | 101 | self.assertEqual( |
100 | APIClient.MED_AUDIO_QUALITY, client.default_audio_quality) | 102 | APIClient.MED_AUDIO_QUALITY, client.default_audio_quality |
103 | ) | ||
101 | 104 | ||
102 | def test_validate_client(self): | 105 | def test_validate_client(self): |
103 | client = TestSettingsDictBuilder._build_maximal() | 106 | client = TestSettingsDictBuilder._build_maximal() |
104 | expected_proxies = { | 107 | expected_proxies = { |
105 | "http": "proxy.example.com", | 108 | "http": "proxy.example.com", |
106 | "https": "proxy.example.com" | 109 | "https": "proxy.example.com", |
107 | } | 110 | } |
108 | 111 | ||
109 | self.assertIsNotNone(client.transport.cryptor.bf_in) | 112 | self.assertIsNotNone(client.transport.cryptor.bf_in) |
110 | self.assertIsNotNone(client.transport.cryptor.bf_out) | 113 | self.assertIsNotNone(client.transport.cryptor.bf_out) |
@@ -119,7 +122,6 @@ class TestSettingsDictBuilder(TestCase): | |||
119 | 122 | ||
120 | 123 | ||
121 | class TestFileBasedBuilder(TestCase): | 124 | class TestFileBasedBuilder(TestCase): |
122 | |||
123 | class StubBuilder(cb.FileBasedClientBuilder): | 125 | class StubBuilder(cb.FileBasedClientBuilder): |
124 | 126 | ||
125 | DEFAULT_CONFIG_FILE = "foo" | 127 | DEFAULT_CONFIG_FILE = "foo" |
@@ -170,7 +172,6 @@ class TestFileBasedBuilder(TestCase): | |||
170 | 172 | ||
171 | 173 | ||
172 | class TestPydoraConfigFileBuilder(TestCase): | 174 | class TestPydoraConfigFileBuilder(TestCase): |
173 | |||
174 | def test_cfg_to_dict(self): | 175 | def test_cfg_to_dict(self): |
175 | cfg = Mock() | 176 | cfg = Mock() |
176 | cfg.items = Mock(return_value=[("a", "b"), ("c", "d")]) | 177 | cfg.items = Mock(return_value=[("a", "b"), ("c", "d")]) |
@@ -184,38 +185,43 @@ class TestPydoraConfigFileBuilder(TestCase): | |||
184 | path = os.path.join(os.path.dirname(__file__), "pydora.cfg") | 185 | path = os.path.join(os.path.dirname(__file__), "pydora.cfg") |
185 | cfg = cb.PydoraConfigFileBuilder(path).parse_config() | 186 | cfg = cb.PydoraConfigFileBuilder(path).parse_config() |
186 | 187 | ||
187 | self.assertDictEqual(cfg, { | 188 | self.assertDictEqual( |
188 | "AUDIO_QUALITY": "test_quality", | 189 | cfg, |
189 | "DECRYPTION_KEY": "test_decryption_key", | 190 | { |
190 | "DEVICE": "test_device", | 191 | "AUDIO_QUALITY": "test_quality", |
191 | "ENCRYPTION_KEY": "test_encryption_key", | 192 | "DECRYPTION_KEY": "test_decryption_key", |
192 | "PARTNER_PASSWORD": "test_partner_password", | 193 | "DEVICE": "test_device", |
193 | "PARTNER_USER": "test_partner_username", | 194 | "ENCRYPTION_KEY": "test_encryption_key", |
194 | "API_HOST": "test_host", | 195 | "PARTNER_PASSWORD": "test_partner_password", |
195 | "USER": { | 196 | "PARTNER_USER": "test_partner_username", |
196 | "USERNAME": "test_username", | 197 | "API_HOST": "test_host", |
197 | "PASSWORD": "test_password", | 198 | "USER": { |
198 | } | 199 | "USERNAME": "test_username", |
199 | }) | 200 | "PASSWORD": "test_password", |
201 | }, | ||
202 | }, | ||
203 | ) | ||
200 | 204 | ||
201 | 205 | ||
202 | class TestPianobarConfigFileBuilder(TestCase): | 206 | class TestPianobarConfigFileBuilder(TestCase): |
203 | |||
204 | def test_integration(self): | 207 | def test_integration(self): |
205 | path = os.path.join(os.path.dirname(__file__), "pianobar.cfg") | 208 | path = os.path.join(os.path.dirname(__file__), "pianobar.cfg") |
206 | cfg = cb.PianobarConfigFileBuilder(path).parse_config() | 209 | cfg = cb.PianobarConfigFileBuilder(path).parse_config() |
207 | 210 | ||
208 | self.assertDictEqual(cfg, { | 211 | self.assertDictEqual( |
209 | "AUDIO_QUALITY": "test_qualityQuality", | 212 | cfg, |
210 | "DECRYPTION_KEY": "test_decryption_key", | 213 | { |
211 | "DEVICE": "test_device", | 214 | "AUDIO_QUALITY": "test_qualityQuality", |
212 | "ENCRYPTION_KEY": "test_encryption_key", | 215 | "DECRYPTION_KEY": "test_decryption_key", |
213 | "PARTNER_PASSWORD": "test_partner_password", | 216 | "DEVICE": "test_device", |
214 | "PARTNER_USER": "test_partner_username", | 217 | "ENCRYPTION_KEY": "test_encryption_key", |
215 | "API_HOST": "test_host/services/json/", | 218 | "PARTNER_PASSWORD": "test_partner_password", |
216 | "PROXY": "test_proxy", | 219 | "PARTNER_USER": "test_partner_username", |
217 | "USER": { | 220 | "API_HOST": "test_host/services/json/", |
218 | "USERNAME": "test_username", | 221 | "PROXY": "test_proxy", |
219 | "PASSWORD": "test_password", | 222 | "USER": { |
220 | } | 223 | "USERNAME": "test_username", |
221 | }) | 224 | "PASSWORD": "test_password", |
225 | }, | ||
226 | }, | ||
227 | ) | ||
diff --git a/tests/test_pandora/test_errors.py b/tests/test_pandora/test_errors.py index 778771a..d9df41f 100644 --- a/tests/test_pandora/test_errors.py +++ b/tests/test_pandora/test_errors.py | |||
@@ -4,7 +4,6 @@ from pandora.errors import InternalServerError, PandoraException | |||
4 | 4 | ||
5 | 5 | ||
6 | class TestPandoraExceptionConstructionFromErrorCode(TestCase): | 6 | class TestPandoraExceptionConstructionFromErrorCode(TestCase): |
7 | |||
8 | def test_it_returns_specific_error_class_if_possible(self): | 7 | def test_it_returns_specific_error_class_if_possible(self): |
9 | error = PandoraException.from_code(0, "Test Message") | 8 | error = PandoraException.from_code(0, "Test Message") |
10 | self.assertIsInstance(error, InternalServerError) | 9 | self.assertIsInstance(error, InternalServerError) |
diff --git a/tests/test_pandora/test_models.py b/tests/test_pandora/test_models.py index cb650df..16307b4 100644 --- a/tests/test_pandora/test_models.py +++ b/tests/test_pandora/test_models.py | |||
@@ -14,7 +14,6 @@ import pandora.models.playlist as plm | |||
14 | 14 | ||
15 | 15 | ||
16 | class TestField(TestCase): | 16 | class TestField(TestCase): |
17 | |||
18 | def test_defaults(self): | 17 | def test_defaults(self): |
19 | field = m.Field("name") | 18 | field = m.Field("name") |
20 | 19 | ||
@@ -24,7 +23,6 @@ class TestField(TestCase): | |||
24 | 23 | ||
25 | 24 | ||
26 | class TestModelMetaClass(TestCase): | 25 | class TestModelMetaClass(TestCase): |
27 | |||
28 | class TestModel(metaclass=m.ModelMetaClass): | 26 | class TestModel(metaclass=m.ModelMetaClass): |
29 | 27 | ||
30 | foo = "bar" | 28 | foo = "bar" |
@@ -40,7 +38,6 @@ class TestModelMetaClass(TestCase): | |||
40 | 38 | ||
41 | 39 | ||
42 | class TestDateField(TestCase): | 40 | class TestDateField(TestCase): |
43 | |||
44 | class SampleModel(m.PandoraModel): | 41 | class SampleModel(m.PandoraModel): |
45 | 42 | ||
46 | date_field = m.DateField("foo") | 43 | date_field = m.DateField("foo") |
@@ -57,34 +54,26 @@ class TestDateField(TestCase): | |||
57 | 54 | ||
58 | 55 | ||
59 | class TestAdditionalUrlField(TestCase): | 56 | class TestAdditionalUrlField(TestCase): |
60 | |||
61 | def test_single_url(self): | 57 | def test_single_url(self): |
62 | dummy_data = { | 58 | dummy_data = {"_paramAdditionalUrls": ["foo"]} |
63 | '_paramAdditionalUrls': ['foo'] | ||
64 | } | ||
65 | 59 | ||
66 | field = plm.AdditionalUrlField("additionalAudioUrl") | 60 | field = plm.AdditionalUrlField("additionalAudioUrl") |
67 | 61 | ||
68 | ret = field.formatter(None, dummy_data, 'test') | 62 | ret = field.formatter(None, dummy_data, "test") |
69 | 63 | ||
70 | self.assertEqual(ret, {'foo': 'test'}) | 64 | self.assertEqual(ret, {"foo": "test"}) |
71 | 65 | ||
72 | def test_multiple_urls(self): | 66 | def test_multiple_urls(self): |
73 | dummy_data = { | 67 | dummy_data = {"_paramAdditionalUrls": ["abc", "def",]} |
74 | '_paramAdditionalUrls': [ | ||
75 | 'abc', | ||
76 | 'def', | ||
77 | ] | ||
78 | } | ||
79 | 68 | ||
80 | field = plm.AdditionalUrlField("additionalAudioUrl") | 69 | field = plm.AdditionalUrlField("additionalAudioUrl") |
81 | 70 | ||
82 | ret = field.formatter(None, dummy_data, ['foo', 'bar']) | 71 | ret = field.formatter(None, dummy_data, ["foo", "bar"]) |
83 | 72 | ||
84 | expected = { | 73 | expected = { |
85 | 'abc': 'foo', | 74 | "abc": "foo", |
86 | 'def': 'bar', | 75 | "def": "bar", |
87 | } | 76 | } |
88 | 77 | ||
89 | self.assertEqual(ret, expected) | 78 | self.assertEqual(ret, expected) |
90 | 79 | ||
@@ -99,7 +88,6 @@ class TestPandoraModel(TestCase): | |||
99 | } | 88 | } |
100 | 89 | ||
101 | class TestModel(m.PandoraModel): | 90 | class TestModel(m.PandoraModel): |
102 | |||
103 | class SubModel(m.PandoraModel): | 91 | class SubModel(m.PandoraModel): |
104 | 92 | ||
105 | field1 = m.Field("field1") | 93 | field1 = m.Field("field1") |
@@ -116,7 +104,6 @@ class TestPandoraModel(TestCase): | |||
116 | pass | 104 | pass |
117 | 105 | ||
118 | class ExtraReprModel(m.PandoraModel): | 106 | class ExtraReprModel(m.PandoraModel): |
119 | |||
120 | def __repr__(self): | 107 | def __repr__(self): |
121 | return self._base_repr("Foo") | 108 | return self._base_repr("Foo") |
122 | 109 | ||
@@ -153,9 +140,11 @@ class TestPandoraModel(TestCase): | |||
153 | self.assertEqual("a string", result[1].field1) | 140 | self.assertEqual("a string", result[1].field1) |
154 | 141 | ||
155 | def test_repr(self): | 142 | def test_repr(self): |
156 | expected = ("TestModel(field1='a string', field2=['test2'], field3=42," | 143 | expected = ( |
157 | " field4=SubModel(field1='foo'), " | 144 | "TestModel(field1='a string', field2=['test2'], field3=42," |
158 | "field5=[SubModel(field1='foo'), SubModel(field1='bar')])") | 145 | " field4=SubModel(field1='foo'), " |
146 | "field5=[SubModel(field1='foo'), SubModel(field1='bar')])" | ||
147 | ) | ||
159 | result = self.TestModel.from_json(None, self.JSON_DATA) | 148 | result = self.TestModel.from_json(None, self.JSON_DATA) |
160 | self.assertEqual(expected, repr(result)) | 149 | self.assertEqual(expected, repr(result)) |
161 | 150 | ||
@@ -179,12 +168,12 @@ class TestSubModel(m.PandoraModel): | |||
179 | class TestPandoraListModel(TestCase): | 168 | class TestPandoraListModel(TestCase): |
180 | 169 | ||
181 | JSON_DATA = { | 170 | JSON_DATA = { |
182 | "field1": 42, | 171 | "field1": 42, |
183 | "field2": [ | 172 | "field2": [ |
184 | {"idx": "foo", "fieldS1": "Foo"}, | 173 | {"idx": "foo", "fieldS1": "Foo"}, |
185 | {"idx": "bar", "fieldS1": "Bar"}, | 174 | {"idx": "bar", "fieldS1": "Bar"}, |
186 | ] | 175 | ], |
187 | } | 176 | } |
188 | 177 | ||
189 | class TestModel(m.PandoraListModel): | 178 | class TestModel(m.PandoraListModel): |
190 | 179 | ||
@@ -204,8 +193,10 @@ class TestPandoraListModel(TestCase): | |||
204 | self.assertEqual("Bar", self.result[1].fieldS1) | 193 | self.assertEqual("Bar", self.result[1].fieldS1) |
205 | 194 | ||
206 | def test_repr(self): | 195 | def test_repr(self): |
207 | expected = ("TestModel(field1=42, [TestSubModel(fieldS1='Foo', " | 196 | expected = ( |
208 | "idx='foo'), TestSubModel(fieldS1='Bar', idx='bar')])") | 197 | "TestModel(field1=42, [TestSubModel(fieldS1='Foo', " |
198 | "idx='foo'), TestSubModel(fieldS1='Bar', idx='bar')])" | ||
199 | ) | ||
209 | self.assertEqual(expected, repr(self.result)) | 200 | self.assertEqual(expected, repr(self.result)) |
210 | 201 | ||
211 | def test_indexed_model(self): | 202 | def test_indexed_model(self): |
@@ -232,17 +223,17 @@ class TestPandoraListModel(TestCase): | |||
232 | class TestPandoraDictListModel(TestCase): | 223 | class TestPandoraDictListModel(TestCase): |
233 | 224 | ||
234 | JSON_DATA = { | 225 | JSON_DATA = { |
235 | "field1": 42, | 226 | "field1": 42, |
236 | "fieldD1": [ | 227 | "fieldD1": [ |
237 | { | 228 | { |
238 | "dictKey": "Foobear", | 229 | "dictKey": "Foobear", |
239 | "listKey": [ | 230 | "listKey": [ |
240 | {"idx": "foo", "fieldS1": "Foo"}, | 231 | {"idx": "foo", "fieldS1": "Foo"}, |
241 | {"idx": "bar", "fieldS1": "Bar"}, | 232 | {"idx": "bar", "fieldS1": "Bar"}, |
242 | ] | 233 | ], |
243 | } | 234 | } |
244 | ] | 235 | ], |
245 | } | 236 | } |
246 | 237 | ||
247 | class TestModel(m.PandoraDictListModel): | 238 | class TestModel(m.PandoraDictListModel): |
248 | 239 | ||
@@ -266,9 +257,11 @@ class TestPandoraDictListModel(TestCase): | |||
266 | self.assertEqual("bar", self.result["Foobear"][1].idx) | 257 | self.assertEqual("bar", self.result["Foobear"][1].idx) |
267 | 258 | ||
268 | def test_repr(self): | 259 | def test_repr(self): |
269 | expected = ("TestModel(field1=42, {'Foobear': " | 260 | expected = ( |
270 | "[TestSubModel(fieldS1='Foo', idx='foo'), " | 261 | "TestModel(field1=42, {'Foobear': " |
271 | "TestSubModel(fieldS1='Bar', idx='bar')]})") | 262 | "[TestSubModel(fieldS1='Foo', idx='foo'), " |
263 | "TestSubModel(fieldS1='Bar', idx='bar')]})" | ||
264 | ) | ||
272 | self.assertEqual(expected, repr(self.result)) | 265 | self.assertEqual(expected, repr(self.result)) |
273 | 266 | ||
274 | 267 | ||
@@ -320,7 +313,6 @@ class TestPlaylistItemModel(TestCase): | |||
320 | 313 | ||
321 | 314 | ||
322 | class TestPlaylistModel(TestCase): | 315 | class TestPlaylistModel(TestCase): |
323 | |||
324 | def setUp(self): | 316 | def setUp(self): |
325 | self.client = Mock() | 317 | self.client = Mock() |
326 | self.playlist = plm.PlaylistModel(self.client) | 318 | self.playlist = plm.PlaylistModel(self.client) |
@@ -354,47 +346,47 @@ class TestPlaylistModel(TestCase): | |||
354 | class TestAdItem(TestCase): | 346 | class TestAdItem(TestCase): |
355 | 347 | ||
356 | JSON_DATA = { | 348 | JSON_DATA = { |
357 | 'audioUrlMap': { | 349 | "audioUrlMap": { |
358 | 'mediumQuality': { | 350 | "mediumQuality": { |
359 | 'audioUrl': 'med_url_mock', | 351 | "audioUrl": "med_url_mock", |
360 | 'bitrate': '64', | 352 | "bitrate": "64", |
361 | 'protocol': 'http', | 353 | "protocol": "http", |
362 | 'encoding': 'aacplus' | 354 | "encoding": "aacplus", |
363 | }, | 355 | }, |
364 | 'highQuality': { | 356 | "highQuality": { |
365 | 'audioUrl': 'high_url_mock', | 357 | "audioUrl": "high_url_mock", |
366 | 'bitrate': '64', | 358 | "bitrate": "64", |
367 | 'protocol': 'http', | 359 | "protocol": "http", |
368 | 'encoding': 'aacplus' | 360 | "encoding": "aacplus", |
361 | }, | ||
362 | "lowQuality": { | ||
363 | "audioUrl": "low_url_mock", | ||
364 | "bitrate": "32", | ||
365 | "protocol": "http", | ||
366 | "encoding": "aacplus", | ||
369 | }, | 367 | }, |
370 | 'lowQuality': { | ||
371 | 'audioUrl': 'low_url_mock', | ||
372 | 'bitrate': '32', | ||
373 | 'protocol': 'http', | ||
374 | 'encoding': 'aacplus' | ||
375 | } | ||
376 | }, | 368 | }, |
377 | 'clickThroughUrl': 'click_url_mock', | 369 | "clickThroughUrl": "click_url_mock", |
378 | 'imageUrl': 'img_url_mock', | 370 | "imageUrl": "img_url_mock", |
379 | 'companyName': '', | 371 | "companyName": "", |
380 | 'title': '', | 372 | "title": "", |
381 | 'trackGain': '0.0', | 373 | "trackGain": "0.0", |
382 | 'adTrackingTokens': ['token_1_mock', 'token_2_mock'] | 374 | "adTrackingTokens": ["token_1_mock", "token_2_mock"], |
383 | } | 375 | } |
384 | 376 | ||
385 | def setUp(self): | 377 | def setUp(self): |
386 | api_client_mock = Mock(spec=APIClient) | 378 | api_client_mock = Mock(spec=APIClient) |
387 | api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY | 379 | api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY |
388 | self.result = am.AdItem.from_json(api_client_mock, self.JSON_DATA) | 380 | self.result = am.AdItem.from_json(api_client_mock, self.JSON_DATA) |
389 | self.result.station_id = 'station_id_mock' | 381 | self.result.station_id = "station_id_mock" |
390 | self.result.ad_token = 'token_mock' | 382 | self.result.ad_token = "token_mock" |
391 | 383 | ||
392 | def test_is_ad_is_true(self): | 384 | def test_is_ad_is_true(self): |
393 | assert self.result.is_ad is True | 385 | assert self.result.is_ad is True |
394 | 386 | ||
395 | def test_register_ad(self): | 387 | def test_register_ad(self): |
396 | self.result._api_client.register_ad = Mock() | 388 | self.result._api_client.register_ad = Mock() |
397 | self.result.register_ad('id_mock') | 389 | self.result.register_ad("id_mock") |
398 | 390 | ||
399 | assert self.result._api_client.register_ad.called | 391 | assert self.result._api_client.register_ad.called |
400 | 392 | ||
@@ -403,12 +395,12 @@ class TestAdItem(TestCase): | |||
403 | self.result.tracking_tokens = [] | 395 | self.result.tracking_tokens = [] |
404 | self.result._api_client.register_ad = Mock(spec=am.AdItem) | 396 | self.result._api_client.register_ad = Mock(spec=am.AdItem) |
405 | 397 | ||
406 | self.result.register_ad('id_mock') | 398 | self.result.register_ad("id_mock") |
407 | 399 | ||
408 | assert self.result._api_client.register_ad.called | 400 | assert self.result._api_client.register_ad.called |
409 | 401 | ||
410 | def test_prepare_playback(self): | 402 | def test_prepare_playback(self): |
411 | with patch.object(plm.PlaylistModel, 'prepare_playback') as super_mock: | 403 | with patch.object(plm.PlaylistModel, "prepare_playback") as super_mock: |
412 | 404 | ||
413 | self.result.register_ad = Mock() | 405 | self.result.register_ad = Mock() |
414 | self.result.prepare_playback() | 406 | self.result.prepare_playback() |
@@ -416,21 +408,26 @@ class TestAdItem(TestCase): | |||
416 | assert super_mock.called | 408 | assert super_mock.called |
417 | 409 | ||
418 | def test_prepare_playback_raises_paramater_missing(self): | 410 | def test_prepare_playback_raises_paramater_missing(self): |
419 | with patch.object(plm.PlaylistModel, 'prepare_playback') as super_mock: | 411 | with patch.object(plm.PlaylistModel, "prepare_playback") as super_mock: |
420 | 412 | ||
421 | self.result.register_ad = Mock(side_effect=ParameterMissing( | 413 | self.result.register_ad = Mock( |
422 | 'No ad tracking tokens provided for registration.') | 414 | side_effect=ParameterMissing( |
423 | ) | 415 | "No ad tracking tokens provided for registration." |
416 | ) | ||
417 | ) | ||
424 | self.assertRaises(ParameterMissing, self.result.prepare_playback) | 418 | self.assertRaises(ParameterMissing, self.result.prepare_playback) |
425 | assert self.result.register_ad.called | 419 | assert self.result.register_ad.called |
426 | assert not super_mock.called | 420 | assert not super_mock.called |
427 | 421 | ||
428 | def test_prepare_playback_handles_paramater_missing_if_no_tokens(self): | 422 | def test_prepare_playback_handles_paramater_missing_if_no_tokens(self): |
429 | with patch.object(plm.PlaylistModel, 'prepare_playback') as super_mock: | 423 | with patch.object(plm.PlaylistModel, "prepare_playback") as super_mock: |
430 | 424 | ||
431 | self.result.tracking_tokens = [] | 425 | self.result.tracking_tokens = [] |
432 | self.result.register_ad = Mock(side_effect=ParameterMissing( | 426 | self.result.register_ad = Mock( |
433 | 'No ad tracking tokens provided for registration.')) | 427 | side_effect=ParameterMissing( |
428 | "No ad tracking tokens provided for registration." | ||
429 | ) | ||
430 | ) | ||
434 | self.result.prepare_playback() | 431 | self.result.prepare_playback() |
435 | assert self.result.register_ad.called | 432 | assert self.result.register_ad.called |
436 | assert super_mock.called | 433 | assert super_mock.called |
@@ -449,43 +446,45 @@ class TestSearchResultItem(TestCase): | |||
449 | "artistName": "artist_name_mock", | 446 | "artistName": "artist_name_mock", |
450 | "musicToken": "S0000000", | 447 | "musicToken": "S0000000", |
451 | "songName": "song_name_mock", | 448 | "songName": "song_name_mock", |
452 | "score": 100 | 449 | "score": 100, |
453 | } | 450 | } |
454 | 451 | ||
455 | ARTIST_JSON_DATA = { | 452 | ARTIST_JSON_DATA = { |
456 | "artistName": "artist_name_mock", | 453 | "artistName": "artist_name_mock", |
457 | "musicToken": "R0000000", | 454 | "musicToken": "R0000000", |
458 | "likelyMatch": False, | 455 | "likelyMatch": False, |
459 | "score": 100 | 456 | "score": 100, |
460 | } | 457 | } |
461 | 458 | ||
462 | COMPOSER_JSON_DATA = { | 459 | COMPOSER_JSON_DATA = { |
463 | "artistName": "composer_name_mock", | 460 | "artistName": "composer_name_mock", |
464 | "musicToken": "C0000000", | 461 | "musicToken": "C0000000", |
465 | "likelyMatch": False, | 462 | "likelyMatch": False, |
466 | "score": 100 | 463 | "score": 100, |
467 | } | 464 | } |
468 | 465 | ||
469 | GENRE_JSON_DATA = { | 466 | GENRE_JSON_DATA = { |
470 | "stationName": "station_name_mock", | 467 | "stationName": "station_name_mock", |
471 | "musicToken": "G0000000", | 468 | "musicToken": "G0000000", |
472 | "score": 100 | 469 | "score": 100, |
473 | } | 470 | } |
474 | 471 | ||
475 | UNKNOWN_JSON_DATA = { | 472 | UNKNOWN_JSON_DATA = { |
476 | "stationName": "unknown_name_mock", | 473 | "stationName": "unknown_name_mock", |
477 | "musicToken": "U0000000", | 474 | "musicToken": "U0000000", |
478 | "score": 100 | 475 | "score": 100, |
479 | } | 476 | } |
480 | 477 | ||
481 | def setUp(self): | 478 | def setUp(self): |
482 | self.api_client_mock = Mock(spec=APIClient) | 479 | self.api_client_mock = Mock(spec=APIClient) |
483 | self.api_client_mock.default_audio_quality = \ | 480 | self.api_client_mock.default_audio_quality = ( |
484 | APIClient.HIGH_AUDIO_QUALITY | 481 | APIClient.HIGH_AUDIO_QUALITY |
482 | ) | ||
485 | 483 | ||
486 | def test_is_song(self): | 484 | def test_is_song(self): |
487 | result = sm.SearchResultItem.from_json( | 485 | result = sm.SearchResultItem.from_json( |
488 | self.api_client_mock, self.SONG_JSON_DATA) | 486 | self.api_client_mock, self.SONG_JSON_DATA |
487 | ) | ||
489 | assert result.is_song | 488 | assert result.is_song |
490 | assert not result.is_artist | 489 | assert not result.is_artist |
491 | assert not result.is_composer | 490 | assert not result.is_composer |
@@ -493,7 +492,8 @@ class TestSearchResultItem(TestCase): | |||
493 | 492 | ||
494 | def test_is_artist(self): | 493 | def test_is_artist(self): |
495 | result = sm.SearchResultItem.from_json( | 494 | result = sm.SearchResultItem.from_json( |
496 | self.api_client_mock, self.ARTIST_JSON_DATA) | 495 | self.api_client_mock, self.ARTIST_JSON_DATA |
496 | ) | ||
497 | assert not result.is_song | 497 | assert not result.is_song |
498 | assert result.is_artist | 498 | assert result.is_artist |
499 | assert not result.is_composer | 499 | assert not result.is_composer |
@@ -501,7 +501,8 @@ class TestSearchResultItem(TestCase): | |||
501 | 501 | ||
502 | def test_is_composer(self): | 502 | def test_is_composer(self): |
503 | result = sm.SearchResultItem.from_json( | 503 | result = sm.SearchResultItem.from_json( |
504 | self.api_client_mock, self.COMPOSER_JSON_DATA) | 504 | self.api_client_mock, self.COMPOSER_JSON_DATA |
505 | ) | ||
505 | assert not result.is_song | 506 | assert not result.is_song |
506 | assert not result.is_artist | 507 | assert not result.is_artist |
507 | assert result.is_composer | 508 | assert result.is_composer |
@@ -509,7 +510,8 @@ class TestSearchResultItem(TestCase): | |||
509 | 510 | ||
510 | def test_is_genre_station(self): | 511 | def test_is_genre_station(self): |
511 | result = sm.SearchResultItem.from_json( | 512 | result = sm.SearchResultItem.from_json( |
512 | self.api_client_mock, self.GENRE_JSON_DATA) | 513 | self.api_client_mock, self.GENRE_JSON_DATA |
514 | ) | ||
513 | assert not result.is_song | 515 | assert not result.is_song |
514 | assert not result.is_artist | 516 | assert not result.is_artist |
515 | assert not result.is_composer | 517 | assert not result.is_composer |
@@ -518,7 +520,8 @@ class TestSearchResultItem(TestCase): | |||
518 | def test_fails_if_unknown(self): | 520 | def test_fails_if_unknown(self): |
519 | with self.assertRaises(NotImplementedError): | 521 | with self.assertRaises(NotImplementedError): |
520 | sm.SearchResultItem.from_json( | 522 | sm.SearchResultItem.from_json( |
521 | self.api_client_mock, self.UNKNOWN_JSON_DATA) | 523 | self.api_client_mock, self.UNKNOWN_JSON_DATA |
524 | ) | ||
522 | 525 | ||
523 | def test_interface(self): | 526 | def test_interface(self): |
524 | result = sm.SearchResultItem(self.api_client_mock) | 527 | result = sm.SearchResultItem(self.api_client_mock) |
@@ -533,44 +536,51 @@ class TestArtistSearchResultItem(TestCase): | |||
533 | "artistName": "artist_name_mock", | 536 | "artistName": "artist_name_mock", |
534 | "musicToken": "R0000000", | 537 | "musicToken": "R0000000", |
535 | "likelyMatch": False, | 538 | "likelyMatch": False, |
536 | "score": 100 | 539 | "score": 100, |
537 | } | 540 | } |
538 | 541 | ||
539 | COMPOSER_JSON_DATA = { | 542 | COMPOSER_JSON_DATA = { |
540 | "artistName": "composer_name_mock", | 543 | "artistName": "composer_name_mock", |
541 | "musicToken": "C0000000", | 544 | "musicToken": "C0000000", |
542 | "likelyMatch": False, | 545 | "likelyMatch": False, |
543 | "score": 100 | 546 | "score": 100, |
544 | } | 547 | } |
545 | 548 | ||
546 | def setUp(self): | 549 | def setUp(self): |
547 | self.api_client_mock = Mock(spec=APIClient) | 550 | self.api_client_mock = Mock(spec=APIClient) |
548 | self.api_client_mock.default_audio_quality = \ | 551 | self.api_client_mock.default_audio_quality = ( |
549 | APIClient.HIGH_AUDIO_QUALITY | 552 | APIClient.HIGH_AUDIO_QUALITY |
553 | ) | ||
550 | 554 | ||
551 | def test_repr(self): | 555 | def test_repr(self): |
552 | result = sm.SearchResultItem.from_json( | 556 | result = sm.SearchResultItem.from_json( |
553 | self.api_client_mock, self.ARTIST_JSON_DATA) | 557 | self.api_client_mock, self.ARTIST_JSON_DATA |
558 | ) | ||
554 | expected = ( | 559 | expected = ( |
555 | "ArtistSearchResultItem(artist='artist_name_mock', " | 560 | "ArtistSearchResultItem(artist='artist_name_mock', " |
556 | "likely_match=False, score=100, token='R0000000')") | 561 | "likely_match=False, score=100, token='R0000000')" |
562 | ) | ||
557 | self.assertEqual(expected, repr(result)) | 563 | self.assertEqual(expected, repr(result)) |
558 | 564 | ||
559 | result = sm.SearchResultItem.from_json( | 565 | result = sm.SearchResultItem.from_json( |
560 | self.api_client_mock, self.COMPOSER_JSON_DATA) | 566 | self.api_client_mock, self.COMPOSER_JSON_DATA |
567 | ) | ||
561 | expected = ( | 568 | expected = ( |
562 | "ArtistSearchResultItem(artist='composer_name_mock', " | 569 | "ArtistSearchResultItem(artist='composer_name_mock', " |
563 | "likely_match=False, score=100, token='C0000000')") | 570 | "likely_match=False, score=100, token='C0000000')" |
571 | ) | ||
564 | self.assertEqual(expected, repr(result)) | 572 | self.assertEqual(expected, repr(result)) |
565 | 573 | ||
566 | def test_create_station(self): | 574 | def test_create_station(self): |
567 | result = sm.SearchResultItem.from_json( | 575 | result = sm.SearchResultItem.from_json( |
568 | self.api_client_mock, self.ARTIST_JSON_DATA) | 576 | self.api_client_mock, self.ARTIST_JSON_DATA |
577 | ) | ||
569 | result._api_client.create_station = Mock() | 578 | result._api_client.create_station = Mock() |
570 | 579 | ||
571 | result.create_station() | 580 | result.create_station() |
572 | result._api_client.create_station.assert_called_with( | 581 | result._api_client.create_station.assert_called_with( |
573 | artist_token=result.token) | 582 | artist_token=result.token |
583 | ) | ||
574 | 584 | ||
575 | 585 | ||
576 | class TestSongSearchResultItem(TestCase): | 586 | class TestSongSearchResultItem(TestCase): |
@@ -579,30 +589,35 @@ class TestSongSearchResultItem(TestCase): | |||
579 | "artistName": "artist_name_mock", | 589 | "artistName": "artist_name_mock", |
580 | "musicToken": "S0000000", | 590 | "musicToken": "S0000000", |
581 | "songName": "song_name_mock", | 591 | "songName": "song_name_mock", |
582 | "score": 100 | 592 | "score": 100, |
583 | } | 593 | } |
584 | 594 | ||
585 | def setUp(self): | 595 | def setUp(self): |
586 | self.api_client_mock = Mock(spec=APIClient) | 596 | self.api_client_mock = Mock(spec=APIClient) |
587 | self.api_client_mock.default_audio_quality = \ | 597 | self.api_client_mock.default_audio_quality = ( |
588 | APIClient.HIGH_AUDIO_QUALITY | 598 | APIClient.HIGH_AUDIO_QUALITY |
599 | ) | ||
589 | 600 | ||
590 | def test_repr(self): | 601 | def test_repr(self): |
591 | result = sm.SearchResultItem.from_json( | 602 | result = sm.SearchResultItem.from_json( |
592 | self.api_client_mock, self.SONG_JSON_DATA) | 603 | self.api_client_mock, self.SONG_JSON_DATA |
604 | ) | ||
593 | expected = ( | 605 | expected = ( |
594 | "SongSearchResultItem(artist='artist_name_mock', score=100, " | 606 | "SongSearchResultItem(artist='artist_name_mock', score=100, " |
595 | "song_name='song_name_mock', token='S0000000')") | 607 | "song_name='song_name_mock', token='S0000000')" |
608 | ) | ||
596 | self.assertEqual(expected, repr(result)) | 609 | self.assertEqual(expected, repr(result)) |
597 | 610 | ||
598 | def test_create_station(self): | 611 | def test_create_station(self): |
599 | result = sm.SearchResultItem.from_json( | 612 | result = sm.SearchResultItem.from_json( |
600 | self.api_client_mock, self.SONG_JSON_DATA) | 613 | self.api_client_mock, self.SONG_JSON_DATA |
614 | ) | ||
601 | result._api_client.create_station = Mock() | 615 | result._api_client.create_station = Mock() |
602 | 616 | ||
603 | result.create_station() | 617 | result.create_station() |
604 | result._api_client.create_station.assert_called_with( | 618 | result._api_client.create_station.assert_called_with( |
605 | track_token=result.token) | 619 | track_token=result.token |
620 | ) | ||
606 | 621 | ||
607 | 622 | ||
608 | class TestGenreStationSearchResultItem(TestCase): | 623 | class TestGenreStationSearchResultItem(TestCase): |
@@ -610,61 +625,69 @@ class TestGenreStationSearchResultItem(TestCase): | |||
610 | GENRE_JSON_DATA = { | 625 | GENRE_JSON_DATA = { |
611 | "stationName": "station_name_mock", | 626 | "stationName": "station_name_mock", |
612 | "musicToken": "G0000000", | 627 | "musicToken": "G0000000", |
613 | "score": 100 | 628 | "score": 100, |
614 | } | 629 | } |
615 | 630 | ||
616 | def setUp(self): | 631 | def setUp(self): |
617 | self.api_client_mock = Mock(spec=APIClient) | 632 | self.api_client_mock = Mock(spec=APIClient) |
618 | self.api_client_mock.default_audio_quality = \ | 633 | self.api_client_mock.default_audio_quality = ( |
619 | APIClient.HIGH_AUDIO_QUALITY | 634 | APIClient.HIGH_AUDIO_QUALITY |
635 | ) | ||
620 | 636 | ||
621 | def test_repr(self): | 637 | def test_repr(self): |
622 | result = sm.SearchResultItem.from_json( | 638 | result = sm.SearchResultItem.from_json( |
623 | self.api_client_mock, self.GENRE_JSON_DATA) | 639 | self.api_client_mock, self.GENRE_JSON_DATA |
640 | ) | ||
624 | expected = ( | 641 | expected = ( |
625 | "GenreStationSearchResultItem(score=100, " | 642 | "GenreStationSearchResultItem(score=100, " |
626 | "station_name='station_name_mock', token='G0000000')") | 643 | "station_name='station_name_mock', token='G0000000')" |
644 | ) | ||
627 | self.assertEqual(expected, repr(result)) | 645 | self.assertEqual(expected, repr(result)) |
628 | 646 | ||
629 | def test_create_station(self): | 647 | def test_create_station(self): |
630 | result = sm.SearchResultItem.from_json( | 648 | result = sm.SearchResultItem.from_json( |
631 | self.api_client_mock, self.GENRE_JSON_DATA) | 649 | self.api_client_mock, self.GENRE_JSON_DATA |
650 | ) | ||
632 | result._api_client.create_station = Mock() | 651 | result._api_client.create_station = Mock() |
633 | 652 | ||
634 | result.create_station() | 653 | result.create_station() |
635 | result._api_client.create_station.assert_called_with( | 654 | result._api_client.create_station.assert_called_with( |
636 | search_token=result.token) | 655 | search_token=result.token |
656 | ) | ||
637 | 657 | ||
638 | 658 | ||
639 | class TestSearchResult(TestCase): | 659 | class TestSearchResult(TestCase): |
640 | 660 | ||
641 | JSON_DATA = { | 661 | JSON_DATA = { |
642 | 'nearMatchesAvailable': True, | 662 | "nearMatchesAvailable": True, |
643 | 'explanation': '', | 663 | "explanation": "", |
644 | 'songs': [{ | 664 | "songs": [ |
645 | 'artistName': 'song_artist_mock', | 665 | { |
646 | 'musicToken': 'S0000000', | 666 | "artistName": "song_artist_mock", |
647 | 'songName': 'song_name_mock', | 667 | "musicToken": "S0000000", |
648 | 'score': 100 | 668 | "songName": "song_name_mock", |
649 | }], | 669 | "score": 100, |
650 | 'artists': [{ | 670 | } |
651 | 'artistName': 'artist_mock', | 671 | ], |
652 | 'musicToken': 'R000000', | 672 | "artists": [ |
653 | 'likelyMatch': False, | 673 | { |
654 | 'score': 80 | 674 | "artistName": "artist_mock", |
655 | }], | 675 | "musicToken": "R000000", |
656 | 'genreStations': [{ | 676 | "likelyMatch": False, |
657 | 'musicToken': 'G0000', | 677 | "score": 80, |
658 | 'stationName': 'station_mock', | 678 | } |
659 | 'score': 50 | 679 | ], |
660 | }] | 680 | "genreStations": [ |
681 | {"musicToken": "G0000", "stationName": "station_mock", "score": 50} | ||
682 | ], | ||
661 | } | 683 | } |
662 | 684 | ||
663 | def setUp(self): | 685 | def setUp(self): |
664 | api_client_mock = Mock(spec=APIClient) | 686 | api_client_mock = Mock(spec=APIClient) |
665 | api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY | 687 | api_client_mock.default_audio_quality = APIClient.HIGH_AUDIO_QUALITY |
666 | self.result = sm.SearchResult.from_json( | 688 | self.result = sm.SearchResult.from_json( |
667 | api_client_mock, self.JSON_DATA) | 689 | api_client_mock, self.JSON_DATA |
690 | ) | ||
668 | 691 | ||
669 | def test_repr(self): | 692 | def test_repr(self): |
670 | expected = ( | 693 | expected = ( |
@@ -676,7 +699,8 @@ class TestSearchResult(TestCase): | |||
676 | "nearest_matches_available=True, " | 699 | "nearest_matches_available=True, " |
677 | "songs=[SongSearchResultItem(artist='song_artist_mock', " | 700 | "songs=[SongSearchResultItem(artist='song_artist_mock', " |
678 | "score=100, song_name='song_name_mock', " | 701 | "score=100, song_name='song_name_mock', " |
679 | "token='S0000000')])") | 702 | "token='S0000000')])" |
703 | ) | ||
680 | self.assertEqual(expected, repr(self.result)) | 704 | self.assertEqual(expected, repr(self.result)) |
681 | 705 | ||
682 | 706 | ||
@@ -684,9 +708,7 @@ class TestGenreStationList(TestCase): | |||
684 | 708 | ||
685 | TEST_DATA = { | 709 | TEST_DATA = { |
686 | "checksum": "bar", | 710 | "checksum": "bar", |
687 | "categories": [ | 711 | "categories": [{"categoryName": "foo", "stations": []},], |
688 | {"categoryName": "foo", "stations": []}, | ||
689 | ] | ||
690 | } | 712 | } |
691 | 713 | ||
692 | def test_has_changed(self): | 714 | def test_has_changed(self): |
@@ -706,7 +728,8 @@ class TestGenreStation(TestCase): | |||
706 | genre_station = stm.GenreStation.from_json(api_client, self.TEST_DATA) | 728 | genre_station = stm.GenreStation.from_json(api_client, self.TEST_DATA) |
707 | 729 | ||
708 | with self.assertRaisesRegex( | 730 | with self.assertRaisesRegex( |
709 | NotImplementedError, "Genre stations do not have playlists.*"): | 731 | NotImplementedError, "Genre stations do not have playlists.*" |
732 | ): | ||
710 | genre_station.get_playlist() | 733 | genre_station.get_playlist() |
711 | 734 | ||
712 | 735 | ||
@@ -750,7 +773,6 @@ class TestBookmark(TestCase): | |||
750 | 773 | ||
751 | 774 | ||
752 | class TestPandoraType(TestCase): | 775 | class TestPandoraType(TestCase): |
753 | |||
754 | def test_it_can_be_built_from_a_model(self): | 776 | def test_it_can_be_built_from_a_model(self): |
755 | pt = plm.PandoraType.from_model(None, "TR") | 777 | pt = plm.PandoraType.from_model(None, "TR") |
756 | self.assertIs(plm.PandoraType.TRACK, pt) | 778 | self.assertIs(plm.PandoraType.TRACK, pt) |
@@ -765,7 +787,6 @@ class TestPandoraType(TestCase): | |||
765 | 787 | ||
766 | 788 | ||
767 | class TestSyntheticField(TestCase): | 789 | class TestSyntheticField(TestCase): |
768 | |||
769 | def test_interface(self): | 790 | def test_interface(self): |
770 | sf = m.SyntheticField(field="foo") | 791 | sf = m.SyntheticField(field="foo") |
771 | 792 | ||
diff --git a/tests/test_pandora/test_transport.py b/tests/test_pandora/test_transport.py index 851fa06..28ca6b2 100644 --- a/tests/test_pandora/test_transport.py +++ b/tests/test_pandora/test_transport.py | |||
@@ -16,12 +16,12 @@ class SysCallError(Exception): | |||
16 | 16 | ||
17 | 17 | ||
18 | class TestTransport(TestCase): | 18 | class TestTransport(TestCase): |
19 | |||
20 | def test_test_url_should_return_true_if_request_okay(self): | 19 | def test_test_url_should_return_true_if_request_okay(self): |
21 | transport = t.APITransport(Mock()) | 20 | transport = t.APITransport(Mock()) |
22 | transport._http = Mock() | 21 | transport._http = Mock() |
23 | transport._http.head.return_value = Mock( | 22 | transport._http.head.return_value = Mock( |
24 | status_code=requests.codes.not_found) | 23 | status_code=requests.codes.not_found |
24 | ) | ||
25 | 25 | ||
26 | self.assertFalse(transport.test_url("foo")) | 26 | self.assertFalse(transport.test_url("foo")) |
27 | 27 | ||
@@ -34,7 +34,8 @@ class TestTransport(TestCase): | |||
34 | 34 | ||
35 | time.sleep = Mock() | 35 | time.sleep = Mock() |
36 | client.transport._make_http_request = Mock( | 36 | client.transport._make_http_request = Mock( |
37 | side_effect=SysCallError("error_mock")) | 37 | side_effect=SysCallError("error_mock") |
38 | ) | ||
38 | client.transport._start_request = Mock() | 39 | client.transport._start_request = Mock() |
39 | 40 | ||
40 | client("method") | 41 | client("method") |
@@ -48,7 +49,8 @@ class TestTransport(TestCase): | |||
48 | 49 | ||
49 | time.sleep = Mock() | 50 | time.sleep = Mock() |
50 | client.transport._make_http_request = Mock( | 51 | client.transport._make_http_request = Mock( |
51 | side_effect=PandoraException("error_mock")) | 52 | side_effect=PandoraException("error_mock") |
53 | ) | ||
52 | client.transport._start_request = Mock() | 54 | client.transport._start_request = Mock() |
53 | 55 | ||
54 | client("method") | 56 | client("method") |
@@ -62,7 +64,8 @@ class TestTransport(TestCase): | |||
62 | 64 | ||
63 | time.sleep = Mock() | 65 | time.sleep = Mock() |
64 | client.transport._make_http_request = Mock( | 66 | client.transport._make_http_request = Mock( |
65 | side_effect=InvalidAuthToken("error_mock")) | 67 | side_effect=InvalidAuthToken("error_mock") |
68 | ) | ||
66 | client.transport._start_request = Mock() | 69 | client.transport._start_request = Mock() |
67 | 70 | ||
68 | client._authenticate = Mock() | 71 | client._authenticate = Mock() |
@@ -82,11 +85,11 @@ class TestTransport(TestCase): | |||
82 | transport._http.post.return_value = http_result | 85 | transport._http.post.return_value = http_result |
83 | 86 | ||
84 | self.assertEqual( | 87 | self.assertEqual( |
85 | "bar", transport(t.APITransport.NO_ENCRYPT[0], foo="bar")) | 88 | "bar", transport(t.APITransport.NO_ENCRYPT[0], foo="bar") |
89 | ) | ||
86 | 90 | ||
87 | 91 | ||
88 | class TestTransportSetters(TestCase): | 92 | class TestTransportSetters(TestCase): |
89 | |||
90 | def setUp(self): | 93 | def setUp(self): |
91 | self.cryptor = Mock() | 94 | self.cryptor = Mock() |
92 | self.transport = t.APITransport(self.cryptor) | 95 | self.transport = t.APITransport(self.cryptor) |
@@ -94,27 +97,29 @@ class TestTransportSetters(TestCase): | |||
94 | def test_set_partner(self): | 97 | def test_set_partner(self): |
95 | self.cryptor.decrypt_sync_time.return_value = 456 | 98 | self.cryptor.decrypt_sync_time.return_value = 456 |
96 | 99 | ||
97 | self.transport.set_partner({ | 100 | self.transport.set_partner( |
98 | "syncTime": "123", | 101 | { |
99 | "partnerAuthToken": "partner_auth_token", | 102 | "syncTime": "123", |
100 | "partnerId": "partner_id", | 103 | "partnerAuthToken": "partner_auth_token", |
101 | }) | 104 | "partnerId": "partner_id", |
105 | } | ||
106 | ) | ||
102 | 107 | ||
103 | self.cryptor.decrypt_sync_time.assert_called_with("123") | 108 | self.cryptor.decrypt_sync_time.assert_called_with("123") |
104 | self.assertEqual("partner_auth_token", self.transport.auth_token) | 109 | self.assertEqual("partner_auth_token", self.transport.auth_token) |
105 | self.assertEqual("partner_id", self.transport.partner_id) | 110 | self.assertEqual("partner_id", self.transport.partner_id) |
106 | self.assertEqual( | 111 | self.assertEqual( |
107 | "partner_auth_token", self.transport.partner_auth_token) | 112 | "partner_auth_token", self.transport.partner_auth_token |
113 | ) | ||
108 | 114 | ||
109 | self.transport.start_time = 10 | 115 | self.transport.start_time = 10 |
110 | with patch.object(time, "time", return_value=30): | 116 | with patch.object(time, "time", return_value=30): |
111 | self.assertEqual(476, self.transport.sync_time) | 117 | self.assertEqual(476, self.transport.sync_time) |
112 | 118 | ||
113 | def test_set_user(self): | 119 | def test_set_user(self): |
114 | self.transport.set_user({ | 120 | self.transport.set_user( |
115 | "userId": "user", | 121 | {"userId": "user", "userAuthToken": "auth",} |
116 | "userAuthToken": "auth", | 122 | ) |
117 | }) | ||
118 | 123 | ||
119 | self.assertEqual("user", self.transport.user_id) | 124 | self.assertEqual("user", self.transport.user_id) |
120 | self.assertEqual("auth", self.transport.user_auth_token) | 125 | self.assertEqual("auth", self.transport.user_auth_token) |
@@ -126,7 +131,6 @@ class TestTransportSetters(TestCase): | |||
126 | 131 | ||
127 | 132 | ||
128 | class TestDelayExponential(TestCase): | 133 | class TestDelayExponential(TestCase): |
129 | |||
130 | def test_fixed_delay(self): | 134 | def test_fixed_delay(self): |
131 | self.assertEqual(8, t.delay_exponential(2, 2, 3)) | 135 | self.assertEqual(8, t.delay_exponential(2, 2, 3)) |
132 | 136 | ||
@@ -143,7 +147,6 @@ class TestDelayExponential(TestCase): | |||
143 | 147 | ||
144 | 148 | ||
145 | class TestRetries(TestCase): | 149 | class TestRetries(TestCase): |
146 | |||
147 | def test_no_retries_returns_none(self): | 150 | def test_no_retries_returns_none(self): |
148 | @t.retries(0) | 151 | @t.retries(0) |
149 | def foo(): | 152 | def foo(): |
@@ -178,7 +181,6 @@ class TestParseResponse(TestCase): | |||
178 | 181 | ||
179 | 182 | ||
180 | class TestTransportRequestPrep(TestCase): | 183 | class TestTransportRequestPrep(TestCase): |
181 | |||
182 | def setUp(self): | 184 | def setUp(self): |
183 | self.cryptor = Mock() | 185 | self.cryptor = Mock() |
184 | self.transport = t.APITransport(self.cryptor) | 186 | self.transport = t.APITransport(self.cryptor) |
@@ -207,7 +209,8 @@ class TestTransportRequestPrep(TestCase): | |||
207 | 209 | ||
208 | self.transport._http = http | 210 | self.transport._http = http |
209 | res = self.transport._make_http_request( | 211 | res = self.transport._make_http_request( |
210 | "/url", b"data", {"a": None, "b": "c"}) | 212 | "/url", b"data", {"a": None, "b": "c"} |
213 | ) | ||
211 | 214 | ||
212 | http.post.assert_called_with("/url", data=b"data", params={"b": "c"}) | 215 | http.post.assert_called_with("/url", data=b"data", params={"b": "c"}) |
213 | retval.raise_for_status.assert_called_with() | 216 | retval.raise_for_status.assert_called_with() |
@@ -237,7 +240,8 @@ class TestTransportRequestPrep(TestCase): | |||
237 | 240 | ||
238 | with patch.object(time, "time", return_value=20): | 241 | with patch.object(time, "time", return_value=20): |
239 | val = self.transport._build_data( | 242 | val = self.transport._build_data( |
240 | t.APITransport.NO_ENCRYPT[0], {"a": "b", "c": None}) | 243 | t.APITransport.NO_ENCRYPT[0], {"a": "b", "c": None} |
244 | ) | ||
241 | 245 | ||
242 | val = json.loads(val) | 246 | val = json.loads(val) |
243 | self.assertEqual("b", val["a"]) | 247 | self.assertEqual("b", val["a"]) |
@@ -247,7 +251,6 @@ class TestTransportRequestPrep(TestCase): | |||
247 | 251 | ||
248 | # All Cryptor implementations must pass these test cases unmodified | 252 | # All Cryptor implementations must pass these test cases unmodified |
249 | class CommonCryptorTestCases: | 253 | class CommonCryptorTestCases: |
250 | |||
251 | def test_decrypt_invalid_padding(self): | 254 | def test_decrypt_invalid_padding(self): |
252 | with self.assertRaises(ValueError): | 255 | with self.assertRaises(ValueError): |
253 | data = b"12345678\x00" | 256 | data = b"12345678\x00" |
@@ -267,7 +270,6 @@ class CommonCryptorTestCases: | |||
267 | 270 | ||
268 | 271 | ||
269 | class TestPurePythonBlowfishCryptor(TestCase, CommonCryptorTestCases): | 272 | class TestPurePythonBlowfishCryptor(TestCase, CommonCryptorTestCases): |
270 | |||
271 | def setUp(self): | 273 | def setUp(self): |
272 | # Ugh... blowfish can't even be *imported* in python2 | 274 | # Ugh... blowfish can't even be *imported* in python2 |
273 | if not t.blowfish: | 275 | if not t.blowfish: |
@@ -288,7 +290,6 @@ class TestEncryptor(TestCase): | |||
288 | ENCODED_TIME = "31353037343131313539" | 290 | ENCODED_TIME = "31353037343131313539" |
289 | 291 | ||
290 | class NoopCrypto: | 292 | class NoopCrypto: |
291 | |||
292 | def __init__(self, key): | 293 | def __init__(self, key): |
293 | pass | 294 | pass |
294 | 295 | ||
@@ -303,14 +304,17 @@ class TestEncryptor(TestCase): | |||
303 | 304 | ||
304 | def test_decrypt(self): | 305 | def test_decrypt(self): |
305 | self.assertEqual( | 306 | self.assertEqual( |
306 | {"foo": "bar"}, self.cryptor.decrypt(self.ENCODED_JSON)) | 307 | {"foo": "bar"}, self.cryptor.decrypt(self.ENCODED_JSON) |
308 | ) | ||
307 | 309 | ||
308 | def test_encrypt(self): | 310 | def test_encrypt(self): |
309 | self.assertEqual( | 311 | self.assertEqual( |
310 | self.ENCODED_JSON.encode("ascii"), | 312 | self.ENCODED_JSON.encode("ascii"), |
311 | self.cryptor.encrypt(self.UNENCODED_JSON)) | 313 | self.cryptor.encrypt(self.UNENCODED_JSON), |
314 | ) | ||
312 | 315 | ||
313 | def test_decrypt_sync_time(self): | 316 | def test_decrypt_sync_time(self): |
314 | self.assertEqual( | 317 | self.assertEqual( |
315 | self.EXPECTED_TIME, | 318 | self.EXPECTED_TIME, |
316 | self.cryptor.decrypt_sync_time(self.ENCODED_TIME)) | 319 | self.cryptor.decrypt_sync_time(self.ENCODED_TIME), |
320 | ) | ||