funkwhale/api/tests/radios/test_filters.py

162 wiersze
5.1 KiB
Python

import pytest
from django.core.exceptions import ValidationError
from funkwhale_api.music.models import Track
from funkwhale_api.radios import filters
@filters.registry.register
class NoopFilter(filters.RadioFilter):
code = 'noop'
def get_query(self, candidates, **kwargs):
return
def test_most_simple_radio_does_not_filter_anything(factories):
tracks = factories['music.Track'].create_batch(3)
radio = factories['radios.Radio'](config=[{'type': 'noop'}])
assert radio.version == 0
assert radio.get_candidates().count() == 3
def test_filter_can_use_custom_queryset(factories):
tracks = factories['music.Track'].create_batch(3)
candidates = Track.objects.filter(pk=tracks[0].pk)
qs = filters.run([{'type': 'noop'}], candidates=candidates)
assert qs.count() == 1
assert qs.first() == tracks[0]
def test_filter_on_tag(factories):
tracks = factories['music.Track'].create_batch(3, tags=['metal'])
factories['music.Track'].create_batch(3, tags=['pop'])
expected = tracks
f = [
{'type': 'tag', 'names': ['metal']}
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == expected
def test_filter_on_artist(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)
expected = list(artist1.tracks.order_by('pk'))
f = [
{'type': 'artist', 'ids': [artist1.pk]}
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == expected
def test_can_combine_with_or(factories):
artist1 = factories['music.Artist']()
artist2 = factories['music.Artist']()
artist3 = factories['music.Artist']()
factories['music.Track'].create_batch(3, artist=artist1)
factories['music.Track'].create_batch(3, artist=artist2)
factories['music.Track'].create_batch(3, artist=artist3)
expected = Track.objects.exclude(artist=artist3).order_by('pk')
f = [
{'type': 'artist', 'ids': [artist1.pk]},
{'type': 'artist', 'ids': [artist2.pk], 'operator': 'or'},
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == list(expected)
def test_can_combine_with_and(factories):
artist1 = factories['music.Artist']()
artist2 = factories['music.Artist']()
metal_tracks = factories['music.Track'].create_batch(
2, artist=artist1, tags=['metal'])
factories['music.Track'].create_batch(2, artist=artist1, tags=['pop'])
factories['music.Track'].create_batch(3, artist=artist2)
expected = metal_tracks
f = [
{'type': 'artist', 'ids': [artist1.pk]},
{'type': 'tag', 'names': ['metal'], 'operator': 'and'},
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == list(expected)
def test_can_negate(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)
expected = artist2.tracks.order_by('pk')
f = [
{'type': 'artist', 'ids': [artist1.pk], 'not': True},
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == list(expected)
def test_can_group(factories):
artist1 = factories['music.Artist']()
artist2 = factories['music.Artist']()
factories['music.Track'].create_batch(2, artist=artist1)
t1 = factories['music.Track'].create_batch(
2, artist=artist1, tags=['metal'])
factories['music.Track'].create_batch(2, artist=artist2)
t2 = factories['music.Track'].create_batch(
2, artist=artist2, tags=['metal'])
factories['music.Track'].create_batch(2, tags=['metal'])
expected = t1 + t2
f = [
{'type': 'tag', 'names': ['metal']},
{'type': 'group', 'operator': 'and', 'filters': [
{'type': 'artist', 'ids': [artist1.pk], 'operator': 'or'},
{'type': 'artist', 'ids': [artist2.pk], 'operator': 'or'},
]}
]
candidates = filters.run(f)
assert list(candidates.order_by('pk')) == list(expected)
def test_artist_filter_clean_config(factories):
artist1 = factories['music.Artist']()
artist2 = factories['music.Artist']()
config = filters.clean_config(
{'type': 'artist', 'ids': [artist2.pk, artist1.pk]})
expected = {
'type': 'artist',
'ids': [artist1.pk, artist2.pk],
'names': [artist1.name, artist2.name]
}
assert filters.clean_config(config) == expected
def test_can_check_artist_filter(factories):
artist = factories['music.Artist']()
assert filters.validate({'type': 'artist', 'ids': [artist.pk]})
with pytest.raises(ValidationError):
filters.validate({'type': 'artist', 'ids': [artist.pk + 1]})
def test_can_check_operator():
assert filters.validate(
{'type': 'group', 'operator': 'or', 'filters': []})
assert filters.validate(
{'type': 'group', 'operator': 'and', 'filters': []})
with pytest.raises(ValidationError):
assert filters.validate(
{'type': 'group', 'operator': 'nope', 'filters': []})