From db18014325f13205d2ceda58acdd81c936058508 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 15 Oct 2020 17:32:24 -0700 Subject: [PATCH 1/4] Adds test for incoming follow request --- bookwyrm/incoming.py | 11 +++--- bookwyrm/tests/test_incoming_follow.py | 47 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 bookwyrm/tests/test_incoming_follow.py diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index b223ab16b..5aa975b47 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -124,10 +124,10 @@ def handle_follow(activity): return # figure out who the actor is - user = get_or_create_remote_user(activity['actor']) + actor = get_or_create_remote_user(activity['actor']) try: relationship = models.UserFollowRequest.objects.create( - user_subject=user, + user_subject=actor, user_object=to_follow, relationship_id=activity['id'] ) @@ -143,14 +143,15 @@ def handle_follow(activity): status_builder.create_notification( to_follow, 'FOLLOW', - related_user=user + related_user=actor ) - outgoing.handle_accept(user, to_follow, relationship) + outgoing.handle_accept(actor, to_follow, relationship) else: + # Accept will be triggered manually status_builder.create_notification( to_follow, 'FOLLOW_REQUEST', - related_user=user + related_user=actor ) diff --git a/bookwyrm/tests/test_incoming_follow.py b/bookwyrm/tests/test_incoming_follow.py new file mode 100644 index 000000000..a3ac3ebe1 --- /dev/null +++ b/bookwyrm/tests/test_incoming_follow.py @@ -0,0 +1,47 @@ +import json +from django.test import TestCase + +from bookwyrm import models, incoming + + +class Follow(TestCase): + ''' not too much going on in the books model but here we are ''' + def setUp(self): + self.remote_user = models.User.objects.create_user( + 'rat', 'rat@rat.com', 'ratword', + local=False, + remote_id='https://example.com/users/rat', + inbox='https://example.com/users/rat/inbox', + outbox='https://example.com/users/rat/outbox', + ) + self.local_user = models.User.objects.create_user( + 'mouse', 'mouse@mouse.com', 'mouseword') + self.local_user.remote_id = 'http://local.com/user/mouse' + self.local_user.save() + + + def test_handle_follow(self): + activity = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/users/rat/follows/123", + "type": "Follow", + "actor": "https://example.com/users/rat", + "object": "http://local.com/user/mouse" + } + + incoming.handle_follow(activity) + + # notification created + notification = models.Notification.objects.get() + self.assertEqual(notification.user, self.local_user) + self.assertEqual(notification.notification_type, 'FOLLOW') + + # the request should have been deleted + requests = models.UserFollowRequest.objects.all() + self.assertEqual(list(requests), []) + + # the follow relationship should exist + follow = models.UserFollows.objects.get(user_object=self.local_user) + self.assertEqual(follow.user_subject, self.remote_user) + + # an Accept should be sent out From 2d2863d4a8b202076077eb57261c7e4cf2c24b8a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 15 Oct 2020 17:46:23 -0700 Subject: [PATCH 2/4] Adds more incoming follow test cases --- bookwyrm/tests/test_incoming_follow.py | 49 +++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/test_incoming_follow.py b/bookwyrm/tests/test_incoming_follow.py index a3ac3ebe1..b5fbec008 100644 --- a/bookwyrm/tests/test_incoming_follow.py +++ b/bookwyrm/tests/test_incoming_follow.py @@ -44,4 +44,51 @@ class Follow(TestCase): follow = models.UserFollows.objects.get(user_object=self.local_user) self.assertEqual(follow.user_subject, self.remote_user) - # an Accept should be sent out + + def test_handle_follow_manually_approved(self): + activity = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/users/rat/follows/123", + "type": "Follow", + "actor": "https://example.com/users/rat", + "object": "http://local.com/user/mouse" + } + + self.local_user.manually_approves_followers = True + self.local_user.save() + + incoming.handle_follow(activity) + + # notification created + notification = models.Notification.objects.get() + self.assertEqual(notification.user, self.local_user) + self.assertEqual(notification.notification_type, 'FOLLOW_REQUEST') + + # the request should exist + request = models.UserFollowRequest.objects.get() + self.assertEqual(request.user_subject, self.remote_user) + self.assertEqual(request.user_object, self.local_user) + + # the follow relationship should not exist + follow = models.UserFollows.objects.all() + self.assertEqual(list(follow), []) + + + def test_nonexistent_user_follow(self): + activity = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/users/rat/follows/123", + "type": "Follow", + "actor": "https://example.com/users/rat", + "object": "http://local.com/user/nonexistent-user" + } + + incoming.handle_follow(activity) + + # do nothing + notifications = models.Notification.objects.all() + self.assertEqual(list(notifications), []) + requests = models.UserFollowRequest.objects.all() + self.assertEqual(list(requests), []) + follows = models.UserFollows.objects.all() + self.assertEqual(list(follows), []) From 7a01d284c681f16cb3dc825cb6cb16a5b2600764 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 16 Oct 2020 09:23:14 -0700 Subject: [PATCH 3/4] Incoming follow accept test --- bookwyrm/tests/test_incoming_follow_accept.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 bookwyrm/tests/test_incoming_follow_accept.py diff --git a/bookwyrm/tests/test_incoming_follow_accept.py b/bookwyrm/tests/test_incoming_follow_accept.py new file mode 100644 index 000000000..c30dc2486 --- /dev/null +++ b/bookwyrm/tests/test_incoming_follow_accept.py @@ -0,0 +1,51 @@ +import json +from django.test import TestCase + +from bookwyrm import models, incoming + + +class IncomingFollowAccept(TestCase): + ''' not too much going on in the books model but here we are ''' + def setUp(self): + self.remote_user = models.User.objects.create_user( + 'rat', 'rat@rat.com', 'ratword', + local=False, + remote_id='https://example.com/users/rat', + inbox='https://example.com/users/rat/inbox', + outbox='https://example.com/users/rat/outbox', + ) + self.local_user = models.User.objects.create_user( + 'mouse', 'mouse@mouse.com', 'mouseword') + self.local_user.remote_id = 'http://local.com/user/mouse' + self.local_user.save() + + + def test_handle_follow_accept(self): + activity = { + "@context": "https://www.w3.org/ns/activitystreams", + "id": "https://example.com/users/rat/follows/123#accepts", + "type": "Accept", + "actor": "https://example.com/users/rat", + "object": { + "id": "https://example.com/users/rat/follows/123", + "type": "Follow", + "actor": "http://local.com/user/mouse", + "object": "https://example.com/users/rat" + } + } + + models.UserFollowRequest.objects.create( + user_subject=self.local_user, + user_object=self.remote_user + ) + self.assertEqual(models.UserFollowRequest.objects.count(), 1) + + incoming.handle_follow_accept(activity) + + # request should be deleted + self.assertEqual(models.UserFollowRequest.objects.count(), 0) + + # relationship should be created + follows = self.remote_user.followers + self.assertEqual(follows.count(), 1) + self.assertEqual(follows.first(), self.local_user) From 7a153e185a798f491cb315878393de87ae77df46 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 16 Oct 2020 09:45:14 -0700 Subject: [PATCH 4/4] User activitypub tests --- bookwyrm/tests/activitypub/test_person.py | 9 ---- bookwyrm/tests/models/test_user_model.py | 51 +++++++++++++++++------ 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/bookwyrm/tests/activitypub/test_person.py b/bookwyrm/tests/activitypub/test_person.py index 8a077a29e..bec9e19bd 100644 --- a/bookwyrm/tests/activitypub/test_person.py +++ b/bookwyrm/tests/activitypub/test_person.py @@ -21,12 +21,3 @@ class Person(TestCase): self.assertEqual(activity.id, 'https://example.com/user/mouse') self.assertEqual(activity.preferredUsername, 'mouse') self.assertEqual(activity.type, 'Person') - - - def test_serialize_model(self): - activity = self.user.to_activity() - self.assertEqual(activity['id'], self.user.remote_id) - self.assertEqual( - activity['endpoints'], - {'sharedInbox': self.user.shared_inbox} - ) diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index a423de37c..0b43cc005 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -7,28 +7,55 @@ from bookwyrm.settings import DOMAIN class User(TestCase): def setUp(self): - models.User.objects.create_user( + self.user = models.User.objects.create_user( 'mouse', 'mouse@mouse.mouse', 'mouseword') def test_computed_fields(self): ''' username instead of id here ''' - user = models.User.objects.get(localname='mouse') expected_id = 'https://%s/user/mouse' % DOMAIN - self.assertEqual(user.remote_id, expected_id) - self.assertEqual(user.username, 'mouse@%s' % DOMAIN) - self.assertEqual(user.localname, 'mouse') - self.assertEqual(user.shared_inbox, 'https://%s/inbox' % DOMAIN) - self.assertEqual(user.inbox, '%s/inbox' % expected_id) - self.assertEqual(user.outbox, '%s/outbox' % expected_id) - self.assertIsNotNone(user.private_key) - self.assertIsNotNone(user.public_key) + self.assertEqual(self.user.remote_id, expected_id) + self.assertEqual(self.user.username, 'mouse@%s' % DOMAIN) + self.assertEqual(self.user.localname, 'mouse') + self.assertEqual(self.user.shared_inbox, 'https://%s/inbox' % DOMAIN) + self.assertEqual(self.user.inbox, '%s/inbox' % expected_id) + self.assertEqual(self.user.outbox, '%s/outbox' % expected_id) + self.assertIsNotNone(self.user.private_key) + self.assertIsNotNone(self.user.public_key) def test_user_shelves(self): - user = models.User.objects.get(localname='mouse') - shelves = models.Shelf.objects.filter(user=user).all() + shelves = models.Shelf.objects.filter(user=self.user).all() self.assertEqual(len(shelves), 3) names = [s.name for s in shelves] self.assertEqual(names, ['To Read', 'Currently Reading', 'Read']) ids = [s.identifier for s in shelves] self.assertEqual(ids, ['to-read', 'reading', 'read']) + + + def test_activitypub_serialize(self): + activity = self.user.to_activity() + self.assertEqual(activity['id'], self.user.remote_id) + self.assertEqual(activity['@context'], [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1', + { + 'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers', + 'schema': 'http://schema.org#', + 'PropertyValue': 'schema:PropertyValue', + 'value': 'schema:value', + } + ]) + self.assertEqual(activity['preferredUsername'], self.user.localname) + self.assertEqual(activity['name'], self.user.name) + self.assertEqual(activity['inbox'], self.user.inbox) + self.assertEqual(activity['outbox'], self.user.outbox) + self.assertEqual(activity['followers'], self.user.ap_followers) + self.assertEqual(activity['bookwyrmUser'], False) + self.assertEqual(activity['discoverable'], True) + self.assertEqual(activity['type'], 'Person') + + def test_activitypub_outbox(self): + activity = self.user.to_outbox() + self.assertEqual(activity['type'], 'OrderedCollection') + self.assertEqual(activity['id'], self.user.outbox) + self.assertEqual(activity['totalItems'], 0)