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

Merge branch 'faster-tests' into 'develop'

Faster tests

See merge request funkwhale/funkwhale!517
parents fa5034bd d4eff5aa
No related branches found
No related tags found
No related merge requests found
Showing
with 82 additions and 57 deletions
...@@ -327,7 +327,7 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") ...@@ -327,7 +327,7 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
# AUTHENTICATION CONFIGURATION # AUTHENTICATION CONFIGURATION
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend", "funkwhale_api.users.auth_backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend", "allauth.account.auth_backends.AuthenticationBackend",
) )
SESSION_COOKIE_HTTPONLY = False SESSION_COOKIE_HTTPONLY = False
...@@ -538,6 +538,7 @@ MUSICBRAINZ_HOSTNAME = env("MUSICBRAINZ_HOSTNAME", default="musicbrainz.org") ...@@ -538,6 +538,7 @@ MUSICBRAINZ_HOSTNAME = env("MUSICBRAINZ_HOSTNAME", default="musicbrainz.org")
# Custom Admin URL, use {% url 'admin:index' %} # Custom Admin URL, use {% url 'admin:index' %}
ADMIN_URL = env("DJANGO_ADMIN_URL", default="^api/admin/") ADMIN_URL = env("DJANGO_ADMIN_URL", default="^api/admin/")
CSRF_USE_SESSIONS = True CSRF_USE_SESSIONS = True
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# Playlist settings # Playlist settings
# XXX: deprecated, see #186 # XXX: deprecated, see #186
......
...@@ -28,3 +28,14 @@ def ManyToManyFromList(field_name): ...@@ -28,3 +28,14 @@ def ManyToManyFromList(field_name):
field.add(*extracted) field.add(*extracted)
return inner return inner
class NoUpdateOnCreate:
"""
Factory boy calls save after the initial create. In most case, this
is not needed, so we disable this behaviour
"""
@classmethod
def _after_postgeneration(cls, instance, create, results=None):
return
import factory import factory
from funkwhale_api.factories import registry from funkwhale_api.factories import registry, NoUpdateOnCreate
from funkwhale_api.music.factories import TrackFactory from funkwhale_api.music.factories import TrackFactory
from funkwhale_api.users.factories import UserFactory from funkwhale_api.users.factories import UserFactory
@registry.register @registry.register
class TrackFavorite(factory.django.DjangoModelFactory): class TrackFavorite(NoUpdateOnCreate, factory.django.DjangoModelFactory):
track = factory.SubFactory(TrackFactory) track = factory.SubFactory(TrackFactory)
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
......
...@@ -7,7 +7,7 @@ from django.conf import settings ...@@ -7,7 +7,7 @@ from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.utils.http import http_date from django.utils.http import http_date
from funkwhale_api.factories import registry from funkwhale_api.factories import registry, NoUpdateOnCreate
from funkwhale_api.users import factories as user_factories from funkwhale_api.users import factories as user_factories
from . import keys, models from . import keys, models
...@@ -67,7 +67,7 @@ def create_user(actor): ...@@ -67,7 +67,7 @@ def create_user(actor):
@registry.register @registry.register
class Domain(factory.django.DjangoModelFactory): class Domain(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.Faker("domain_name") name = factory.Faker("domain_name")
class Meta: class Meta:
...@@ -76,7 +76,7 @@ class Domain(factory.django.DjangoModelFactory): ...@@ -76,7 +76,7 @@ class Domain(factory.django.DjangoModelFactory):
@registry.register @registry.register
class ActorFactory(factory.DjangoModelFactory): class ActorFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
public_key = None public_key = None
private_key = None private_key = None
preferred_username = factory.Faker("user_name") preferred_username = factory.Faker("user_name")
...@@ -100,6 +100,7 @@ class ActorFactory(factory.DjangoModelFactory): ...@@ -100,6 +100,7 @@ class ActorFactory(factory.DjangoModelFactory):
o.domain.name, o.preferred_username o.domain.name, o.preferred_username
) )
) )
keys = factory.LazyFunction(keys.get_key_pair)
class Meta: class Meta:
model = models.Actor model = models.Actor
...@@ -125,19 +126,9 @@ class ActorFactory(factory.DjangoModelFactory): ...@@ -125,19 +126,9 @@ class ActorFactory(factory.DjangoModelFactory):
else: else:
self.user = UserFactory(actor=self, **kwargs) self.user = UserFactory(actor=self, **kwargs)
@factory.post_generation
def keys(self, create, extracted, **kwargs):
if not create:
# Simple build, do nothing.
return
if not extracted:
private, public = keys.get_key_pair()
self.private_key = private.decode("utf-8")
self.public_key = public.decode("utf-8")
@registry.register @registry.register
class FollowFactory(factory.DjangoModelFactory): class FollowFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
target = factory.SubFactory(ActorFactory) target = factory.SubFactory(ActorFactory)
actor = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory)
...@@ -149,28 +140,23 @@ class FollowFactory(factory.DjangoModelFactory): ...@@ -149,28 +140,23 @@ class FollowFactory(factory.DjangoModelFactory):
@registry.register @registry.register
class MusicLibraryFactory(factory.django.DjangoModelFactory): class MusicLibraryFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
actor = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory)
privacy_level = "me" privacy_level = "me"
name = factory.Faker("sentence") name = factory.Faker("sentence")
description = factory.Faker("sentence") description = factory.Faker("sentence")
uploads_count = 0 uploads_count = 0
fid = factory.Faker("federation_url") fid = factory.Faker("federation_url")
followers_url = factory.LazyAttribute(
lambda o: o.fid + "/followers" if o.fid else None
)
class Meta: class Meta:
model = "music.Library" model = "music.Library"
@factory.post_generation
def followers_url(self, create, extracted, **kwargs):
if not create:
# Simple build, do nothing.
return
self.followers_url = extracted or self.fid + "/followers"
@registry.register @registry.register
class LibraryScan(factory.django.DjangoModelFactory): class LibraryScan(NoUpdateOnCreate, factory.django.DjangoModelFactory):
library = factory.SubFactory(MusicLibraryFactory) library = factory.SubFactory(MusicLibraryFactory)
actor = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory)
total_files = factory.LazyAttribute(lambda o: o.library.uploads_count) total_files = factory.LazyAttribute(lambda o: o.library.uploads_count)
...@@ -180,7 +166,7 @@ class LibraryScan(factory.django.DjangoModelFactory): ...@@ -180,7 +166,7 @@ class LibraryScan(factory.django.DjangoModelFactory):
@registry.register @registry.register
class ActivityFactory(factory.django.DjangoModelFactory): class ActivityFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
actor = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory)
url = factory.Faker("federation_url") url = factory.Faker("federation_url")
payload = factory.LazyFunction(lambda: {"type": "Create"}) payload = factory.LazyFunction(lambda: {"type": "Create"})
...@@ -190,7 +176,7 @@ class ActivityFactory(factory.django.DjangoModelFactory): ...@@ -190,7 +176,7 @@ class ActivityFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class InboxItemFactory(factory.django.DjangoModelFactory): class InboxItemFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
actor = factory.SubFactory(ActorFactory, local=True) actor = factory.SubFactory(ActorFactory, local=True)
activity = factory.SubFactory(ActivityFactory) activity = factory.SubFactory(ActivityFactory)
type = "to" type = "to"
...@@ -200,7 +186,7 @@ class InboxItemFactory(factory.django.DjangoModelFactory): ...@@ -200,7 +186,7 @@ class InboxItemFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class DeliveryFactory(factory.django.DjangoModelFactory): class DeliveryFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
activity = factory.SubFactory(ActivityFactory) activity = factory.SubFactory(ActivityFactory)
inbox_url = factory.Faker("url") inbox_url = factory.Faker("url")
...@@ -209,7 +195,7 @@ class DeliveryFactory(factory.django.DjangoModelFactory): ...@@ -209,7 +195,7 @@ class DeliveryFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class LibraryFollowFactory(factory.DjangoModelFactory): class LibraryFollowFactory(NoUpdateOnCreate, factory.DjangoModelFactory):
target = factory.SubFactory(MusicLibraryFactory) target = factory.SubFactory(MusicLibraryFactory)
actor = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory)
......
...@@ -238,6 +238,15 @@ class Actor(models.Model): ...@@ -238,6 +238,15 @@ class Actor(models.Model):
) )
return data return data
@property
def keys(self):
return self.private_key, self.public_key
@keys.setter
def keys(self, v):
self.private_key = v[0].decode("utf-8")
self.public_key = v[1].decode("utf-8")
class InboxItem(models.Model): class InboxItem(models.Model):
""" """
......
import factory import factory
from funkwhale_api.factories import registry from funkwhale_api.factories import registry, NoUpdateOnCreate
from funkwhale_api.music import factories from funkwhale_api.music import factories
from funkwhale_api.users.factories import UserFactory from funkwhale_api.users.factories import UserFactory
@registry.register @registry.register
class ListeningFactory(factory.django.DjangoModelFactory): class ListeningFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
track = factory.SubFactory(factories.TrackFactory) track = factory.SubFactory(factories.TrackFactory)
......
...@@ -2,7 +2,8 @@ import os ...@@ -2,7 +2,8 @@ import os
import factory import factory
from funkwhale_api.factories import ManyToManyFromList, registry from funkwhale_api.factories import ManyToManyFromList, registry, NoUpdateOnCreate
from funkwhale_api.federation import factories as federation_factories from funkwhale_api.federation import factories as federation_factories
from funkwhale_api.music import licenses from funkwhale_api.music import licenses
from funkwhale_api.users import factories as users_factories from funkwhale_api.users import factories as users_factories
...@@ -39,7 +40,7 @@ def deduce_from_conf(field): ...@@ -39,7 +40,7 @@ def deduce_from_conf(field):
@registry.register @registry.register
class LicenseFactory(factory.django.DjangoModelFactory): class LicenseFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
code = "cc-by-4.0" code = "cc-by-4.0"
url = deduce_from_conf("url") url = deduce_from_conf("url")
commercial = deduce_from_conf("commercial") commercial = deduce_from_conf("commercial")
...@@ -54,7 +55,7 @@ class LicenseFactory(factory.django.DjangoModelFactory): ...@@ -54,7 +55,7 @@ class LicenseFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class ArtistFactory(factory.django.DjangoModelFactory): class ArtistFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.Faker("name") name = factory.Faker("name")
mbid = factory.Faker("uuid4") mbid = factory.Faker("uuid4")
fid = factory.Faker("federation_url") fid = factory.Faker("federation_url")
...@@ -65,7 +66,7 @@ class ArtistFactory(factory.django.DjangoModelFactory): ...@@ -65,7 +66,7 @@ class ArtistFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class AlbumFactory(factory.django.DjangoModelFactory): class AlbumFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
title = factory.Faker("sentence", nb_words=3) title = factory.Faker("sentence", nb_words=3)
mbid = factory.Faker("uuid4") mbid = factory.Faker("uuid4")
release_date = factory.Faker("date_object") release_date = factory.Faker("date_object")
...@@ -80,7 +81,7 @@ class AlbumFactory(factory.django.DjangoModelFactory): ...@@ -80,7 +81,7 @@ class AlbumFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class TrackFactory(factory.django.DjangoModelFactory): class TrackFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
fid = factory.Faker("federation_url") fid = factory.Faker("federation_url")
title = factory.Faker("sentence", nb_words=3) title = factory.Faker("sentence", nb_words=3)
mbid = factory.Faker("uuid4") mbid = factory.Faker("uuid4")
...@@ -104,7 +105,7 @@ class TrackFactory(factory.django.DjangoModelFactory): ...@@ -104,7 +105,7 @@ class TrackFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class UploadFactory(factory.django.DjangoModelFactory): class UploadFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
fid = factory.Faker("federation_url") fid = factory.Faker("federation_url")
track = factory.SubFactory(TrackFactory) track = factory.SubFactory(TrackFactory)
library = factory.SubFactory(federation_factories.MusicLibraryFactory) library = factory.SubFactory(federation_factories.MusicLibraryFactory)
...@@ -128,7 +129,7 @@ class UploadFactory(factory.django.DjangoModelFactory): ...@@ -128,7 +129,7 @@ class UploadFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class UploadVersionFactory(factory.django.DjangoModelFactory): class UploadVersionFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
upload = factory.SubFactory(UploadFactory, bitrate=200000) upload = factory.SubFactory(UploadFactory, bitrate=200000)
bitrate = factory.SelfAttribute("upload.bitrate") bitrate = factory.SelfAttribute("upload.bitrate")
mimetype = "audio/mpeg" mimetype = "audio/mpeg"
...@@ -140,7 +141,7 @@ class UploadVersionFactory(factory.django.DjangoModelFactory): ...@@ -140,7 +141,7 @@ class UploadVersionFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class WorkFactory(factory.django.DjangoModelFactory): class WorkFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
mbid = factory.Faker("uuid4") mbid = factory.Faker("uuid4")
language = "eng" language = "eng"
nature = "song" nature = "song"
...@@ -151,7 +152,7 @@ class WorkFactory(factory.django.DjangoModelFactory): ...@@ -151,7 +152,7 @@ class WorkFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class LyricsFactory(factory.django.DjangoModelFactory): class LyricsFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
work = factory.SubFactory(WorkFactory) work = factory.SubFactory(WorkFactory)
url = factory.Faker("url") url = factory.Faker("url")
content = factory.Faker("paragraphs", nb=4) content = factory.Faker("paragraphs", nb=4)
...@@ -161,7 +162,7 @@ class LyricsFactory(factory.django.DjangoModelFactory): ...@@ -161,7 +162,7 @@ class LyricsFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class TagFactory(factory.django.DjangoModelFactory): class TagFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.SelfAttribute("slug") name = factory.SelfAttribute("slug")
slug = factory.Faker("slug") slug = factory.Faker("slug")
...@@ -172,7 +173,7 @@ class TagFactory(factory.django.DjangoModelFactory): ...@@ -172,7 +173,7 @@ class TagFactory(factory.django.DjangoModelFactory):
# XXX To remove # XXX To remove
class ImportBatchFactory(factory.django.DjangoModelFactory): class ImportBatchFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
submitted_by = factory.SubFactory(users_factories.UserFactory) submitted_by = factory.SubFactory(users_factories.UserFactory)
class Meta: class Meta:
...@@ -180,7 +181,7 @@ class ImportBatchFactory(factory.django.DjangoModelFactory): ...@@ -180,7 +181,7 @@ class ImportBatchFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class ImportJobFactory(factory.django.DjangoModelFactory): class ImportJobFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
batch = factory.SubFactory(ImportBatchFactory) batch = factory.SubFactory(ImportBatchFactory)
source = factory.Faker("url") source = factory.Faker("url")
mbid = factory.Faker("uuid4") mbid = factory.Faker("uuid4")
......
import factory import factory
from funkwhale_api.factories import registry from funkwhale_api.factories import registry, NoUpdateOnCreate
from funkwhale_api.music.factories import TrackFactory from funkwhale_api.music.factories import TrackFactory
from funkwhale_api.users.factories import UserFactory from funkwhale_api.users.factories import UserFactory
@registry.register @registry.register
class PlaylistFactory(factory.django.DjangoModelFactory): class PlaylistFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.Faker("name") name = factory.Faker("name")
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
...@@ -15,7 +15,7 @@ class PlaylistFactory(factory.django.DjangoModelFactory): ...@@ -15,7 +15,7 @@ class PlaylistFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class PlaylistTrackFactory(factory.django.DjangoModelFactory): class PlaylistTrackFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
playlist = factory.SubFactory(PlaylistFactory) playlist = factory.SubFactory(PlaylistFactory)
track = factory.SubFactory(TrackFactory) track = factory.SubFactory(TrackFactory)
......
import factory import factory
from funkwhale_api.factories import registry from funkwhale_api.factories import registry, NoUpdateOnCreate
from funkwhale_api.users.factories import UserFactory from funkwhale_api.users.factories import UserFactory
@registry.register @registry.register
class RadioFactory(factory.django.DjangoModelFactory): class RadioFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.Faker("name") name = factory.Faker("name")
description = factory.Faker("paragraphs") description = factory.Faker("paragraphs")
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
...@@ -16,7 +16,7 @@ class RadioFactory(factory.django.DjangoModelFactory): ...@@ -16,7 +16,7 @@ class RadioFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class RadioSessionFactory(factory.django.DjangoModelFactory): class RadioSessionFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
class Meta: class Meta:
...@@ -24,7 +24,7 @@ class RadioSessionFactory(factory.django.DjangoModelFactory): ...@@ -24,7 +24,7 @@ class RadioSessionFactory(factory.django.DjangoModelFactory):
@registry.register(name="radios.CustomRadioSession") @registry.register(name="radios.CustomRadioSession")
class CustomRadioSessionFactory(factory.django.DjangoModelFactory): class CustomRadioSessionFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
user = factory.SubFactory(UserFactory) user = factory.SubFactory(UserFactory)
radio_type = "custom" radio_type = "custom"
custom_radio = factory.SubFactory( custom_radio = factory.SubFactory(
......
from django.contrib.auth import backends, get_user_model
class ModelBackend(backends.ModelBackend):
def get_user(self, user_id):
"""
Select related to avoid two additional queries
"""
try:
user = (
get_user_model()
._default_manager.select_related("actor__domain")
.get(pk=user_id)
)
except get_user_model().DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
...@@ -2,13 +2,13 @@ import factory ...@@ -2,13 +2,13 @@ import factory
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
from django.utils import timezone from django.utils import timezone
from funkwhale_api.factories import ManyToManyFromList, registry from funkwhale_api.factories import ManyToManyFromList, registry, NoUpdateOnCreate
from . import models from . import models
@registry.register @registry.register
class GroupFactory(factory.django.DjangoModelFactory): class GroupFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
name = factory.Sequence(lambda n: "group-{0}".format(n)) name = factory.Sequence(lambda n: "group-{0}".format(n))
class Meta: class Meta:
...@@ -32,7 +32,7 @@ class GroupFactory(factory.django.DjangoModelFactory): ...@@ -32,7 +32,7 @@ class GroupFactory(factory.django.DjangoModelFactory):
@registry.register @registry.register
class InvitationFactory(factory.django.DjangoModelFactory): class InvitationFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
owner = factory.LazyFunction(lambda: UserFactory()) owner = factory.LazyFunction(lambda: UserFactory())
class Meta: class Meta:
......
No preview for this file type
No preview for this file type
...@@ -448,7 +448,7 @@ def test_get_audio_data(factories): ...@@ -448,7 +448,7 @@ def test_get_audio_data(factories):
result = upload.get_audio_data() result = upload.get_audio_data()
assert result == {"duration": 229, "bitrate": 128000, "size": 3459481} assert result == {"duration": 1, "bitrate": 112000, "size": 14858}
def test_library_queryset_with_follows(factories): def test_library_queryset_with_follows(factories):
......
...@@ -27,7 +27,7 @@ def test_guess_mimetype_try_using_extension_if_fail(wrong, factories, mocker): ...@@ -27,7 +27,7 @@ def test_guess_mimetype_try_using_extension_if_fail(wrong, factories, mocker):
[ [
("sample.flac", {"bitrate": 1608000, "length": 0.001}), ("sample.flac", {"bitrate": 1608000, "length": 0.001}),
("test.mp3", {"bitrate": 8000, "length": 267.70285714285717}), ("test.mp3", {"bitrate": 8000, "length": 267.70285714285717}),
("test.ogg", {"bitrate": 128000, "length": 229.18304166666667}), ("test.ogg", {"bitrate": 112000, "length": 1}),
], ],
) )
def test_get_audio_file_data(name, expected): def test_get_audio_file_data(name, expected):
......
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