Skip to content
Snippets Groups Projects
Verified Commit c8a2ae42 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch 'release/0.3'

parents 86c607de 7bbb7387
No related branches found
No related tags found
No related merge requests found
Showing
with 422 additions and 97 deletions
import json
from django.test import RequestFactory
from test_plus.test import TestCase
from funkwhale_api.users.models import User
from . factories import UserFactory
class UserTestCase(TestCase):
def setUp(self):
self.user = self.make_user()
self.factory = RequestFactory()
def test_can_create_user_via_api(self):
url = self.reverse('rest_register')
data = {
'username': 'test1',
'email': 'test1@test.com',
'password1': 'testtest',
'password2': 'testtest',
}
with self.settings(REGISTRATION_MODE="public"):
response = self.client.post(url, data)
self.assertEqual(response.status_code, 201)
u = User.objects.get(email='test1@test.com')
self.assertEqual(u.username, 'test1')
def test_can_disable_registration_view(self):
url = self.reverse('rest_register')
data = {
'username': 'test1',
'email': 'test1@test.com',
'password1': 'testtest',
'password2': 'testtest',
}
with self.settings(REGISTRATION_MODE="disabled"):
response = self.client.post(url, data)
self.assertEqual(response.status_code, 403)
def test_can_fetch_data_from_api(self):
url = self.reverse('api:v1:users:users-me')
response = self.client.get(url)
# login required
self.assertEqual(response.status_code, 401)
user = UserFactory(
is_staff=True,
perms=[
'music.add_importbatch',
'dynamic_preferences.change_globalpreferencemodel',
]
)
self.assertTrue(user.has_perm('music.add_importbatch'))
self.login(user)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
payload = json.loads(response.content.decode('utf-8'))
self.assertEqual(payload['username'], user.username)
self.assertEqual(payload['is_staff'], user.is_staff)
self.assertEqual(payload['is_superuser'], user.is_superuser)
self.assertEqual(payload['email'], user.email)
self.assertEqual(payload['name'], user.name)
self.assertEqual(
payload['permissions']['import.launch']['status'], True)
self.assertEqual(
payload['permissions']['settings.change']['status'], True)
import tempfile
import shutil
class TMPDirTestCaseMixin(object):
def setUp(self):
super().tearDown()
self.download_dir = tempfile.mkdtemp()
def tearDown(self):
super().tearDown()
shutil.rmtree(self.download_dir)
......@@ -3,3 +3,4 @@ DJANGO_SETTINGS_MODULE=config.settings.test
# -- recommended but optional:
python_files = tests.py test_*.py *_tests.py
testpatsh = tests
......@@ -49,7 +49,7 @@ mutagen>=1.39,<1.40
# Until this is merged
#django-taggit>=0.22,<0.23
git+https://github.com/jdufresne/django-taggit.git@e8f7f216f04c9781bebc84363ab24d575f948ede
git+https://github.com/alex/django-taggit.git@95776ac66948ed7ba7c12e35c1170551e3be66a5
# Until this is merged
git+https://github.com/EliotBerriot/PyMemoize.git@django
# Until this is merged
......
......@@ -5,7 +5,6 @@ django_coverage_plugin>=1.5,<1.6
Sphinx>=1.6,<1.7
django-extensions>=1.9,<1.10
Werkzeug>=0.13,<0.14
django-test-plus>=1.0.20
factory_boy>=2.8.1
# django-debug-toolbar that works with Django 1.5+
......
......@@ -2,7 +2,10 @@
flake8
pytest
pytest-django
# pytest-django until a new release containing django_assert_num_queries
# is deployed to pypi
git+https://github.com/pytest-dev/pytest-django.git@d3d9bb3ef6f0377cb5356eb368992a0834692378
pytest-mock
pytest-sugar
pytest-xdist
import tempfile
import shutil
import pytest
@pytest.fixture(scope="session", autouse=True)
def factories_autodiscover():
from django.apps import apps
from funkwhale_api import factories
app_names = [app.name for app in apps.app_configs.values()]
factories.registry.autodiscover(app_names)
@pytest.fixture
def factories(db):
from funkwhale_api import factories
yield factories.registry
@pytest.fixture
def tmpdir():
d = tempfile.mkdtemp()
yield d
shutil.rmtree(d)
@pytest.fixture
def logged_in_client(db, factories, client):
user = factories['users.User']()
assert client.login(username=user.username, password='test')
setattr(client, 'user', user)
yield client
delattr(client, 'user')
@pytest.fixture
def superuser_client(db, factories, client):
user = factories['users.SuperUser']()
assert client.login(username=user.username, password='test')
setattr(client, 'user', user)
yield client
delattr(client, 'user')
File moved
File moved
File moved
File moved
import json
import pytest
from django.urls import reverse
from funkwhale_api.music import models
from funkwhale_api.musicbrainz import api
from funkwhale_api.music import serializers
from . import data as api_data
def test_can_submit_youtube_url_for_track_import(mocker, superuser_client):
mocker.patch(
'funkwhale_api.musicbrainz.api.artists.get',
return_value=api_data.artists['get']['adhesive_wombat'])
mocker.patch(
'funkwhale_api.musicbrainz.api.releases.get',
return_value=api_data.albums['get']['marsupial'])
mocker.patch(
'funkwhale_api.musicbrainz.api.recordings.get',
return_value=api_data.tracks['get']['8bitadventures'])
mocker.patch(
'funkwhale_api.music.models.TrackFile.download_file',
return_value=None)
mbid = '9968a9d6-8d92-4051-8f76-674e157b6eed'
video_id = 'tPEE9ZwTmy0'
url = reverse('api:v1:submit-single')
response = superuser_client.post(
url,
{'import_url': 'https://www.youtube.com/watch?v={0}'.format(video_id),
'mbid': mbid})
track = models.Track.objects.get(mbid=mbid)
assert track.artist.name == 'Adhesive Wombat'
assert track.album.title == 'Marsupial Madness'
def test_import_creates_an_import_with_correct_data(superuser_client, settings):
mbid = '9968a9d6-8d92-4051-8f76-674e157b6eed'
video_id = 'tPEE9ZwTmy0'
url = reverse('api:v1:submit-single')
settings.CELERY_ALWAYS_EAGER = False
response = superuser_client.post(
url,
{'import_url': 'https://www.youtube.com/watch?v={0}'.format(video_id),
'mbid': mbid})
batch = models.ImportBatch.objects.latest('id')
assert batch.jobs.count() == 1
assert batch.submitted_by == superuser_client.user
assert batch.status == 'pending'
job = batch.jobs.first()
assert str(job.mbid) == mbid
assert job.status == 'pending'
assert job.source == 'https://www.youtube.com/watch?v={0}'.format(video_id)
def test_can_import_whole_album(mocker, superuser_client, settings):
mocker.patch(
'funkwhale_api.musicbrainz.api.artists.get',
return_value=api_data.artists['get']['soad'])
mocker.patch(
'funkwhale_api.musicbrainz.api.images.get_front',
return_value=b'')
mocker.patch(
'funkwhale_api.musicbrainz.api.releases.get',
return_value=api_data.albums['get_with_includes']['hypnotize'])
payload = {
'releaseId': '47ae093f-1607-49a3-be11-a15d335ccc94',
'tracks': [
{
'mbid': '1968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=1111111111',
},
{
'mbid': '2968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=2222222222',
},
{
'mbid': '3968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=3333333333',
},
]
}
url = reverse('api:v1:submit-album')
settings.CELERY_ALWAYS_EAGER = False
response = superuser_client.post(
url, json.dumps(payload), content_type="application/json")
batch = models.ImportBatch.objects.latest('id')
assert batch.jobs.count() == 3
assert batch.submitted_by == superuser_client.user
assert batch.status == 'pending'
album = models.Album.objects.latest('id')
assert str(album.mbid) == '47ae093f-1607-49a3-be11-a15d335ccc94'
medium_data = api_data.albums['get_with_includes']['hypnotize']['release']['medium-list'][0]
assert int(medium_data['track-count']) == album.tracks.all().count()
for track in medium_data['track-list']:
instance = models.Track.objects.get(mbid=track['recording']['id'])
assert instance.title == track['recording']['title']
assert instance.position == int(track['position'])
assert instance.title == track['recording']['title']
for row in payload['tracks']:
job = models.ImportJob.objects.get(mbid=row['mbid'])
assert str(job.mbid) == row['mbid']
assert job.status == 'pending'
assert job.source == row['source']
def test_can_import_whole_artist(mocker, superuser_client, settings):
mocker.patch(
'funkwhale_api.musicbrainz.api.artists.get',
return_value=api_data.artists['get']['soad'])
mocker.patch(
'funkwhale_api.musicbrainz.api.images.get_front',
return_value=b'')
mocker.patch(
'funkwhale_api.musicbrainz.api.releases.get',
return_value=api_data.albums['get_with_includes']['hypnotize'])
payload = {
'artistId': 'mbid',
'albums': [
{
'releaseId': '47ae093f-1607-49a3-be11-a15d335ccc94',
'tracks': [
{
'mbid': '1968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=1111111111',
},
{
'mbid': '2968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=2222222222',
},
{
'mbid': '3968a9d6-8d92-4051-8f76-674e157b6eed',
'source': 'https://www.youtube.com/watch?v=3333333333',
},
]
}
]
}
url = reverse('api:v1:submit-artist')
settings.CELERY_ALWAYS_EAGER = False
response = superuser_client.post(
url, json.dumps(payload), content_type="application/json")
batch = models.ImportBatch.objects.latest('id')
assert batch.jobs.count() == 3
assert batch.submitted_by == superuser_client.user
assert batch.status == 'pending'
album = models.Album.objects.latest('id')
assert str(album.mbid) == '47ae093f-1607-49a3-be11-a15d335ccc94'
medium_data = api_data.albums['get_with_includes']['hypnotize']['release']['medium-list'][0]
assert int(medium_data['track-count']) == album.tracks.all().count()
for track in medium_data['track-list']:
instance = models.Track.objects.get(mbid=track['recording']['id'])
assert instance.title == track['recording']['title']
assert instance.position == int(track['position'])
assert instance.title == track['recording']['title']
for row in payload['albums'][0]['tracks']:
job = models.ImportJob.objects.get(mbid=row['mbid'])
assert str(job.mbid) == row['mbid']
assert job.status == 'pending'
assert job.source == row['source']
def test_user_can_query_api_for_his_own_batches(client, factories):
user1 = factories['users.SuperUser']()
user2 = factories['users.SuperUser']()
job = factories['music.ImportJob'](batch__submitted_by=user1)
url = reverse('api:v1:import-batches-list')
client.login(username=user2.username, password='test')
response2 = client.get(url)
results = json.loads(response2.content.decode('utf-8'))
assert results['count'] == 0
client.logout()
client.login(username=user1.username, password='test')
response1 = client.get(url)
results = json.loads(response1.content.decode('utf-8'))
assert results['count'] == 1
assert results['results'][0]['jobs'][0]['mbid'] == job.mbid
def test_can_search_artist(factories, client):
artist1 = factories['music.Artist']()
artist2 = factories['music.Artist']()
expected = [serializers.ArtistSerializerNested(artist1).data]
url = reverse('api:v1:artists-search')
response = client.get(url, {'query': artist1.name})
assert json.loads(response.content.decode('utf-8')) == expected
def test_can_search_artist_by_name_start(factories, client):
artist1 = factories['music.Artist'](name='alpha')
artist2 = factories['music.Artist'](name='beta')
expected = {
'next': None,
'previous': None,
'count': 1,
'results': [serializers.ArtistSerializerNested(artist1).data]
}
url = reverse('api:v1:artists-list')
response = client.get(url, {'name__startswith': 'a'})
assert expected == json.loads(response.content.decode('utf-8'))
def test_can_search_tracks(factories, client):
track1 = factories['music.Track'](title="test track 1")
track2 = factories['music.Track']()
query = 'test track 1'
expected = [serializers.TrackSerializerNested(track1).data]
url = reverse('api:v1:tracks-search')
response = client.get(url, {'query': query})
assert expected == json.loads(response.content.decode('utf-8'))
@pytest.mark.parametrize('route,method', [
('api:v1:tags-list', 'get'),
('api:v1:tracks-list', 'get'),
('api:v1:artists-list', 'get'),
('api:v1:albums-list', 'get'),
])
def test_can_restrict_api_views_to_authenticated_users(db, route, method, settings, client):
url = reverse(route)
settings.API_AUTHENTICATION_REQUIRED = True
response = getattr(client, method)(url)
assert response.status_code == 401
def test_track_file_url_is_restricted_to_authenticated_users(client, factories, settings):
settings.API_AUTHENTICATION_REQUIRED = True
f = factories['music.TrackFile']()
assert f.audio_file is not None
url = f.path
response = client.get(url)
assert response.status_code == 401
user = factories['users.SuperUser']()
client.login(username=user.username, password='test')
response = client.get(url)
assert response.status_code == 200
assert response['X-Accel-Redirect'] == '/_protected{}'.format(f.audio_file.url)
import json
from django.urls import reverse
from funkwhale_api.music import models
from funkwhale_api.musicbrainz import api
from funkwhale_api.music import serializers
from funkwhale_api.music import lyrics as lyrics_utils
from .mocking import lyricswiki
from . import data as api_data
def test_works_import_lyrics_if_any(mocker, factories):
mocker.patch(
'funkwhale_api.music.lyrics._get_html',
return_value=lyricswiki.content)
lyrics = factories['music.Lyrics'](
url='http://lyrics.wikia.com/System_Of_A_Down:Chop_Suey!')
lyrics.fetch_content()
self.assertIn(
'Grab a brush and put on a little makeup',
lyrics.content,
)
def test_clean_content():
c = """<div class="lyricbox">Hello<br /><script>alert('hello');</script>Is it me you're looking for?<br /></div>"""
d = lyrics_utils.extract_content(c)
d = lyrics_utils.clean_content(d)
expected = """Hello
Is it me you're looking for?
"""
assert d == expected
def test_markdown_rendering(factories):
content = """Hello
Is it me you're looking for?"""
l = factories['music.Lyrics'](content=content)
expected = "<p>Hello<br />\nIs it me you're looking for?</p>"
assert expected == l.content_rendered
def test_works_import_lyrics_if_any(mocker, factories, logged_in_client):
mocker.patch(
'funkwhale_api.musicbrainz.api.works.get',
return_value=api_data.works['get']['chop_suey'])
mocker.patch(
'funkwhale_api.musicbrainz.api.recordings.get',
return_value=api_data.tracks['get']['chop_suey'])
mocker.patch(
'funkwhale_api.music.lyrics._get_html',
return_value=lyricswiki.content)
track = factories['music.Track'](
work=None,
mbid='07ca77cf-f513-4e9c-b190-d7e24bbad448')
url = reverse('api:v1:tracks-lyrics', kwargs={'pk': track.pk})
response = logged_in_client.get(url)
assert response.status_code == 200
track.refresh_from_db()
lyrics = models.Lyrics.objects.latest('id')
work = models.Work.objects.latest('id')
assert track.work == work
assert lyrics.work == work
import datetime
import os
import pytest
from funkwhale_api.music import metadata
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
@pytest.mark.parametrize('field,value', [
('title', 'Peer Gynt Suite no. 1, op. 46: I. Morning'),
('artist', 'Edvard Grieg'),
('album', 'Peer Gynt Suite no. 1, op. 46'),
('date', datetime.date(2012, 8, 15)),
('track_number', 1),
('musicbrainz_albumid', 'a766da8b-8336-47aa-a3ee-371cc41ccc75'),
('musicbrainz_recordingid', 'bd21ac48-46d8-4e78-925f-d9cc2a294656'),
('musicbrainz_artistid', '013c8e5b-d72a-4cd3-8dee-6c64d6125823'),
])
def test_can_get_metadata_from_ogg_file(field, value):
path = os.path.join(DATA_DIR, 'test.ogg')
data = metadata.Metadata(path)
assert data.get(field) == value
@pytest.mark.parametrize('field,value', [
('title', 'Bend'),
('artist', 'Binärpilot'),
('album', 'You Can\'t Stop Da Funk'),
('date', datetime.date(2006, 2, 7)),
('track_number', 1),
('musicbrainz_albumid', 'ce40cdb1-a562-4fd8-a269-9269f98d4124'),
('musicbrainz_recordingid', 'f269d497-1cc0-4ae4-a0c4-157ec7d73fcb'),
('musicbrainz_artistid', '9c6bddde-6228-4d9f-ad0d-03f6fcb19e13'),
])
def test_can_get_metadata_from_id3_mp3_file(field, value):
path = os.path.join(DATA_DIR, 'test.mp3')
data = metadata.Metadata(path)
assert data.get(field) == value
......@@ -2,16 +2,14 @@ import pytest
from funkwhale_api.music import models
from funkwhale_api.music import importers
from . import factories
def test_can_store_release_group_id_on_album(db):
album = factories.AlbumFactory()
def test_can_store_release_group_id_on_album(factories):
album = factories['music.Album']()
assert album.release_group_id is not None
def test_import_album_stores_release_group(db):
def test_import_album_stores_release_group(factories):
album_data = {
"artist-credit": [
{
......@@ -31,7 +29,7 @@ def test_import_album_stores_release_group(db):
"title": "Marsupial Madness",
'release-group': {'id': '447b4979-2178-405c-bfe6-46bf0b09e6c7'}
}
artist = factories.ArtistFactory(
artist = factories['music.Artist'](
mbid=album_data['artist-credit'][0]['artist']['id']
)
cleaned_data = models.Album.clean_musicbrainz_data(album_data)
......@@ -41,9 +39,9 @@ def test_import_album_stores_release_group(db):
assert album.artist == artist
def test_import_job_is_bound_to_track_file(db, mocker):
track = factories.TrackFactory()
job = factories.ImportJobFactory(mbid=track.mbid)
def test_import_job_is_bound_to_track_file(factories, mocker):
track = factories['music.Track']()
job = factories['music.ImportJob'](mbid=track.mbid)
mocker.patch('funkwhale_api.music.models.TrackFile.download_file')
job.run()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment