From 2db416c38dcc1b44960eed435375926cdacfdffc Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Sat, 29 Sep 2018 02:39:14 +0300 Subject: [PATCH] Make activitypub_object_view into a view decorator --- .../entities/activitypub/django/views.py | 31 ++++++++++++------- .../entities/activitypub/django/test_views.py | 14 +++++---- .../tests/entities/diaspora/test_utils.py | 4 +-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/federation/entities/activitypub/django/views.py b/federation/entities/activitypub/django/views.py index e7d9be9..a86aa30 100644 --- a/federation/entities/activitypub/django/views.py +++ b/federation/entities/activitypub/django/views.py @@ -1,21 +1,28 @@ -from typing import Callable +from functools import wraps -from django.http import HttpRequest, Http404, JsonResponse +from django.http import Http404, JsonResponse + +from federation.utils.django import get_function_from_config -def activitypub_object_view(request: HttpRequest, fetch_function: Callable, fallback_view=None): - # TODO implement as view decorator instead? +def activitypub_object_view(request, *args, **kwargs): """ - Generic ActivityPub object view. + Generic ActivityPub object view decorator. Takes an ID and fetches it using the provided function. Renders the ActivityPub object - in JSON if the object is found. Falls back to fallback view, if given, if the content + in JSON if the object is found. Falls back to decorated view, if the content type doesn't match. """ - if request.content_type != 'application/json': - return fallback_view.as_view(request=request) - obj = fetch_function(request.build_absolute_uri()) - if not obj: - raise Http404 + 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 - return JsonResponse(obj.to_as2()) + return JsonResponse(obj.to_as2()) + return inner + return decorator diff --git a/federation/tests/entities/activitypub/django/test_views.py b/federation/tests/entities/activitypub/django/test_views.py index 3dbf57b..1d3ca0b 100644 --- a/federation/tests/entities/activitypub/django/test_views.py +++ b/federation/tests/entities/activitypub/django/test_views.py @@ -1,12 +1,17 @@ import json -from unittest.mock import Mock +from django.http import HttpResponse from django.test import RequestFactory from federation.entities.activitypub.django.views import activitypub_object_view from federation.entities.activitypub.entities import ActivitypubProfile +@activitypub_object_view +def dummy_view(request, *args, **kwargs): + return HttpResponse("foo") + + class TestActivityPubObjectView: def test_renders_as2(self): entity = ActivitypubProfile( @@ -18,11 +23,8 @@ class TestActivityPubObjectView: ) # TODO test with real content type, but also json request = RequestFactory().get("/", CONTENT_TYPE='application/json') - response = activitypub_object_view( - request=request, - fetch_function=lambda x: entity, - fallback_view=lambda x: Mock, - ) + response = dummy_view(request)(request=request) + assert response.status_code == 200 content = json.loads(response.content) assert content['name'] == 'Bob Bobértson' diff --git a/federation/tests/entities/diaspora/test_utils.py b/federation/tests/entities/diaspora/test_utils.py index 118536d..3558e75 100644 --- a/federation/tests/entities/diaspora/test_utils.py +++ b/federation/tests/entities/diaspora/test_utils.py @@ -16,14 +16,14 @@ class TestGetBaseAttributes: attrs = get_base_attributes(entity).keys() assert set(attrs) == { "created_at", "location", "provider_display_name", "public", "raw_content", - "signature", "base_url", "actor_id", "id", "handle", "guid", + "signature", "base_url", "actor_id", "id", "handle", "guid", "activity", "activity_id", } entity = Profile() attrs = get_base_attributes(entity).keys() assert set(attrs) == { "created_at", "name", "email", "gender", "raw_content", "location", "public", "nsfw", "public_key", "image_urls", "tag_list", "signature", "url", "atom_url", - "base_url", "id", "actor_id", "handle", "handle", "guid", + "base_url", "id", "actor_id", "handle", "handle", "guid", "activity", "activity_id", } class TestGetFullXMLRepresentation: