funkwhale/api/tests/federation/test_tasks.py

157 wiersze
5.7 KiB
Python

import datetime
import os
import pathlib
from django.core.paginator import Paginator
from django.utils import timezone
from funkwhale_api.federation import serializers
from funkwhale_api.federation import tasks
def test_scan_library_does_nothing_if_federation_disabled(mocker, factories):
library = factories["federation.Library"](federation_enabled=False)
tasks.scan_library(library_id=library.pk)
assert library.tracks.count() == 0
def test_scan_library_page_does_nothing_if_federation_disabled(mocker, factories):
library = factories["federation.Library"](federation_enabled=False)
tasks.scan_library_page(library_id=library.pk, page_url=None)
assert library.tracks.count() == 0
def test_scan_library_fetches_page_and_calls_scan_page(mocker, factories, r_mock):
now = timezone.now()
library = factories["federation.Library"](federation_enabled=True)
collection_conf = {
"actor": library.actor,
"id": library.url,
"page_size": 10,
"items": range(10),
}
collection = serializers.PaginatedCollectionSerializer(collection_conf)
scan_page = mocker.patch("funkwhale_api.federation.tasks.scan_library_page.delay")
r_mock.get(collection_conf["id"], json=collection.data)
tasks.scan_library(library_id=library.pk)
scan_page.assert_called_once_with(
library_id=library.id, page_url=collection.data["first"], until=None
)
library.refresh_from_db()
assert library.fetched_date > now
def test_scan_page_fetches_page_and_creates_tracks(mocker, factories, r_mock):
library = factories["federation.Library"](federation_enabled=True)
tfs = factories["music.TrackFile"].create_batch(size=5)
page_conf = {
"actor": library.actor,
"id": library.url,
"page": Paginator(tfs, 5).page(1),
"item_serializer": serializers.AudioSerializer,
}
page = serializers.CollectionPageSerializer(page_conf)
r_mock.get(page.data["id"], json=page.data)
tasks.scan_library_page(library_id=library.pk, page_url=page.data["id"])
lts = list(library.tracks.all().order_by("-published_date"))
assert len(lts) == 5
def test_scan_page_trigger_next_page_scan_skip_if_same(mocker, factories, r_mock):
patched_scan = mocker.patch(
"funkwhale_api.federation.tasks.scan_library_page.delay"
)
library = factories["federation.Library"](federation_enabled=True)
tfs = factories["music.TrackFile"].create_batch(size=1)
page_conf = {
"actor": library.actor,
"id": library.url,
"page": Paginator(tfs, 3).page(1),
"item_serializer": serializers.AudioSerializer,
}
page = serializers.CollectionPageSerializer(page_conf)
data = page.data
data["next"] = data["id"]
r_mock.get(page.data["id"], json=data)
tasks.scan_library_page(library_id=library.pk, page_url=data["id"])
patched_scan.assert_not_called()
def test_scan_page_stops_once_until_is_reached(mocker, factories, r_mock):
library = factories["federation.Library"](federation_enabled=True)
tfs = list(reversed(factories["music.TrackFile"].create_batch(size=5)))
page_conf = {
"actor": library.actor,
"id": library.url,
"page": Paginator(tfs, 3).page(1),
"item_serializer": serializers.AudioSerializer,
}
page = serializers.CollectionPageSerializer(page_conf)
r_mock.get(page.data["id"], json=page.data)
tasks.scan_library_page(
library_id=library.pk, page_url=page.data["id"], until=tfs[1].creation_date
)
lts = list(library.tracks.all().order_by("-published_date"))
assert len(lts) == 2
for i, tf in enumerate(tfs[:1]):
assert tf.creation_date == lts[i].published_date
def test_clean_federation_music_cache_if_no_listen(preferences, factories):
preferences["federation__music_cache_duration"] = 60
lt1 = factories["federation.LibraryTrack"](with_audio_file=True)
lt2 = factories["federation.LibraryTrack"](with_audio_file=True)
lt3 = factories["federation.LibraryTrack"](with_audio_file=True)
tf1 = factories["music.TrackFile"](accessed_date=timezone.now(), library_track=lt1)
tf2 = factories["music.TrackFile"](
accessed_date=timezone.now() - datetime.timedelta(minutes=61), library_track=lt2
)
tf3 = factories["music.TrackFile"](accessed_date=None, library_track=lt3)
path1 = lt1.audio_file.path
path2 = lt2.audio_file.path
path3 = lt3.audio_file.path
tasks.clean_music_cache()
lt1.refresh_from_db()
lt2.refresh_from_db()
lt3.refresh_from_db()
assert bool(lt1.audio_file) is True
assert bool(lt2.audio_file) is False
assert bool(lt3.audio_file) is False
assert os.path.exists(path1) is True
assert os.path.exists(path2) is False
assert os.path.exists(path3) is False
def test_clean_federation_music_cache_orphaned(settings, preferences, factories):
preferences["federation__music_cache_duration"] = 60
path = os.path.join(settings.MEDIA_ROOT, "federation_cache")
keep_path = os.path.join(os.path.join(path, "1a", "b2"), "keep.ogg")
remove_path = os.path.join(os.path.join(path, "c3", "d4"), "remove.ogg")
os.makedirs(os.path.dirname(keep_path), exist_ok=True)
os.makedirs(os.path.dirname(remove_path), exist_ok=True)
pathlib.Path(keep_path).touch()
pathlib.Path(remove_path).touch()
lt = factories["federation.LibraryTrack"](
with_audio_file=True, audio_file__path=keep_path
)
tf = factories["music.TrackFile"](library_track=lt, accessed_date=timezone.now())
tasks.clean_music_cache()
lt.refresh_from_db()
assert bool(lt.audio_file) is True
assert os.path.exists(lt.audio_file.path) is True
assert os.path.exists(remove_path) is False