import json import pytest from django.urls import reverse from funkwhale_api.music.serializers import TrackSerializerNested from funkwhale_api.radios import filters from funkwhale_api.radios import serializers def test_can_list_config_options(logged_in_client): url = reverse('api:v1:radios:radios-filters') response = logged_in_client.get(url) assert response.status_code == 200 payload = json.loads(response.content.decode('utf-8')) expected = [f for f in filters.registry.values() if f.expose_in_api] assert len(payload) == len(expected) def test_can_validate_config(logged_in_client, factories): artist1 = factories['music.Artist']() artist2 = factories['music.Artist']() factories['music.Track'].create_batch(3, artist=artist1) factories['music.Track'].create_batch(3, artist=artist2) candidates = artist1.tracks.order_by('pk') f = { 'filters': [ {'type': 'artist', 'ids': [artist1.pk]} ] } url = reverse('api:v1:radios:radios-validate') response = logged_in_client.post( url, json.dumps(f), content_type="application/json") assert response.status_code == 200 payload = json.loads(response.content.decode('utf-8')) expected = { 'count': candidates.count(), 'sample': TrackSerializerNested(candidates, many=True).data } assert payload['filters'][0]['candidates'] == expected assert payload['filters'][0]['errors'] == [] def test_can_validate_config_with_wrong_config(logged_in_client, factories): f = { 'filters': [ {'type': 'artist', 'ids': [999]} ] } url = reverse('api:v1:radios:radios-validate') response = logged_in_client.post( url, json.dumps(f), content_type="application/json") assert response.status_code == 200 payload = json.loads(response.content.decode('utf-8')) expected = { 'count': None, 'sample': None } assert payload['filters'][0]['candidates'] == expected assert len(payload['filters'][0]['errors']) == 1 def test_saving_radio_sets_user(logged_in_client, factories): artist = factories['music.Artist']() f = { 'name': 'Test', 'config': [ {'type': 'artist', 'ids': [artist.pk]} ] } url = reverse('api:v1:radios:radios-list') response = logged_in_client.post( url, json.dumps(f), content_type="application/json") assert response.status_code == 201 radio = logged_in_client.user.radios.latest('id') assert radio.name == 'Test' assert radio.user == logged_in_client.user def test_user_can_detail_his_radio(logged_in_client, factories): radio = factories['radios.Radio'](user=logged_in_client.user) url = reverse('api:v1:radios:radios-detail', kwargs={'pk': radio.pk}) response = logged_in_client.get(url) assert response.status_code == 200 def test_user_can_detail_public_radio(logged_in_client, factories): radio = factories['radios.Radio'](is_public=True) url = reverse('api:v1:radios:radios-detail', kwargs={'pk': radio.pk}) response = logged_in_client.get(url) assert response.status_code == 200 def test_user_cannot_detail_someone_else_radio(logged_in_client, factories): radio = factories['radios.Radio'](is_public=False) url = reverse('api:v1:radios:radios-detail', kwargs={'pk': radio.pk}) response = logged_in_client.get(url) assert response.status_code == 404 def test_user_can_edit_his_radio(logged_in_client, factories): radio = factories['radios.Radio'](user=logged_in_client.user) url = reverse('api:v1:radios:radios-detail', kwargs={'pk': radio.pk}) response = logged_in_client.put( url, json.dumps({'name': 'new', 'config': []}), content_type="application/json") radio.refresh_from_db() assert response.status_code == 200 assert radio.name == 'new' def test_user_cannot_edit_someone_else_radio(logged_in_client, factories): radio = factories['radios.Radio']() url = reverse('api:v1:radios:radios-detail', kwargs={'pk': radio.pk}) response = logged_in_client.put( url, json.dumps({'name': 'new', 'config': []}), content_type="application/json") assert response.status_code == 404 def test_clean_config_is_called_on_serializer_save(mocker, factories): user = factories['users.User']() artist = factories['music.Artist']() data= { 'name': 'Test', 'config': [ {'type': 'artist', 'ids': [artist.pk]} ] } spied = mocker.spy(filters.registry['artist'], 'clean_config') serializer = serializers.RadioSerializer(data=data) assert serializer.is_valid() instance = serializer.save(user=user) spied.assert_called_once_with(data['config'][0]) assert instance.config[0]['names'] == [artist.name]