Newer
Older
Eliot Berriot
committed
import os
import pathlib
from funkwhale_api.federation import tasks
def test_clean_federation_music_cache_if_no_listen(preferences, factories):
preferences["federation__music_cache_duration"] = 60
remote_library = factories["music.Library"]()
tf1 = factories["music.TrackFile"](
library=remote_library, accessed_date=timezone.now()
)
tf2 = factories["music.TrackFile"](
library=remote_library,
accessed_date=timezone.now() - datetime.timedelta(minutes=61),
)
tf3 = factories["music.TrackFile"](library=remote_library, accessed_date=None)
path1 = tf1.audio_file.path
path2 = tf2.audio_file.path
path3 = tf3.audio_file.path
tasks.clean_music_cache()
tf1.refresh_from_db()
tf2.refresh_from_db()
tf3.refresh_from_db()
assert bool(tf1.audio_file) is True
assert bool(tf2.audio_file) is False
assert bool(tf3.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", "tracks")
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()
tf = factories["music.TrackFile"](
accessed_date=timezone.now(), audio_file__path=keep_path
)
tasks.clean_music_cache()
tf.refresh_from_db()
assert bool(tf.audio_file) is True
assert os.path.exists(tf.audio_file.path) is True
assert os.path.exists(remove_path) is False
def test_handle_in(factories, mocker, now):
mocked_dispatch = mocker.patch("funkwhale_api.federation.routes.inbox.dispatch")
r1 = factories["users.User"](with_actor=True).actor
r2 = factories["users.User"](with_actor=True).actor
a = factories["federation.Activity"](payload={"hello": "world"})
ii1 = factories["federation.InboxItem"](activity=a, actor=r1)
ii2 = factories["federation.InboxItem"](activity=a, actor=r2)
tasks.dispatch_inbox(activity_id=a.pk)
mocked_dispatch.assert_called_once_with(
a.payload, context={"actor": a.actor, "inbox_items": [ii1, ii2]}
)
ii1.refresh_from_db()
ii2.refresh_from_db()
assert ii1.is_delivered is True
assert ii2.is_delivered is True
assert ii1.last_delivery_date == now
assert ii2.last_delivery_date == now
def test_handle_in_error(factories, mocker, now):
mocker.patch(
"funkwhale_api.federation.routes.inbox.dispatch", side_effect=Exception()
r1 = factories["users.User"](with_actor=True).actor
r2 = factories["users.User"](with_actor=True).actor
a = factories["federation.Activity"](payload={"hello": "world"})
factories["federation.InboxItem"](activity=a, actor=r1)
factories["federation.InboxItem"](activity=a, actor=r2)
with pytest.raises(Exception):
tasks.dispatch_inbox(activity_id=a.pk)
assert a.inbox_items.filter(is_delivered=False).count() == 2
def test_dispatch_outbox_to_inbox(factories, mocker):
mocked_inbox = mocker.patch("funkwhale_api.federation.tasks.dispatch_inbox.delay")
mocked_deliver_to_remote_inbox = mocker.patch(
"funkwhale_api.federation.tasks.deliver_to_remote_inbox.delay"
)
activity = factories["federation.Activity"](actor__local=True)
factories["federation.InboxItem"](activity=activity, actor__local=True)
remote_ii = factories["federation.InboxItem"](
activity=activity,
actor__shared_inbox_url=None,
actor__inbox_url="https://test.inbox",
)
tasks.dispatch_outbox(activity_id=activity.pk)
mocked_inbox.assert_called_once_with(activity_id=activity.pk)
mocked_deliver_to_remote_inbox.assert_called_once_with(
activity_id=activity.pk, inbox_url=remote_ii.actor.inbox_url
def test_dispatch_outbox_to_shared_inbox_url(factories, mocker):
mocked_deliver_to_remote_inbox = mocker.patch(
"funkwhale_api.federation.tasks.deliver_to_remote_inbox.delay"
)
activity = factories["federation.Activity"](actor__local=True)
# shared inbox
remote_ii_shared1 = factories["federation.InboxItem"](
activity=activity, actor__shared_inbox_url="https://shared.inbox"
)
# another on the same shared inbox
factories["federation.InboxItem"](
activity=activity, actor__shared_inbox_url="https://shared.inbox"
)
# one on a dedicated inbox
remote_ii_single = factories["federation.InboxItem"](
activity=activity,
actor__shared_inbox_url=None,
actor__inbox_url="https://single.inbox",
)
tasks.dispatch_outbox(activity_id=activity.pk)
assert mocked_deliver_to_remote_inbox.call_count == 2
mocked_deliver_to_remote_inbox.assert_any_call(
activity_id=activity.pk,
shared_inbox_url=remote_ii_shared1.actor.shared_inbox_url,
)
mocked_deliver_to_remote_inbox.assert_any_call(
activity_id=activity.pk, inbox_url=remote_ii_single.actor.inbox_url
)
def test_deliver_to_remote_inbox_inbox_url(factories, r_mock):
activity = factories["federation.Activity"]()
url = "https://test.shared/"
r_mock.post(url)
tasks.deliver_to_remote_inbox(activity_id=activity.pk, inbox_url=url)
Eliot Berriot
committed
request = r_mock.request_history[0]
Eliot Berriot
committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
assert r_mock.called is True
assert r_mock.call_count == 1
assert request.url == url
assert request.headers["content-type"] == "application/activity+json"
assert request.json() == activity.payload
def test_deliver_to_remote_inbox_shared_inbox_url(factories, r_mock):
activity = factories["federation.Activity"]()
url = "https://test.shared/"
r_mock.post(url)
tasks.deliver_to_remote_inbox(activity_id=activity.pk, shared_inbox_url=url)
request = r_mock.request_history[0]
assert r_mock.called is True
assert r_mock.call_count == 1
assert request.url == url
assert request.headers["content-type"] == "application/activity+json"
assert request.json() == activity.payload
def test_deliver_to_remote_inbox_success_shared_inbox_marks_inbox_items_as_delivered(
factories, r_mock, now
):
activity = factories["federation.Activity"]()
url = "https://test.shared/"
r_mock.post(url)
ii = factories["federation.InboxItem"](
activity=activity, actor__shared_inbox_url=url
other_ii = factories["federation.InboxItem"](
activity=activity, actor__shared_inbox_url="https://other.url"
)
tasks.deliver_to_remote_inbox(activity_id=activity.pk, shared_inbox_url=url)
ii.refresh_from_db()
other_ii.refresh_from_db()
assert ii.is_delivered is True
assert ii.last_delivery_date == now
assert other_ii.is_delivered is False
assert other_ii.last_delivery_date is None
def test_deliver_to_remote_inbox_success_single_inbox_marks_inbox_items_as_delivered(
factories, r_mock, now
):
activity = factories["federation.Activity"]()
url = "https://test.single/"
r_mock.post(url)
ii = factories["federation.InboxItem"](activity=activity, actor__inbox_url=url)
other_ii = factories["federation.InboxItem"](
activity=activity, actor__inbox_url="https://other.url"
)
tasks.deliver_to_remote_inbox(activity_id=activity.pk, inbox_url=url)
Eliot Berriot
committed
ii.refresh_from_db()
other_ii.refresh_from_db()
Eliot Berriot
committed
assert ii.is_delivered is True
assert ii.last_delivery_date == now
assert other_ii.is_delivered is False
assert other_ii.last_delivery_date is None
Eliot Berriot
committed
def test_deliver_to_remote_inbox_error(factories, r_mock, now):
activity = factories["federation.Activity"]()
url = "https://test.single/"
r_mock.post(url, status_code=404)
ii = factories["federation.InboxItem"](activity=activity, actor__inbox_url=url)
with pytest.raises(tasks.RequestException):
tasks.deliver_to_remote_inbox(activity_id=activity.pk, inbox_url=url)
ii.refresh_from_db()
assert ii.is_delivered is False
assert ii.last_delivery_date == now
assert ii.delivery_attempts == 1