class PlayerTestCase(LoggedInUserTestCase): """A test case for the player (player.py) functions, mostly the endpoints just to make sure they work.""" @setup def _queue_tracks(self): r = random.Random() sample_tracks_copy = sample_tracks r.shuffle(sample_tracks_copy) for track in sample_tracks_copy[:5]: response = self.app.post('/queue/add', data = {'spotify_uri': track['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' self.added_tracks = sample_tracks_copy[:5] self.mpd = MockMPDClient() def test_player_endpoint(self): response = self.assert_endpoint_works('/player') assert 'Account settings' in response.data def test_player_status(self): response = self.assert_endpoint_works('/player/status/poll') response_data = json.loads(response.data) assert response.status_code == 200 for track in self.added_tracks: assert track['file'] in [t['spotify_url'] for t in response_data['user_queue']] assert track['file'] in [t['spotify_url'] for t in response_data['global_queue']] pl_update = response_data['last_global_playlist_update'] response = self.app.get('/player/status/poll?current=%s' % str(float(pl_update)+1)) response_data = json.loads(response.data) assert response.status_code == 200 assert 'user_queue' not in response_data assert 'global_queue' not in response_data self.mpd.addid('spotify:track:6LDYVzxjDSAO92UZ5veM3u') response = self.app.get('/player/status/poll?current=%s' % pl_update) response_data = json.loads(response.data) assert response.status_code == 200 assert 'user_queue' in response_data assert 'global_queue' in response_data
def wrapped(*args, **kwargs): if not app.config['TESTING']: mpd_client = MPDClient() else: from testing.mocks.mock_mpd_client import MockMPDClient mpd_client = MockMPDClient() try: mpd_client.connect(host=app.config['MPD_SERVER_HOSTNAME'], port=app.config['MPD_SERVER_PORT']) except: # Do something sensible when you can't connect to the MPD server, like pass None in for mpd_client # maybe eventually just forward to the configuration page/no connection page mpd_client = None app.logger.warning( "Could not connect to MPD server on host %r, port %r" % (app.config['MPD_SERVER_HOSTNAME'], app.config['MPD_SERVER_PORT'])) try: return jsonify(status="error", message="MPD credentials incorrect") except: return "Crap.", 500 else: return_value = f(mpd_client, *args, **kwargs) if mpd_client is not None: mpd_client.disconnect() return return_value
def _queue_tracks(self): r = random.Random() sample_tracks_copy = sample_tracks r.shuffle(sample_tracks_copy) for track in sample_tracks_copy[:5]: response = self.app.post('/queue/add', data = {'spotify_uri': track['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' self.added_tracks = sample_tracks_copy[:5] self.mpd = MockMPDClient()
def _with_mpd_client(self): self.mpd = MockMPDClient()
class QueueTestCase(LoggedInUserTestCase): """Tests all of the functions pertaining to queue management (queue.py).""" @setup def _with_mpd_client(self): self.mpd = MockMPDClient() @teardown def _without_mpd_client(self): self.mpd.stop_idle() def test_queue_add(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert response_data['file'] == track_to_add['file'] assert any([ track['spotify_url'] == track_to_add['file'] for track in response_data['queue'] ]) assert track_to_add in self.mpd.playlistinfo() def test_queue_add_bad_track(self): track_to_add = 'ERk;lw343##' response = self.app.post('/queue/add', data={'spotify_uri': track_to_add}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'invalid' in response_data['message'] def test_queue_add_no_track(self): response = self.app.post('/queue/add', data={}) assert response.status_code != 200 def test_queue_remove(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [ track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file'] ][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data={'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert track_to_add not in self.mpd.playlistinfo() def test_queue_remove_bad_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [ track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file'] ][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data={'track_id': 'kjffdgfsfsasfdghhjkghf'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Not a valid track ID!' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_nonexistent_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [ track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file'] ][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data={'track_id': '4354565745353534'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Could not find track with id' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_unowned_track(self): other_user = self.create_test_user() other_user_client = app.test_client() # Log the 'other' user in other_user_client.post('/login', data={ 'username': other_user.username, 'password': other_user.username }, follow_redirects=True) track_to_add = self.random_sample_track() response = other_user_client.post( '/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [ track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file'] ][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data={'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'You are not authorized' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_reorder_tracks(self): # Add a bunch of tracks. tracks_to_add = [ track for track in sample_tracks if track['album'] == 'Some Are Lakes' ] for track_to_add in tracks_to_add: response = self.app.post( '/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' r = random.Random() pqe_ids = [track['id'] for track in response_data['queue']] priorities = range(1, len(pqe_ids) + 1) r.shuffle(pqe_ids) r.shuffle(priorities) new_priorities = dict( (pqe_id, priority) for (pqe_id, priority) in zip(pqe_ids, priorities)) response = self.app.post('/queue/reorder', data=new_priorities) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' def test_user_queue_list(self): r = random.Random() # Add a bunch of tracks. tracks_to_add = [ track for track in sample_tracks if track['album'] == 'Set Yourself On Fire' ] r.shuffle(tracks_to_add) for track_to_add in tracks_to_add: response = self.app.post( '/queue/add', data={'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' response = self.assert_endpoint_works('/queue/list') response_data = json.loads(response.data) assert response_data['status'] == 'ok' for track in tracks_to_add: assert any([ response_track['spotify_url'] == track['file'] for response_track in response_data['result'] ]) def test_track_from_spotify_url(self): track = track_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track is not None assert track.title == 'Elevator Love Letter' assert track.artist == 'Stars' assert track.album == 'Heart' assert track.length == 243.147 assert track.date == '2003' or track.date == '2003-01-01' assert track.spotify_url == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_info_from_spotify_url(self): track_info = track_info_from_spotify_url( 'spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track_info is not None assert all(k in track_info for k in ('title', 'artist', 'album', 'spotify_url', 'date', 'length')) assert track_info['title'] == 'Elevator Love Letter' assert track_info['artist'] == 'Stars' assert track_info['album'] == 'Heart' assert track_info['length'] == 243.147 assert track_info['date'] == '2003' or track.date == '2003-01-01' assert track_info[ 'spotify_url'] == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_from_mpd_search_results(self): track = track_from_mpd_search_results( 'spotify:track:6LDYVzxjDSAO92UZ5veM3u', self.mpd) assert track is not None assert track.title == 'Elevator Love Letter' assert track.artist == 'Stars' assert track.album == 'Heart' assert track.length == 243.147 assert track.date == '2003-01-01' or track.date == '2003' assert track.spotify_url == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_info_from_mpd_search_results(self): track_info = track_info_from_spotify_url( 'spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track_info is not None assert all(k in track_info for k in ('title', 'artist', 'album', 'spotify_url', 'date', 'length')) assert track_info['title'] == 'Elevator Love Letter' assert track_info['artist'] == 'Stars' assert track_info['album'] == 'Heart' assert track_info['length'] == 243.147 assert track_info['date'] == '2003' or track.date == '2003-01-01' assert track_info[ 'spotify_url'] == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_nxtrack_purge(self): self.mpd.clear() track = track_from_spotify_url("spotify:track:6LDYVzxjDSAO92UZ5veM3u") self.db.session.add(PlayQueueEntry(track=track, mpd_id=0)) self.db.session.commit() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 def test_add_anon_track(self): self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) self.mpd.addid("spotify:track:6LDYVzxjDSAO92UZ5veM3u") _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 1 assert len(PlayQueueEntry.query.all()) == 1 db_entry = PlayQueueEntry.query.first() assert db_entry.track.spotify_url == "spotify:track:6LDYVzxjDSAO92UZ5veM3u" assert db_entry.user is None @suite('transient') def test_round_robin_selection(self): set_config_value('SELECTION_SCHEME', 'ROUND_ROBIN') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 # Simulate 5 users queueing up 10 tracks each in serial users = [] for i in range(1, 4): user = self.create_test_user() users.append(user) for ii in range(1, 4): track = self.random_sample_track() add_track_from_spotify_url(self.mpd, track['file'], user.id) first_user = users[0] users = sorted(users, key=lambda x: x.username) users = cycle(users) users = dropwhile(lambda x: x != first_user, users) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) mpd_playlist = self.mpd.playlistinfo() db_tracks = PlayQueueEntry.query.order_by( PlayQueueEntry.playback_priority.asc()).all() for (pqe, mpd_track) in zip(db_tracks, mpd_playlist): assert pqe.playback_priority == mpd_track['pos'] for (pqe, prop_user) in zip(db_tracks, users): assert pqe.user == prop_user @suite('transient') def test_fcfs_selection(self): set_config_value('SELECTION_SCHEME', 'FCFS') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 # Simulate 5 users queueing up 10 tracks each in serial users = [] for i in range(1, 4): user = self.create_test_user() for i in range(1, 4): users.append(user) track = self.random_sample_track() add_track_from_spotify_url(self.mpd, track['file'], user.id) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) mpd_playlist = self.mpd.playlistinfo() db_tracks = PlayQueueEntry.query.order_by( PlayQueueEntry.playback_priority.asc()).all() for (pqe, mpd_track) in zip(db_tracks, mpd_playlist): assert pqe.playback_priority == mpd_track['pos'] for (pqe, prop_user) in zip(db_tracks, users): assert pqe.user == prop_user @suite('transient') def test_fcfs_with_voting_selection(self): set_config_value('SELECTION_SCHEME', 'FCFS_VOTE') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 user1 = self.create_test_user() user2 = self.create_test_user() tracks = [] for i in range(1, 11): st = self.random_sample_track() tracks.append( add_track_from_spotify_url(self.mpd, st['file'], user1.id)) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) for mpd_track, expected_track in zip(self.mpd.playlistinfo(), tracks): assert mpd_track['file'] == expected_track.spotify_url r = random.Random() pqes = PlayQueueEntry.query.order_by(PlayQueueEntry.time_added).all() up_voted = [] down_voted = [] for i in range(1, 4): pqe = r.choice(pqes) pqes.remove(pqe) up_voted.append(pqe) vote = Vote(user=user2, pqe=pqe, direction=1) db.session.add(vote) for i in range(1, 4): pqe = r.choice(pqes) pqes.remove(pqe) down_voted.append(pqe) vote = Vote(user=user2, pqe=pqe, direction=-1) db.session.add(vote) db.session.commit() up_voted = sorted(up_voted, key=lambda x: x.time_added) down_voted = sorted(down_voted, key=lambda x: x.time_added) expected_order = up_voted + pqes + down_voted # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) for mpd_track, expected_track in zip(self.mpd.playlistinfo(), expected_order): assert mpd_track['file'] == expected_track.track.spotify_url def random_sample_track(self): r = random.Random() return r.choice(sample_tracks)
def setup(self): # Make sure the user that is testing has administrative privileges give_user_privilege(self.user, "ADMIN_INTERFACE") self.mpd = MockMPDClient()
class QueueTestCase(LoggedInUserTestCase): """Tests all of the functions pertaining to queue management (queue.py).""" @setup def _with_mpd_client(self): self.mpd = MockMPDClient() @teardown def _without_mpd_client(self): self.mpd.stop_idle() def test_queue_add(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert response_data['file'] == track_to_add['file'] assert any([track['spotify_url'] == track_to_add['file'] for track in response_data['queue']]) assert track_to_add in self.mpd.playlistinfo() def test_queue_add_bad_track(self): track_to_add = 'ERk;lw343##' response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'invalid' in response_data['message'] def test_queue_add_no_track(self): response = self.app.post('/queue/add', data = {}) assert response.status_code != 200 def test_queue_remove(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert track_to_add not in self.mpd.playlistinfo() def test_queue_remove_bad_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': 'kjffdgfsfsasfdghhjkghf'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Not a valid track ID!' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_nonexistent_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': '4354565745353534'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Could not find track with id' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_unowned_track(self): other_user = self.create_test_user() other_user_client = app.test_client() # Log the 'other' user in other_user_client.post('/login', data = {'username': other_user.username, 'password': other_user.username}, follow_redirects = True) track_to_add = self.random_sample_track() response = other_user_client.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'You are not authorized' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_reorder_tracks(self): # Add a bunch of tracks. tracks_to_add = [track for track in sample_tracks if track['album'] == 'Some Are Lakes'] for track_to_add in tracks_to_add: response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' r = random.Random() pqe_ids = [track['id'] for track in response_data['queue']] priorities = range(1, len(pqe_ids) + 1) r.shuffle(pqe_ids) r.shuffle(priorities) new_priorities = dict( (pqe_id, priority) for (pqe_id, priority) in zip(pqe_ids, priorities) ) response = self.app.post('/queue/reorder', data = new_priorities) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' def test_user_queue_list(self): r = random.Random() # Add a bunch of tracks. tracks_to_add = [track for track in sample_tracks if track['album'] == 'Set Yourself On Fire'] r.shuffle(tracks_to_add) for track_to_add in tracks_to_add: response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' response = self.assert_endpoint_works('/queue/list') response_data = json.loads(response.data) assert response_data['status'] == 'ok' for track in tracks_to_add: assert any([response_track['spotify_url'] == track['file'] for response_track in response_data['result']]) def test_track_from_spotify_url(self): track = track_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track is not None assert track.title == 'Elevator Love Letter' assert track.artist == 'Stars' assert track.album == 'Heart' assert track.length == 243.147 assert track.date == '2003' or track.date == '2003-01-01' assert track.spotify_url == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_info_from_spotify_url(self): track_info = track_info_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track_info is not None assert all(k in track_info for k in ('title', 'artist', 'album', 'spotify_url', 'date', 'length')) assert track_info['title'] == 'Elevator Love Letter' assert track_info['artist'] == 'Stars' assert track_info['album'] == 'Heart' assert track_info['length'] == 243.147 assert track_info['date'] == '2003' or track.date == '2003-01-01' assert track_info['spotify_url'] == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_from_mpd_search_results(self): track = track_from_mpd_search_results('spotify:track:6LDYVzxjDSAO92UZ5veM3u', self.mpd) assert track is not None assert track.title == 'Elevator Love Letter' assert track.artist == 'Stars' assert track.album == 'Heart' assert track.length == 243.147 assert track.date == '2003-01-01' or track.date == '2003' assert track.spotify_url == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_info_from_mpd_search_results(self): track_info = track_info_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track_info is not None assert all(k in track_info for k in ('title', 'artist', 'album', 'spotify_url', 'date', 'length')) assert track_info['title'] == 'Elevator Love Letter' assert track_info['artist'] == 'Stars' assert track_info['album'] == 'Heart' assert track_info['length'] == 243.147 assert track_info['date'] == '2003' or track.date == '2003-01-01' assert track_info['spotify_url'] == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_nxtrack_purge(self): self.mpd.clear() track = track_from_spotify_url("spotify:track:6LDYVzxjDSAO92UZ5veM3u") self.db.session.add(PlayQueueEntry(track=track, mpd_id=0)) self.db.session.commit() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 def test_add_anon_track(self): self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) self.mpd.addid("spotify:track:6LDYVzxjDSAO92UZ5veM3u") _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 1 assert len(PlayQueueEntry.query.all()) == 1 db_entry = PlayQueueEntry.query.first() assert db_entry.track.spotify_url == "spotify:track:6LDYVzxjDSAO92UZ5veM3u" assert db_entry.user is None @suite('transient') def test_round_robin_selection(self): set_config_value('SELECTION_SCHEME', 'ROUND_ROBIN') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 # Simulate 5 users queueing up 10 tracks each in serial users = [] for i in range(1, 4): user = self.create_test_user() users.append(user) for ii in range(1, 4): track = self.random_sample_track() add_track_from_spotify_url(self.mpd, track['file'], user.id) first_user = users[0] users = sorted(users, key=lambda x: x.username) users = cycle(users) users = dropwhile(lambda x: x != first_user, users) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) mpd_playlist = self.mpd.playlistinfo() db_tracks = PlayQueueEntry.query.order_by(PlayQueueEntry.playback_priority.asc()).all() for (pqe, mpd_track) in zip(db_tracks, mpd_playlist): assert pqe.playback_priority == mpd_track['pos'] for (pqe, prop_user) in zip(db_tracks, users): assert pqe.user == prop_user @suite('transient') def test_fcfs_selection(self): set_config_value('SELECTION_SCHEME', 'FCFS') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 # Simulate 5 users queueing up 10 tracks each in serial users = [] for i in range(1, 4): user = self.create_test_user() for i in range(1, 4): users.append(user) track = self.random_sample_track() add_track_from_spotify_url(self.mpd, track['file'], user.id) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) mpd_playlist = self.mpd.playlistinfo() db_tracks = PlayQueueEntry.query.order_by(PlayQueueEntry.playback_priority.asc()).all() for (pqe, mpd_track) in zip(db_tracks, mpd_playlist): assert pqe.playback_priority == mpd_track['pos'] for (pqe, prop_user) in zip(db_tracks, users): assert pqe.user == prop_user @suite('transient') def test_fcfs_with_voting_selection(self): set_config_value('SELECTION_SCHEME', 'FCFS_VOTE') load_config_from_db() self.mpd.clear() _ensure_mpd_playlist_consistency(self.mpd) assert len(self.mpd.playlistinfo()) == 0 assert len(PlayQueueEntry.query.all()) == 0 user1 = self.create_test_user() user2 = self.create_test_user() tracks = [] for i in range(1,11): st = self.random_sample_track() tracks.append(add_track_from_spotify_url(self.mpd, st['file'], user1.id)) # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) for mpd_track, expected_track in zip(self.mpd.playlistinfo(), tracks): assert mpd_track['file'] == expected_track.spotify_url r = random.Random() pqes = PlayQueueEntry.query.order_by(PlayQueueEntry.time_added).all() up_voted = [] down_voted = [] for i in range(1,4): pqe = r.choice(pqes) pqes.remove(pqe) up_voted.append(pqe) vote = Vote(user=user2, pqe=pqe, direction=1) db.session.add(vote) for i in range(1,4): pqe = r.choice(pqes) pqes.remove(pqe) down_voted.append(pqe) vote = Vote(user=user2, pqe=pqe, direction=-1) db.session.add(vote) db.session.commit() up_voted = sorted(up_voted, key=lambda x: x.time_added) down_voted = sorted(down_voted, key=lambda x: x.time_added) expected_order = up_voted + pqes + down_voted # Simulate the callback chain that would occur in the wild last_order = [] while last_order != [i['id'] for i in self.mpd.playlistinfo()]: last_order = [i['id'] for i in self.mpd.playlistinfo()] _ensure_mpd_playlist_consistency(self.mpd) for mpd_track, expected_track in zip(self.mpd.playlistinfo(), expected_order): assert mpd_track['file'] == expected_track.track.spotify_url def random_sample_track(self): r = random.Random() return r.choice(sample_tracks)
class QueueTestCase(LoggedInUserTestCase): """Tests all of the functions pertaining to queue management (queue.py).""" @setup def _with_mpd_client(self): self.mpd = MockMPDClient() def test_queue_add(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert response_data['file'] == track_to_add['file'] assert any([track['spotify_url'] == track_to_add['file'] for track in response_data['queue']]) assert track_to_add in self.mpd.playlistinfo() def test_queue_add_bad_track(self): track_to_add = 'ERk;lw343##' response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'invalid' in response_data['message'] def test_queue_add_no_track(self): response = self.app.post('/queue/add', data = {}) assert response.status_code != 200 def test_queue_remove(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' assert not any([track['spotify_url'] == track_to_add['file'] for track in response_data['queue']]) assert track_to_add not in self.mpd.playlistinfo() def test_queue_remove_bad_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': 'kjffdgfsfsasfdghhjkghf'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Not a valid track ID!' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_nonexistent_track(self): track_to_add = self.random_sample_track() response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': '4354565745353534'}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'Could not find track with id' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_remove_unowned_track(self): other_user = self.create_test_user() other_user_client = app.test_client() # Log the 'other' user in other_user_client.post('/login', data = {'username': other_user.username, 'password': other_user.username}, follow_redirects = True) track_to_add = self.random_sample_track() response = other_user_client.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' added_track = [track for track in response_data['queue'] if track['spotify_url'] == track_to_add['file']][0] added_mpd_id = added_track['mpd_id'] response = self.app.post('/queue/remove', data = {'track_id': added_mpd_id}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] != 'ok' assert response_data['status'] == 'error' assert 'You are not authorized' in response_data['message'] assert track_to_add in self.mpd.playlistinfo() def test_queue_reorder_tracks(self): # Add a bunch of tracks. tracks_to_add = [track for track in sample_tracks if track['album'] == 'Some Are Lakes'] for track_to_add in tracks_to_add: response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' r = random.Random() pqe_ids = [track['id'] for track in response_data['queue']] priorities = range(1, len(pqe_ids) + 1) r.shuffle(pqe_ids) r.shuffle(priorities) new_priorities = dict( (pqe_id, priority) for (pqe_id, priority) in zip(pqe_ids, priorities) ) response = self.app.post('/queue/reorder', data = new_priorities) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' def test_user_queue_list(self): r = random.Random() # Add a bunch of tracks. tracks_to_add = [track for track in sample_tracks if track['album'] == 'Set Yourself On Fire'] r.shuffle(tracks_to_add) for track_to_add in tracks_to_add: response = self.app.post('/queue/add', data = {'spotify_uri': track_to_add['file']}) response_data = json.loads(response.data) assert response.status_code == 200 assert response_data['status'] == 'ok' response = self.assert_endpoint_works('/queue/list') response_data = json.loads(response.data) assert response_data['status'] == 'ok' for track in tracks_to_add: assert any([response_track['spotify_url'] == track['file'] for response_track in response_data['result']]) def test_track_from_spotify_url(self): track = track_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track is not None assert track.title == 'Elevator Love Letter' assert track.artist == 'Stars' assert track.album == 'Heart' assert track.length == 243.147 assert track.date == '2003' assert track.spotify_url == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def test_track_info_from_spotify_url(self): track_info = track_info_from_spotify_url('spotify:track:6LDYVzxjDSAO92UZ5veM3u') assert track_info is not None assert all(k in track_info for k in ('title', 'artist', 'album', 'spotify_url', 'date', 'length')) assert track_info['title'] == 'Elevator Love Letter' assert track_info['artist'] == 'Stars' assert track_info['album'] == 'Heart' assert track_info['length'] == 243.147 assert track_info['date'] == '2003' assert track_info['spotify_url'] == 'spotify:track:6LDYVzxjDSAO92UZ5veM3u' def random_sample_track(self): r = random.Random() return r.choice(sample_tracks)