예제 #1
0
    def test_filter_playlist_by_genre(self):
        new_song = MoodyUtil.create_song(genre='super-dope')
        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=self.song,
                                        emotion=self.emotion,
                                        vote=True)
        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=new_song,
                                        emotion=self.emotion,
                                        vote=True)

        data = {'emotion': self.emotion.name, 'genre': new_song.genre}

        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        queryset = UserSongVote.objects.filter(user=self.user,
                                               emotion=self.emotion,
                                               vote=True,
                                               song__genre=new_song.genre)
        votes_for_emotion_data = average(queryset, 'song__valence',
                                         'song__energy', 'song__danceability')
        valence = votes_for_emotion_data['song__valence__avg'] * 100
        energy = votes_for_emotion_data['song__energy__avg'] * 100
        danceability = votes_for_emotion_data['song__danceability__avg'] * 100

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(len(resp_data['results']), 1)
        self.assertEqual(resp_data['results'][0]['song']['code'],
                         new_song.code)
        self.assertEqual(resp_data['valence'], valence)
        self.assertEqual(resp_data['energy'], energy)
        self.assertEqual(resp_data['danceability'], danceability)
예제 #2
0
    def test_happy_path(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        songs = ExportPlaylistHelper.get_export_playlist_for_user(
            self.user, self.emotion.name)

        self.assertIn(self.song.code, songs)
예제 #3
0
    def test_exclude_downvoted_songs(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        False)
        songs = ExportPlaylistHelper.get_export_playlist_for_user(
            self.user, self.emotion.name)

        self.assertNotIn(self.song.code, songs)
예제 #4
0
    def test_downvoted_songs_are_not_returned(self):
        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=self.song,
                                        emotion=self.emotion,
                                        vote=False)

        data = {'emotion': self.emotion.name}
        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(len(resp_data['results']), 0)
예제 #5
0
    def test_filter_does_not_remove_different_songs(self):
        other_song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user, other_song, self.emotion,
                                        True)

        user_votes = UserSongVote.objects.filter(user=self.user,
                                                 emotion=self.emotion)
        filtered_votes = filter_duplicate_votes_on_song_from_playlist(
            user_votes)

        self.assertEqual(filtered_votes.count(), 2)
예제 #6
0
    def test_duplicate_votes_for_song_returns_one_record_for_song(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user,
                                        self.song,
                                        self.emotion,
                                        True,
                                        context='WORK')

        songs = ExportPlaylistHelper.get_export_playlist_for_user(
            self.user, self.emotion.name)

        self.assertEqual(len(songs), 1)
예제 #7
0
    def test_filter_by_genre(self):
        genre = 'hiphop'
        other_song = MoodyUtil.create_song(genre=genre)

        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user, other_song, self.emotion,
                                        True)

        songs = ExportPlaylistHelper.get_export_playlist_for_user(
            self.user, self.emotion.name, genre=other_song.genre)

        self.assertIn(other_song.code, songs)
        self.assertNotIn(self.song.code, songs)
예제 #8
0
    def test_filter_removes_duplicate_votes_on_song(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user,
                                        self.song,
                                        self.emotion,
                                        True,
                                        context='WORK')

        user_votes = UserSongVote.objects.filter(user=self.user,
                                                 emotion=self.emotion)
        filtered_votes = filter_duplicate_votes_on_song_from_playlist(
            user_votes)

        self.assertEqual(filtered_votes.count(), 1)
예제 #9
0
    def test_endpoint_returns_contexts_for_downvotes(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        False, 'PARTY')
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        False, 'WORK')

        data = {'emotion': self.emotion.name, 'song_code': self.song.code}

        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        expected_contexts = ['PARTY', 'WORK']

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(resp_data['contexts'], expected_contexts)
예제 #10
0
    def test_happy_path(self):
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True, 'WORK')

        data = {'emotion': self.emotion.name, 'song_code': self.song.code}

        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        expected_contexts = ['', 'WORK']

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(resp_data['contexts'], expected_contexts)
예제 #11
0
    def test_post_request_with_invalid_playlist_name_displays_error(self):
        song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, song, self.emotion, True)

        data = {
            'playlist_name': 'test|timeout /T 15',
            'emotion': self.emotion.name,
        }

        resp = self.client.post(self.url, data)

        messages = get_messages_from_response(resp)
        last_message = messages[-1]
        msg = 'Please submit a valid request'

        self.assertEqual(last_message, msg)
예제 #12
0
    def test_post_request_happy_path(self, mock_task_call):
        song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, song, self.emotion, True)

        data = {
            'playlist_name': self.test_playlist_name,
            'emotion': self.emotion.name
        }

        resp = self.client.post(self.url, data)

        mock_task_call.assert_called_once_with(
            self.spotify_auth.pk,
            self.test_playlist_name, [song.code],
            None,
            trace_id=resp.wsgi_request.trace_id)
