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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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'])
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)
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)
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
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)
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)
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)
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)
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)
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)