mirror of
https://github.com/c0de-archive/spotipy.git
synced 2024-11-05 07:27:47 +00:00
Merge branch 'master' into support_changing_playlist_details
Conflicts: spotipy/client.py
This commit is contained in:
commit
931abce4d7
@ -252,6 +252,7 @@ API Reference
|
|||||||
.. automodule:: spotipy.client
|
.. automodule:: spotipy.client
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
|
:special-members: __init__
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
:mod:`oauth2` Module
|
:mod:`oauth2` Module
|
||||||
@ -260,6 +261,7 @@ API Reference
|
|||||||
.. automodule:: spotipy.oauth2
|
.. automodule:: spotipy.oauth2
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
|
:special-members: __init__
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
:mod:`util` Module
|
:mod:`util` Module
|
||||||
@ -268,6 +270,7 @@ API Reference
|
|||||||
.. automodule:: spotipy.util
|
.. automodule:: spotipy.util
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
|
:special-members: __init__
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ class Spotify(object):
|
|||||||
return self._get("users/%s/playlists/%s" % (user, plid), fields=fields)
|
return self._get("users/%s/playlists/%s" % (user, plid), fields=fields)
|
||||||
|
|
||||||
def user_playlist_tracks(self, user, playlist_id=None, fields=None,
|
def user_playlist_tracks(self, user, playlist_id=None, fields=None,
|
||||||
limit=100, offset=0):
|
limit=100, offset=0, market=None):
|
||||||
''' Get full details of the tracks of a playlist owned by a user.
|
''' Get full details of the tracks of a playlist owned by a user.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@ -364,10 +364,12 @@ class Spotify(object):
|
|||||||
- fields - which fields to return
|
- fields - which fields to return
|
||||||
- limit - the maximum number of tracks to return
|
- limit - the maximum number of tracks to return
|
||||||
- offset - the index of the first track to return
|
- offset - the index of the first track to return
|
||||||
|
- market - an ISO 3166-1 alpha-2 country code.
|
||||||
'''
|
'''
|
||||||
plid = self._get_id('playlist', playlist_id)
|
plid = self._get_id('playlist', playlist_id)
|
||||||
return self._get("users/%s/playlists/%s/tracks" % (user, plid),
|
return self._get("users/%s/playlists/%s/tracks" % (user, plid),
|
||||||
limit=limit, offset=offset, fields=fields)
|
limit=limit, offset=offset, fields=fields,
|
||||||
|
market=market)
|
||||||
|
|
||||||
def user_playlist_create(self, user, name, public=True):
|
def user_playlist_create(self, user, name, public=True):
|
||||||
''' Creates a playlist for a user
|
''' Creates a playlist for a user
|
||||||
|
118
tests/test_oauth.py
Normal file
118
tests/test_oauth.py
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
from spotipy.oauth2 import SpotifyOAuth
|
||||||
|
import json
|
||||||
|
import io
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
try:
|
||||||
|
import unittest.mock as mock
|
||||||
|
except ImportError:
|
||||||
|
import mock
|
||||||
|
|
||||||
|
patch = mock.patch
|
||||||
|
DEFAULT = mock.DEFAULT
|
||||||
|
|
||||||
|
|
||||||
|
def _make_fake_token(expires_at, expires_in, scope):
|
||||||
|
return dict(
|
||||||
|
expires_at=expires_at,
|
||||||
|
expires_in=expires_in,
|
||||||
|
scope=scope,
|
||||||
|
token_type="Bearer",
|
||||||
|
refresh_token="REFRESH",
|
||||||
|
access_token="ACCESS")
|
||||||
|
|
||||||
|
|
||||||
|
def _fake_file():
|
||||||
|
return mock.Mock(spec_set=io.FileIO)
|
||||||
|
|
||||||
|
|
||||||
|
def _token_file(token):
|
||||||
|
fi = _fake_file()
|
||||||
|
fi.read.return_value = token
|
||||||
|
return fi
|
||||||
|
|
||||||
|
|
||||||
|
def _make_oauth(*args, **kwargs):
|
||||||
|
return SpotifyOAuth("CLID", "CLISEC", "REDIR", "STATE", *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class OAuthCacheTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@patch.multiple(SpotifyOAuth,
|
||||||
|
_is_token_expired=DEFAULT, _refresh_access_token=DEFAULT)
|
||||||
|
@patch('spotipy.oauth2.open', create=True)
|
||||||
|
def test_gets_from_cache_path(self, opener,
|
||||||
|
_is_token_expired, _refresh_access_token):
|
||||||
|
scope = "playlist-modify-private"
|
||||||
|
path = ".cache-username"
|
||||||
|
tok = _make_fake_token(1, 1, scope)
|
||||||
|
|
||||||
|
opener.return_value = _token_file(json.dumps(tok, ensure_ascii=False))
|
||||||
|
_is_token_expired.return_value = False
|
||||||
|
|
||||||
|
spot = _make_oauth(scope, path)
|
||||||
|
cached_tok = spot.get_cached_token()
|
||||||
|
|
||||||
|
opener.assert_called_with(path)
|
||||||
|
self.assertIsNotNone(cached_tok)
|
||||||
|
self.assertEqual(_refresh_access_token.call_count, 0)
|
||||||
|
|
||||||
|
@patch.multiple(SpotifyOAuth,
|
||||||
|
_is_token_expired=DEFAULT, _refresh_access_token=DEFAULT)
|
||||||
|
@patch('spotipy.oauth2.open', create=True)
|
||||||
|
def test_expired_token_refreshes(self, opener,
|
||||||
|
_is_token_expired, _refresh_access_token):
|
||||||
|
scope = "playlist-modify-private"
|
||||||
|
path = ".cache-username"
|
||||||
|
expired_tok = _make_fake_token(0, None, scope)
|
||||||
|
fresh_tok = _make_fake_token(1, 1, scope)
|
||||||
|
|
||||||
|
token_file = _token_file(json.dumps(expired_tok, ensure_ascii=False))
|
||||||
|
opener.return_value = token_file
|
||||||
|
_refresh_access_token.return_value = fresh_tok
|
||||||
|
|
||||||
|
spot = _make_oauth(scope, path)
|
||||||
|
spot.get_cached_token()
|
||||||
|
|
||||||
|
_is_token_expired.assert_called_with(expired_tok)
|
||||||
|
_refresh_access_token.assert_called_with(expired_tok['refresh_token'])
|
||||||
|
opener.assert_any_call(path)
|
||||||
|
|
||||||
|
@patch.multiple(SpotifyOAuth,
|
||||||
|
_is_token_expired=DEFAULT, _refresh_access_token=DEFAULT)
|
||||||
|
@patch('spotipy.oauth2.open', create=True)
|
||||||
|
def test_badly_scoped_token_bails(self, opener,
|
||||||
|
_is_token_expired, _refresh_access_token):
|
||||||
|
token_scope = "playlist-modify-public"
|
||||||
|
requested_scope = "playlist-modify-private"
|
||||||
|
path = ".cache-username"
|
||||||
|
tok = _make_fake_token(1, 1, token_scope)
|
||||||
|
|
||||||
|
opener.return_value = _token_file(json.dumps(tok, ensure_ascii=False))
|
||||||
|
_is_token_expired.return_value = False
|
||||||
|
|
||||||
|
spot = _make_oauth(requested_scope, path)
|
||||||
|
cached_tok = spot.get_cached_token()
|
||||||
|
|
||||||
|
opener.assert_called_with(path)
|
||||||
|
self.assertIsNone(cached_tok)
|
||||||
|
self.assertEqual(_refresh_access_token.call_count, 0)
|
||||||
|
|
||||||
|
@patch('spotipy.oauth2.open', create=True)
|
||||||
|
def test_saves_to_cache_path(self, opener):
|
||||||
|
scope = "playlist-modify-private"
|
||||||
|
path = ".cache-username"
|
||||||
|
tok = _make_fake_token(1, 1, scope)
|
||||||
|
|
||||||
|
fi = _fake_file()
|
||||||
|
opener.return_value = fi
|
||||||
|
|
||||||
|
spot = SpotifyOAuth("CLID", "CLISEC", "REDIR", "STATE", scope, path)
|
||||||
|
spot._save_token_info(tok)
|
||||||
|
|
||||||
|
opener.assert_called_with(path, 'w')
|
||||||
|
self.assertTrue(fi.write.called)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user