예제 #13
0
    def test_filter_by_artist(self):
        expected_song = MoodyUtil.create_song(artist='Cool Artist')

        MoodyUtil.create_user_song_vote(self.user, self.song, self.emotion,
                                        True)
        MoodyUtil.create_user_song_vote(self.user, expected_song, self.emotion,
                                        True)

        data = {'emotion': self.emotion.name, 'artist': expected_song.artist}

        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(len(resp_data['results']), 1)
        self.assertEqual(resp_data['results'][0]['song']['code'],
                         expected_song.code)
예제 #14
0
    def test_cached_playlist_includes_songs_user_voted_on_for_different_emotion(
            self, mock_cache):
        voted_song = MoodyUtil.create_song()
        cached_data = {
            'emotion': Emotion.HAPPY,
            'context': 'WORK',
            'playlist': Song.objects.filter(code__in=[voted_song.code])
        }
        mock_cache.get.return_value = cached_data

        MoodyUtil.create_user_song_vote(
            self.user, voted_song,
            Emotion.objects.get(name=Emotion.MELANCHOLY), True)

        resp = self.client.get(self.url)
        resp_json = resp.json()

        self.assertEqual(voted_song.code, resp_json['playlist'][0]['code'])
예제 #15
0
    def test_filter_by_context(self):
        other_song = MoodyUtil.create_song()

        MoodyUtil.create_user_song_vote(self.user,
                                        self.song,
                                        self.emotion,
                                        True,
                                        context='WORK')
        MoodyUtil.create_user_song_vote(self.user,
                                        other_song,
                                        self.emotion,
                                        True,
                                        context='PARTY')

        songs = ExportPlaylistHelper.get_export_playlist_for_user(
            self.user, self.emotion.name, context='PARTY')

        self.assertIn(other_song.code, songs)
        self.assertNotIn(self.song.code, songs)
예제 #16
0
    def test_happy_path(self):
        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=self.song,
                                        emotion=self.emotion,
                                        vote=True)

        data = {'emotion': self.emotion.name}
        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        user_emotion = self.user.get_user_emotion_record(self.emotion.name)

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(resp_data['results'][0]['song']['code'],
                         self.song.code)
        self.assertEqual(resp_data['valence'], user_emotion.valence * 100)
        self.assertEqual(resp_data['energy'], user_emotion.energy * 100)
        self.assertEqual(resp_data['danceability'],
                         user_emotion.danceability * 100)
예제 #17
0
    def test_multiple_votes_for_a_song_does_not_return_duplicate_songs(self):
        # Create two upvotes in different contexts
        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=self.song,
                                        emotion=self.emotion,
                                        vote=True,
                                        context='WORK')

        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=self.song,
                                        emotion=self.emotion,
                                        vote=True,
                                        context='PARTY')

        data = {'emotion': self.emotion.name}
        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(len(resp_data['results']),
                         1)  # We should only see the song once in the response
예제 #18
0
    def test_filter_by_context(self):
        expected_song = MoodyUtil.create_song(name='song-with-context')
        context = 'WORK'

        MoodyUtil.create_user_song_vote(user=self.user,
                                        song=expected_song,
                                        emotion=self.emotion,
                                        vote=True,
                                        context=context)

        MoodyUtil.create_user_song_vote(
            user=self.user,
            song=self.song,
            emotion=self.emotion,
            vote=True,
        )

        data = {'emotion': self.emotion.name, 'context': context}

        resp = self.client.get(self.url, data=data)
        resp_data = resp.json()

        queryset = UserSongVote.objects.filter(user=self.user,
                                               emotion=self.emotion,
                                               vote=True,
                                               context=context)
        votes_for_emotion_data = average(queryset, 'song__valence',
                                         'song__energy', 'song__danceability')
        valence = votes_for_emotion_data['song__valence__avg'] * 100
        energy = votes_for_emotion_data['song__energy__avg'] * 100
        danceability = votes_for_emotion_data['song__danceability__avg'] * 100

        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        self.assertEqual(len(resp_data['results']), 1)
        self.assertEqual(resp_data['results'][0]['song']['code'],
                         expected_song.code)
        self.assertEqual(resp_data['valence'], valence)
        self.assertEqual(resp_data['energy'], energy)
        self.assertEqual(resp_data['danceability'], danceability)
예제 #19
0
    def test_post_with_invalid_image_upload_displays_error(self):
        song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, song, self.emotion, True)

        with open(
                '{}/apps/spotify/tests/fixtures/hack.php'.format(
                    settings.BASE_DIR), 'rb') as hack_file:
            hack = BytesIO(hack_file.read())
            hack.name = 'hack.php'

        data = {
            'playlist_name': self.test_playlist_name,
            'emotion': self.emotion.name,
            'cover_image': hack
        }

        resp = self.client.post(self.url, data)

        messages = get_messages_from_response(resp)
        last_message = messages[-1]
        msg = 'Please submit a valid request'

        self.assertEqual(last_message, msg)
