From 9f829cb04480106b91de97bd80be04a041c11fd1 Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Sat, 29 Sep 2018 19:10:44 +0300 Subject: [PATCH] Finalize initial ActivityPub view decorator functionality Now returns the AS2 serialized object, if found through the configured fetch function. --- .../entities/activitypub/django/views.py | 27 +++++------ .../entities/activitypub/django/test_views.py | 46 ++++++++++++++----- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/federation/entities/activitypub/django/views.py b/federation/entities/activitypub/django/views.py index ace6b46..4ad2935 100644 --- a/federation/entities/activitypub/django/views.py +++ b/federation/entities/activitypub/django/views.py @@ -1,11 +1,9 @@ -from functools import wraps - from django.http import Http404, JsonResponse from federation.utils.django import get_function_from_config -def activitypub_object_view(request, *args, **kwargs): +def activitypub_object_view(func): """ Generic ActivityPub object view decorator. @@ -13,17 +11,14 @@ def activitypub_object_view(request, *args, **kwargs): in JSON if the object is found. Falls back to decorated view, if the content type doesn't match. """ - def decorator(func): - @wraps(func) - def inner(request, *args, **kwargs): - if request.content_type != 'application/json': - return func(request, *args, **kwargs) - get_object_function = get_function_from_config('get_object_function') - obj = get_object_function(request.build_absolute_uri()) - if not obj: - raise Http404 + def inner(request, *args, **kwargs): + if request.content_type not in ('application/json', 'application/activity+json'): + return func(request, *args, **kwargs) + get_object_function = get_function_from_config('get_object_function') + obj = get_object_function(request.build_absolute_uri()) + if not obj: + raise Http404 - as2_obj = obj.as_protocol('activitypub') - return JsonResponse(as2_obj.to_as2()) - return inner - return decorator + as2_obj = obj.as_protocol('activitypub') + return JsonResponse(as2_obj.to_as2(), content_type='application/activity+json') + return inner diff --git a/federation/tests/entities/activitypub/django/test_views.py b/federation/tests/entities/activitypub/django/test_views.py index 8ca8b47..129daeb 100644 --- a/federation/tests/entities/activitypub/django/test_views.py +++ b/federation/tests/entities/activitypub/django/test_views.py @@ -1,10 +1,12 @@ import json +import pytest from django.http import HttpResponse from django.test import RequestFactory +from django.utils.decorators import method_decorator +from django.views import View from federation.entities.activitypub.django.views import activitypub_object_view -from federation.entities.activitypub.entities import ActivitypubProfile @activitypub_object_view @@ -12,21 +14,43 @@ def dummy_view(request, *args, **kwargs): return HttpResponse("foo") +@method_decorator(activitypub_object_view, name='get') +class DummyView(View): + def get(self, request, *args, **kwargs): + return HttpResponse("foo") + + class TestActivityPubObjectView: - def test_renders_as2(self): - # TODO test with real content type, but also json - request = RequestFactory().get("/", CONTENT_TYPE='application/json') - response = dummy_view(request)(request=request) + @pytest.mark.parametrize('content_type', ('application/activity+json', 'application/json')) + def test_renders_as2(self, content_type): + request = RequestFactory().get("/", CONTENT_TYPE=content_type) + response = dummy_view(request=request) assert response.status_code == 200 content = json.loads(response.content) assert content['name'] == 'Bob Bobértson' - # TODO verify content type + assert response['Content-Type'] == 'application/activity+json' + + @pytest.mark.parametrize('content_type', ('application/activity+json', 'application/json')) + def test_renders_as2__cbv(self, content_type): + request = RequestFactory().get("/", CONTENT_TYPE=content_type) + view = DummyView.as_view() + response = view(request=request) + + assert response.status_code == 200 + content = json.loads(response.content) + assert content['name'] == 'Bob Bobértson' + assert response['Content-Type'] == 'application/activity+json' def test_falls_back_if_not_right_content_type(self): - # TODO - pass + request = RequestFactory().get("/") + response = dummy_view(request=request) - def test_falls_back_to_fallback_view(self): - # TODO - pass + assert response.content == b'foo' + + def test_falls_back_if_not_right_content_type__cbv(self): + request = RequestFactory().get("/") + view = DummyView.as_view() + response = view(request=request) + + assert response.content == b'foo'