Skip to content
Snippets Groups Projects
test_radios.py 7.15 KiB
Newer Older
  • Learn to ignore specific revisions
  • import random
    import json
    from test_plus.test import TestCase
    from django.core.urlresolvers import reverse
    from django.core.exceptions import ValidationError
    
    from model_mommy import mommy
    
    from funkwhale_api.radios import radios
    from funkwhale_api.radios import models
    from funkwhale_api.favorites.models import TrackFavorite
    from funkwhale_api.users.models import User
    from funkwhale_api.music.models import Artist
    
    class TestRadios(TestCase):
    
        def setUp(self):
            super().setUp()
            self.user = User.objects.create_user(username='test', email='test@test.com', password='test')
    
        def test_can_pick_track_from_choices(self):
            choices = [1, 2, 3, 4, 5]
    
            radio = radios.SimpleRadio()
    
            first_pick = radio.pick(choices=choices)
    
            self.assertIn(first_pick, choices)
    
            previous_choices = [first_pick]
            for remaining_choice in choices:
                pick = radio.pick(choices=choices, previous_choices=previous_choices)
                self.assertIn(pick, set(choices).difference(previous_choices))
    
        def test_can_pick_by_weight(self):
            choices_with_weight = [
                # choice, weight
                (1, 1),
                (2, 2),
                (3, 3),
                (4, 4),
                (5, 5),
            ]
    
            picks = {choice: 0 for choice, weight in choices_with_weight}
    
            for i in range(1000):
                radio = radios.SimpleRadio()
                pick = radio.weighted_pick(choices=choices_with_weight)
                picks[pick] = picks[pick] + 1
    
            self.assertTrue(picks[5] > picks[4])
            self.assertTrue(picks[4] > picks[3])
            self.assertTrue(picks[3] > picks[2])
            self.assertTrue(picks[2] > picks[1])
    
        def test_can_get_choices_for_favorites_radio(self):
            tracks = mommy.make('music.Track', _quantity=100)
    
            for i in range(20):
                TrackFavorite.add(track=random.choice(tracks), user=self.user)
    
            radio = radios.FavoritesRadio()
            choices = radio.get_choices(user=self.user)
    
            self.assertEqual(choices.count(), self.user.track_favorites.all().count())
    
            for favorite in self.user.track_favorites.all():
                self.assertIn(favorite.track, choices)
    
            for i in range(20):
                pick = radio.pick(user=self.user)
                self.assertIn(pick, choices)
    
        def test_can_use_radio_session_to_filter_choices(self):
            tracks = mommy.make('music.Track', _quantity=30)
            radio = radios.RandomRadio()
            session = radio.start_session(self.user)
    
            for i in range(30):
    
    
            # ensure 30 differents tracks have been suggested
            tracks_id = [session_track.track.pk for session_track in session.session_tracks.all()]
            self.assertEqual(len(set(tracks_id)), 30)
    
        def test_can_restore_radio_from_previous_session(self):
            tracks = mommy.make('music.Track', _quantity=30)
    
            radio = radios.RandomRadio()
            session = radio.start_session(self.user)
    
            restarted_radio = radios.RandomRadio(session)
            self.assertEqual(radio.session, restarted_radio.session)
    
        def test_can_get_start_radio_from_api(self):
    
            url = reverse('api:v1:radios:sessions-list')
    
            response = self.client.post(url, {'radio_type': 'random'})
            session = models.RadioSession.objects.latest('id')
            self.assertEqual(session.radio_type, 'random')
            self.assertEqual(session.user, None)
    
            self.client.login(username=self.user.username, password='test')
            response = self.client.post(url, {'radio_type': 'random'})
            session = models.RadioSession.objects.latest('id')
            self.assertEqual(session.radio_type, 'random')
            self.assertEqual(session.user, self.user)
    
        def test_can_start_radio_for_anonymous_user(self):
    
            url = reverse('api:v1:radios:sessions-list')
    
            response = self.client.post(url, {'radio_type': 'random'})
            session = models.RadioSession.objects.latest('id')
    
            self.assertIsNone(session.user)
            self.assertIsNotNone(session.session_key)
    
        def test_can_get_track_for_session_from_api(self):
            tracks = mommy.make('music.Track', _quantity=1)
    
            self.client.login(username=self.user.username, password='test')
    
            url = reverse('api:v1:radios:sessions-list')
    
            response = self.client.post(url, {'radio_type': 'random'})
            session = models.RadioSession.objects.latest('id')
    
    
            url = reverse('api:v1:radios:tracks-list')
    
            response = self.client.post(url, {'session': session.pk})
            data = json.loads(response.content.decode('utf-8'))
    
            self.assertEqual(data['track']['id'], tracks[0].id)
            self.assertEqual(data['position'], 1)
    
            next_track = mommy.make('music.Track')
            response = self.client.post(url, {'session': session.pk})
            data = json.loads(response.content.decode('utf-8'))
    
            self.assertEqual(data['track']['id'], next_track.id)
            self.assertEqual(data['position'], 2)
    
        def test_related_object_radio_validate_related_object(self):
            # cannot start without related object
            radio = radios.ArtistRadio()
            with self.assertRaises(ValidationError):
                radio.start_session(self.user)
    
            # cannot start with bad related object type
            radio = radios.ArtistRadio()
            with self.assertRaises(ValidationError):
                radio.start_session(self.user, related_object=self.user)
    
        def test_can_start_artist_radio(self):
            artist = mommy.make('music.Artist')
            wrong_tracks = mommy.make('music.Track', _quantity=30)
            good_tracks = mommy.make('music.Track', artist=artist, _quantity=5)
    
            radio = radios.ArtistRadio()
            session = radio.start_session(self.user, related_object=artist)
            self.assertEqual(session.radio_type, 'artist')
            for i in range(5):
                self.assertIn(radio.pick(), good_tracks)
    
        def test_can_start_tag_radio(self):
            tag = mommy.make('taggit.Tag')
            wrong_tracks = mommy.make('music.Track', _quantity=30)
            good_tracks = mommy.make('music.Track', _quantity=5)
            for track in good_tracks:
                track.tags.add(tag)
    
            radio = radios.TagRadio()
            session = radio.start_session(self.user, related_object=tag)
            self.assertEqual(session.radio_type, 'tag')
            for i in range(5):
                self.assertIn(radio.pick(), good_tracks)
    
        def test_can_start_artist_radio_from_api(self):
            artist = mommy.make('music.Artist')
    
            url = reverse('api:v1:radios:sessions-list')
    
    
            response = self.client.post(url, {'radio_type': 'artist', 'related_object_id': artist.id})
            session = models.RadioSession.objects.latest('id')
            self.assertEqual(session.radio_type, 'artist')
            self.assertEqual(session.related_object, artist)
    
        def test_can_start_less_listened_radio(self):
            history = mommy.make('history.Listening', _quantity=5, user=self.user)
            wrong_tracks = [h.track for h in history]
    
            good_tracks = mommy.make('music.Track', _quantity=30)
    
            radio = radios.LessListenedRadio()
            session = radio.start_session(self.user)
            self.assertEqual(session.related_object, self.user)
            for i in range(5):
                self.assertIn(radio.pick(), good_tracks)