Esempio n. 1
0
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
Esempio n. 2
0
 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
Esempio n. 3
0
    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()
Esempio n. 4
0
    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()
Esempio n. 5
0
 def _with_mpd_client(self):
     self.mpd = MockMPDClient()
Esempio n. 6
0
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)
Esempio n. 7
0
 def setup(self):
     # Make sure the user that is testing has administrative privileges
     give_user_privilege(self.user, "ADMIN_INTERFACE")
     self.mpd = MockMPDClient()
Esempio n. 8
0
 def _with_mpd_client(self):
     self.mpd = MockMPDClient()
Esempio n. 9
0
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)
Esempio n. 10
0
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)