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

Fix #114: can now filter artists and albums with no listenable tracks

parent 0f06c398
No related branches found
No related tags found
No related merge requests found
import django_filters from django.db.models import Count
from django_filters import rest_framework as filters
from . import models from . import models
class ArtistFilter(django_filters.FilterSet): class ListenableMixin(filters.FilterSet):
listenable = filters.BooleanFilter(name='_', method='filter_listenable')
def filter_listenable(self, queryset, name, value):
queryset = queryset.annotate(
files_count=Count('tracks__files')
)
if value:
return queryset.filter(files_count__gt=0)
else:
return queryset.filter(files_count=0)
class ArtistFilter(ListenableMixin):
class Meta: class Meta:
model = models.Artist model = models.Artist
fields = { fields = {
'name': ['exact', 'iexact', 'startswith', 'icontains'] 'name': ['exact', 'iexact', 'startswith', 'icontains'],
'listenable': 'exact',
} }
class AlbumFilter(ListenableMixin):
listenable = filters.BooleanFilter(name='_', method='filter_listenable')
class Meta:
model = models.Album
fields = ['listenable']
...@@ -54,6 +54,7 @@ class TagViewSetMixin(object): ...@@ -54,6 +54,7 @@ class TagViewSetMixin(object):
queryset = queryset.filter(tags__pk=tag) queryset = queryset.filter(tags__pk=tag)
return queryset return queryset
class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
queryset = ( queryset = (
models.Artist.objects.all() models.Artist.objects.all()
...@@ -67,6 +68,7 @@ class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): ...@@ -67,6 +68,7 @@ class ArtistViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
filter_class = filters.ArtistFilter filter_class = filters.ArtistFilter
ordering_fields = ('id', 'name', 'creation_date') ordering_fields = ('id', 'name', 'creation_date')
class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
queryset = ( queryset = (
models.Album.objects.all() models.Album.objects.all()
...@@ -78,6 +80,7 @@ class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet): ...@@ -78,6 +80,7 @@ class AlbumViewSet(SearchMixin, viewsets.ReadOnlyModelViewSet):
permission_classes = [ConditionalAuthentication] permission_classes = [ConditionalAuthentication]
search_fields = ['title__unaccent'] search_fields = ['title__unaccent']
ordering_fields = ('creation_date',) ordering_fields = ('creation_date',)
filter_class = filters.AlbumFilter
class ImportBatchViewSet( class ImportBatchViewSet(
......
...@@ -4,6 +4,7 @@ import pytest ...@@ -4,6 +4,7 @@ import pytest
from django.core.cache import cache as django_cache from django.core.cache import cache as django_cache
from dynamic_preferences.registries import global_preferences_registry from dynamic_preferences.registries import global_preferences_registry
from rest_framework.test import APIClient from rest_framework.test import APIClient
from rest_framework.test import APIRequestFactory
from funkwhale_api.activity import record from funkwhale_api.activity import record
from funkwhale_api.taskapp import celery from funkwhale_api.taskapp import celery
...@@ -84,6 +85,11 @@ def superuser_client(db, factories, client): ...@@ -84,6 +85,11 @@ def superuser_client(db, factories, client):
delattr(client, 'user') delattr(client, 'user')
@pytest.fixture
def api_request():
return APIRequestFactory()
@pytest.fixture @pytest.fixture
def activity_registry(): def activity_registry():
r = record.registry r = record.registry
......
import pytest
from funkwhale_api.music import views
@pytest.mark.parametrize('param,expected', [
('true', 'full'),
('false', 'empty'),
])
def test_artist_view_filter_listenable(
param, expected, factories, api_request):
artists = {
'empty': factories['music.Artist'](),
'full': factories['music.TrackFile']().track.artist,
}
request = api_request.get('/', {'listenable': param})
view = views.ArtistViewSet()
view.action_map = {'get': 'list'}
expected = [artists[expected]]
view.request = view.initialize_request(request)
queryset = view.filter_queryset(view.get_queryset())
assert list(queryset) == expected
@pytest.mark.parametrize('param,expected', [
('true', 'full'),
('false', 'empty'),
])
def test_album_view_filter_listenable(
param, expected, factories, api_request):
artists = {
'empty': factories['music.Album'](),
'full': factories['music.TrackFile']().track.album,
}
request = api_request.get('/', {'listenable': param})
view = views.AlbumViewSet()
view.action_map = {'get': 'list'}
expected = [artists[expected]]
view.request = view.initialize_request(request)
queryset = view.filter_queryset(view.get_queryset())
assert list(queryset) == expected
Can now filter artists and albums with no listenable tracks (#114)
...@@ -129,7 +129,8 @@ export default { ...@@ -129,7 +129,8 @@ export default {
page: this.page, page: this.page,
page_size: this.paginateBy, page_size: this.paginateBy,
name__icontains: this.query, name__icontains: this.query,
ordering: this.getOrderingAsString() ordering: this.getOrderingAsString(),
listenable: 'true'
} }
logger.default.debug('Fetching artists') logger.default.debug('Fetching artists')
axios.get(url, {params: params}).then((response) => { axios.get(url, {params: params}).then((response) => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment