From dbc5e47b4b3bd88da5006e02c37e44eeb19b34a8 Mon Sep 17 00:00:00 2001 From: Marnanel Thurman Date: Mon, 21 Sep 2020 18:10:34 +0100 Subject: [PATCH] Messages posted to user inboxes, and to the shared inbox, will be acted upon. Closes issue #37. --- kepi/bowler_pub/views/activitypub.py | 40 ++++++++++++- kepi/sombrero_sendpub/tests/test_delivery.py | 60 +++++++++++++++----- 2 files changed, 83 insertions(+), 17 deletions(-) diff --git a/kepi/bowler_pub/views/activitypub.py b/kepi/bowler_pub/views/activitypub.py index 8bf1db7..2ea253d 100644 --- a/kepi/bowler_pub/views/activitypub.py +++ b/kepi/bowler_pub/views/activitypub.py @@ -465,9 +465,43 @@ class InboxView(CollectionView): ) def post(self, + request, + username = None, *args, **kwargs): - return HttpResponse( - status = 403, - reason = 'See https://gitlab.com/marnanel/kepi/-/issues/37', + """ + Accept a message posted to one of our inboxes. + + All we do here is pass the message on to validate(), + which will run asynchronously, and then thank the + caller. There is no situation where the caller can + get an error, because errors are being checked for + behind the scenes by the validate() task. + + Params: + request: the HttpRequest + username: the name of the owner of the inbox; + can be None for the shared inbox. + (We ignore this. There's nothing to + be gained by checking it.) + """ + + body = request.data + + log_one_message( + direction = 'incoming', + body = body, + ) + + validate( + path=request.path, + headers=request.headers, + body=body, ) + + # I think this should be 201 Created, but the spec + # says 200, so 200 is what they get. + return HttpResponse( + status = 200, + reason = "Thank you!", + ) diff --git a/kepi/sombrero_sendpub/tests/test_delivery.py b/kepi/sombrero_sendpub/tests/test_delivery.py index 35cddc0..30375b7 100644 --- a/kepi/sombrero_sendpub/tests/test_delivery.py +++ b/kepi/sombrero_sendpub/tests/test_delivery.py @@ -13,34 +13,60 @@ from kepi.sombrero_sendpub.delivery import deliver from kepi.trilby_api.tests import create_local_person from kepi.trilby_api.models import Follow from kepi.bowler_pub.tests import create_remote_person, mock_remote_object -from unittest.mock import MagicMock import kepi.bowler_pub.views as bowler_views import httpretty -TEST_ACTIVITY = {"hello": "world"} +TEST_ACTIVITY = { + 'id': 'https://example.com/foo', + 'type': 'Create', + 'actor': 'alice@example.com', + 'object': { + 'type': 'Note', + 'content': 'Lorem ipsum', + }, + } -class TestDelivery(TestCase): +class Tests(TestCase): def setup_locals(self): self.alice = create_local_person("alice") self.bob = create_local_person("bob") self.carol = create_local_person("carol") - self._real_inbox_view = bowler_views.InboxView.post - self._local_mock = MagicMock( - wraps=self._real_inbox_view, - ) - bowler_views.InboxView.post = self._local_mock + self._real_inbox_post = bowler_views.InboxView.post + self.remotes = {} + self.received_post = set() + + def mock_post(*args, **kwargs): + """ + Wrapper for InboxView.post(), which flags that + the local view has received a copy of the message. + + Adds the name of the user to self.received_post. + If the message was sent to the local shared inbox, + adds "(shared)". + """ + logger.info("Received local post") + + self.received_post.add( + kwargs.get("username") or "(shared)") + + logger.info("%s %s %s", + self.received_post, + kwargs, + kwargs.get("username", "(shared")) + + result = self._real_inbox_post(*args, **kwargs) + return result + + bowler_views.InboxView.post = mock_post def acknowledge_remote(self, name): - logger.info("Received post for %s", name) + logger.info("Received remote post for %s", name) self.received_post.add(name) def setup_remotes(self): - self.remotes = {} - self.received_post = set() - for name in ['peter', 'robert', 'quentin']: self.remotes[name] = create_remote_person( url = 'https://example.org/people/'+name, @@ -69,7 +95,10 @@ class TestDelivery(TestCase): ], ) - self._local_mock.assert_called_once() + self.assertEqual( + self.received_post, + set(['(shared)']), + ) def test_send_to_followers_of_local_user(self): @@ -86,7 +115,10 @@ class TestDelivery(TestCase): ], ) - self._local_mock.assert_called_once() + self.assertEqual( + self.received_post, + set(['(shared)']), + ) @httpretty.activate def test_send_to_remote_user(self):