예제 #20
0
    def test_happy_path(self):
        dispatch_uid = settings.UPDATE_USER_EMOTION_ATTRIBUTES_SIGNAL_UID
        with SignalDisconnect(post_save, update_user_emotion_attributes,
                              UserSongVote, dispatch_uid):
            MoodyUtil.create_user_song_vote(self.user, self.song1,
                                            self.emotion, True)
            MoodyUtil.create_user_song_vote(self.user, self.song2,
                                            self.emotion, True)

        UpdateUserEmotionRecordAttributeTask().run(self.user.pk,
                                                   self.emotion.pk)

        user_emotion = self.user.get_user_emotion_record(self.emotion.name)
        user_votes = self.user.usersongvote_set.all()

        expected_attributes = average(user_votes, 'song__valence',
                                      'song__energy', 'song__danceability')
        expected_valence = expected_attributes['song__valence__avg']
        expected_energy = expected_attributes['song__energy__avg']
        expected_danceability = expected_attributes['song__danceability__avg']

        self.assertEqual(user_emotion.valence, expected_valence)
        self.assertEqual(user_emotion.energy, expected_energy)
        self.assertEqual(user_emotion.danceability, expected_danceability)
예제 #21
0
    def test_post_request_with_invalid_playlist_name_and_cover_image_displays_error(
            self):
        song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, song, self.emotion, True)

        with open(
                '{}/apps/spotify/tests/fixtures/cat.jpg'.format(
                    settings.BASE_DIR), 'rb') as img_file:
            img = BytesIO(img_file.read())
            img.name = 'my_cover.jpg'

        data = {
            'playlist_name': 'test|timeout /T 15',
            'emotion': self.emotion.name,
            'cover_image': img
        }

        resp = self.client.post(self.url, data)

        messages = get_messages_from_response(resp)
        last_message = messages[-1]
        msg = 'Please submit a valid request'

        self.assertEqual(last_message, msg)
예제 #22
0
    def test_post_with_image_upload_saves_image(self, mock_task_call):
        song = MoodyUtil.create_song()
        MoodyUtil.create_user_song_vote(self.user, song, self.emotion, True)

        with open(
                '{}/apps/spotify/tests/fixtures/cat.jpg'.format(
                    settings.BASE_DIR), 'rb') as img_file:
            img = BytesIO(img_file.read())
            img.name = 'my_cover.jpg'

        data = {
            'playlist_name': self.test_playlist_name,
            'emotion': self.emotion.name,
            'cover_image': img
        }

        expected_image_filename = '{}/{}_{}_{}.jpg'.format(
            settings.IMAGE_FILE_UPLOAD_PATH,
            self.user.username,
            data['emotion'],
            data['playlist_name'],
        )

        # Cleanup old cover file if exists
        if os.path.exists(expected_image_filename):
            os.unlink(expected_image_filename)

        resp = self.client.post(self.url, data)

        self.assertTrue(os.path.exists(expected_image_filename))

        mock_task_call.assert_called_once_with(
            self.spotify_auth.pk,
            self.test_playlist_name, [song.code],
            expected_image_filename,
            trace_id=resp.wsgi_request.trace_id)
예제 #23
0
    def test_playlist_for_context_is_generated_with_upvoted_song_attributes_for_context(
            self, mock_generate_playlist):
        context = 'WORK'
        emotion = Emotion.objects.get(name=Emotion.HAPPY)

        song = MoodyUtil.create_song(energy=.25, valence=.50, danceability=.75)
        song2 = MoodyUtil.create_song(energy=.75,
                                      valence=.50,
                                      danceability=.25)
        song3 = MoodyUtil.create_song(energy=.50,
                                      valence=.75,
                                      danceability=.25)

        MoodyUtil.create_user_song_vote(self.user,
                                        song,
                                        emotion,
                                        True,
                                        context=context)
        MoodyUtil.create_user_song_vote(self.user,
                                        song2,
                                        emotion,
                                        True,
                                        context=context)
        MoodyUtil.create_user_song_vote(
            self.user, song3, emotion,
            True)  # Attributes should not be factored in

        params = {'emotion': emotion.name, 'jitter': 0, 'context': context}
        self.client.get(self.url, data=params)

        votes = UserSongVote.objects.filter(user=self.user,
                                            emotion=emotion,
                                            context=context,
                                            vote=True)
        attributes_for_votes = average(votes, 'song__valence', 'song__energy',
                                       'song__danceability')
        expected_valence = attributes_for_votes['song__valence__avg']
        expected_energy = attributes_for_votes['song__energy__avg']
        expected_danceability = attributes_for_votes['song__danceability__avg']

        call_args = mock_generate_playlist.mock_calls[0][1]
        called_energy = call_args[0]
        called_valence = call_args[1]
        called_danceability = call_args[2]

        self.assertEqual(called_valence, expected_valence)
        self.assertEqual(called_energy, expected_energy)
        self.assertEqual(called_danceability, expected_danceability)