diff --git a/server/djrandom/frontend/__init__.py b/server/djrandom/frontend/__init__.py index 996971513c13f67d97acb56fc5a13c62eb42f853..b7f0e3bc8013e87a6b89de4bede4025f4475e717 100644 --- a/server/djrandom/frontend/__init__.py +++ b/server/djrandom/frontend/__init__.py @@ -21,7 +21,9 @@ def shutdown_dbsession(exception=None): def require_auth(f): @wraps(f) def check_auth_wrapper(*args, **kwargs): - if 'userid' in session: + if app.config.get('TESTING'): + g.userid = 'testuser' + elif 'userid' in session: g.userid = session['userid'] elif 'X-Key' in request.headers: user = User.find_with_api_key( diff --git a/server/djrandom/frontend/api_views.py b/server/djrandom/frontend/api_views.py index 7b19685aacda620f0357838abf76f1a4203cbdb1..f9aac546438db65d3800087ce58ae9c6f965ea89 100644 --- a/server/djrandom/frontend/api_views.py +++ b/server/djrandom/frontend/api_views.py @@ -20,6 +20,7 @@ def all_artists_json(): @app.route('/json/albums/<artist>') @require_auth def artist_albums_json(artist): + print 'artist: %s' % repr(artist) albums = [x[0] for x in Session.query(distinct(MP3.album)).filter_by(artist=artist)] return jsonify(albums=albums) @@ -28,6 +29,7 @@ def artist_albums_json(artist): @app.route('/json/album/<artist>/<album>') @require_auth def album_songs_json(artist, album): + print 'artist, album: %s / %s' % (repr(artist), repr(album)) songs = [x.to_dict() for x in MP3.get_songs_for_album(artist, album)] return jsonify(songs=songs) @@ -125,7 +127,6 @@ def playlist_info_json(uuid): @app.route('/json/playlist/by_title/<uuid>/<title>') @require_auth def playlist_info_by_title_json(uuid, title): - title = urllib.unquote(title) playlist = Playlist.get_by_title(uuid, title) if not playlist: abort(404) diff --git a/server/djrandom/model/mp3.py b/server/djrandom/model/mp3.py index 5cc3b3405ca0dc10c11ac9894cac314b53907ea7..12b9c631d2a99323141937a0c044e1909feba6af 100644 --- a/server/djrandom/model/mp3.py +++ b/server/djrandom/model/mp3.py @@ -39,7 +39,7 @@ class MP3(Base): artist = Column(Unicode(256)) title = Column(Unicode(256)) album = Column(Unicode(256)) - track_num = Column(Integer(3)) + track_num = Column(Integer()) genre = Column(Unicode(64)) uploaded_at = Column(DateTime()) play_count = Column(Integer(), default=0) diff --git a/server/djrandom/test/__init__.py b/server/djrandom/test/__init__.py index 3acf1bda51efc2557647dbbd902084984a3aa923..b53d6a97faa953c417e8e1374f53b8a0af43c222 100644 --- a/server/djrandom/test/__init__.py +++ b/server/djrandom/test/__init__.py @@ -15,11 +15,14 @@ class DbTestCase(mox.MoxTestBase): self.mox.StubOutWithMock(indexer.Indexer, 'add_mp3') self.mox.StubOutWithMock(indexer.Indexer, 'del_mp3') self.mox.StubOutWithMock(indexer.Indexer, 'commit') - database.init_db('sqlite://', 'http://solr/') + self.engine = database.init_db( + 'sqlite:///%s' % os.path.join(self.tmpdir, 'data.db'), + 'http://solr/') def tearDown(self): - database.Session.remove() mox.MoxTestBase.tearDown(self) + database.Session.remove() + database.Base.metadata.drop_all(self.engine) shutil.rmtree(self.tmpdir) @@ -46,12 +49,17 @@ class SolrTestCase(mox.MoxTestBase): class WsgiTestCase(DbTestCase): FLASK_APP = None - DATA = [] def setUp(self): DbTestCase.setUp(self) - for item in self.DATA: - database.Session.add(item) - database.Session.commit() self.FLASK_APP.config['TESTING'] = True self.app = self.FLASK_APP.test_client() + + def _load_data(self, data): + sess = database.Session() + for item in data: + print 'adding item', str(item) + sess.add(item) + sess.commit() + + diff --git a/server/djrandom/test/test_frontend_api.py b/server/djrandom/test/test_frontend_api.py new file mode 100644 index 0000000000000000000000000000000000000000..6b1e322c9f948c261205f4286832b0fea829c4c2 --- /dev/null +++ b/server/djrandom/test/test_frontend_api.py @@ -0,0 +1,170 @@ +import urllib +import json +from datetime import datetime +from djrandom.test import WsgiTestCase +from djrandom import frontend +from djrandom.database import Session +from djrandom.frontend import svcs +from djrandom.model.mp3 import MP3, PlayLog +from djrandom.model.playlist import Playlist + + +class FrontendApiTest(WsgiTestCase): + + FLASK_APP = frontend.app + + + def setUp(self): + WsgiTestCase.setUp(self) + self.searcher = svcs['searcher'] = self.mox.CreateMockAnything() + self.markov = svcs['markov'] = self.mox.CreateMockAnything() + + self._load_data( + [MP3(sha1='1', + artist=u'artist 1', + album=u'album', + title=u'song 1', + path='/root/1', + play_count=3, + state=MP3.READY), + MP3(sha1='2', + artist=u'artist 1', + album=u'album 2', + title=u'song 2', + path='/root/2', + state=MP3.READY), + MP3(sha1='3', + artist=u'artist 2', + album=u'album', + title=u'song 3', + path='/root/3', + state=MP3.READY), + MP3(sha1='4', + path='/root/4', + state=MP3.INCOMING), + Playlist(uuid='1234', + userid='testuser', + play_count=1, + contents='1,2'), + Playlist(uuid='2345', + title=u'my playlist', + userid='testuser', + contents='2,3') + ]) + + def _jsonget(self, url, expected_status=200): + rv = self.app.get(url) + self.assertEquals(expected_status, rv.status_code) + return json.loads(rv.data) + + def _jsonpost(self, url, data, expected_status=200): + rv = self.app.post(url, data=data) + self.assertEquals(expected_status, rv.status_code) + return json.loads(rv.data) + + def test_all_artists_json(self): + rv = self._jsonget('/json/artists') + self.assertTrue('artists' in rv) + self.assertEquals([u'artist 1', u'artist 2'], + sorted(rv['artists'])) + + def test_artist_albums_json(self): + rv = self._jsonget('/json/albums/artist%201') + self.assertTrue('albums' in rv) + self.assertEquals(set([u'album', u'album 2']), + set(rv['albums'])) + + def test_album_songs_json(self): + rv = self._jsonget('/json/album/artist%201/album%202') + self.assertTrue('songs' in rv) + mp3 = MP3.query.get('2') + self.assertEquals([mp3.to_dict()], rv['songs']) + + def test_song_info_json(self): + rv = self._jsonget('/json/song/1') + mp3 = MP3.query.get('1') + self.assertEquals(mp3.to_dict(), rv) + + def test_json_search(self): + self.searcher.search('my query', n=100).AndReturn( + [(1.0, '1'), (0.5, '2')]) + self.mox.ReplayAll() + + rv = self._jsonget('/json/search?q=my+query') + self.assertTrue('results' in rv) + self.assertEquals( + [{'score': 1, 'sha1': '1'}, + {'score': 0.5, 'sha1': '2'}], + rv['results']) + + def test_more_like_these_json(self): + self.searcher.more_like_these(['1', '2'], 5).AndReturn( + ['3']) + self.mox.ReplayAll() + + rv = self._jsonpost('/json/morelikethese', + {'h': '1,2', 'n': '5'}) + self.assertTrue('results' in rv) + self.assertEquals(['3'], rv['results']) + + def test_most_played_json(self): + plog = PlayLog(sha1='1', userid='testuser', stamp=datetime.now()) + Session.add(plog) + Session.commit() + + rv = self._jsonget('/json/most_played') + self.assertTrue('results' in rv) + self.assertTrue(len(rv['results']) > 0) + self.assertEquals( + {'sha1': '1', 'count': 1}, + rv['results'][0]) + + #def test_never_played_json(self): + # rv = self._jsonget('/json/never_played') + # self.assertTrue('results' in rv) + # self.assertTrue(len(rv['results']) > 0) + # self.assertEquals( + # set(['2', '3']), + # set(rv['results'])) + + def test_markov_json(self): + self.markov.generate_sequence(['2', '3'], 2, 2).AndReturn( + ['1', '2']) + self.mox.ReplayAll() + + rv = self._jsonpost('/json/markov', + {'h': '1,2,3', 'n': '2'}) + self.assertTrue('results' in rv) + self.assertEquals(['1', '2'], rv['results']) + + def test_play_callback(self): + rv = self._jsonpost('/json/playing', + {'cur': '3', + 'prev': '1,2'}) + self.assertEquals({'status': True}, rv) + + plog = PlayLog.query.first() + self.assertEquals('3', plog.sha1) + self.assertEquals('testuser', plog.userid) + self.assertEquals('1,2', plog.prev) + + mp3 = MP3.query.get('3') + self.assertEquals(1, mp3.play_count) + + def test_playlist_info_json(self): + rv = self._jsonget('/json/playlist/get/1234') + pl = Playlist.query.get('1234') + self.assertEquals(pl.to_dict(), rv) + + def test_playlist_info_by_title_json(self): + rv = self._jsonget('/json/playlist/by_title/testuser/my%20playlist') + pl = Playlist.query.get('2345') + self.assertEquals(pl.to_dict(), rv) + + def test_playlist_list_by_uuid_json(self): + rv = self._jsonget('/json/playlist/list/testuser') + self.assertTrue('results' in rv) + self.assertEquals(2, len(rv['results'])) + self.assertEquals( + set(['1234', '2345']), + set([x['uuid'] for x in rv['results']])) diff --git a/server/djrandom/test/test_receiver.py b/server/djrandom/test/test_receiver.py index b5b346421a283c9f057243afd4150e6980024884..d45a1c7a96183a2cac14492824d72ea03d89b459 100644 --- a/server/djrandom/test/test_receiver.py +++ b/server/djrandom/test/test_receiver.py @@ -9,11 +9,10 @@ class ReceiverTest(WsgiTestCase): FLASK_APP = receiver.app - DATA = [MP3(sha1='1234')] - def setUp(self): WsgiTestCase.setUp(self) receiver.storage_root = self.tmpdir + self._load_data([MP3(sha1='1234')]) def test_check_existing(self): rv = self.app.get('/check/1234')