diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index 9a5ad11f..4bbb5e9f 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -93,7 +93,10 @@ class ActivityObject: with transaction.atomic(): # we can't set many to many and reverse fields on an unsaved object try: - instance.save(broadcast=False) + try: + instance.save(broadcast=False) + except TypeError: + instance.save() except IntegrityError as e: raise ActivitySerializerError(e) diff --git a/bookwyrm/activitypub/note.py b/bookwyrm/activitypub/note.py index 72fbe5fc..1e0bdcb7 100644 --- a/bookwyrm/activitypub/note.py +++ b/bookwyrm/activitypub/note.py @@ -18,7 +18,7 @@ class Note(ActivityObject): ''' Note activity ''' published: str attributedTo: str - content: str + content: str = '' to: List[str] = field(default_factory=lambda: []) cc: List[str] = field(default_factory=lambda: []) replies: Dict = field(default_factory=lambda: {}) diff --git a/bookwyrm/tests/activitypub/test_base_activity.py b/bookwyrm/tests/activitypub/test_base_activity.py index 8668c7e2..e84d7674 100644 --- a/bookwyrm/tests/activitypub/test_base_activity.py +++ b/bookwyrm/tests/activitypub/test_base_activity.py @@ -23,7 +23,7 @@ class BaseActivity(TestCase): 'mouse', 'mouse@mouse.mouse', 'mouseword', local=True, localname='mouse') self.user.remote_id = 'http://example.com/a/b' - self.user.save() + self.user.save(broadcast=False) datafile = pathlib.Path(__file__).parent.joinpath( '../data/ap_user.json' @@ -167,16 +167,19 @@ class BaseActivity(TestCase): with self.assertRaises(ValueError): self.user.avatar.file #pylint: disable=pointless-statement - activity.to_model(models.User, self.user) + # this would trigger a broadcast because it's a local user + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + activity.to_model(models.User, self.user) self.assertIsNotNone(self.user.avatar.name) self.assertIsNotNone(self.user.avatar.file) def test_to_model_many_to_many(self): ''' annoying that these all need special handling ''' - status = models.Status.objects.create( - content='test status', - user=self.user, - ) + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + status = models.Status.objects.create( + content='test status', + user=self.user, + ) book = models.Edition.objects.create( title='Test Edition', remote_id='http://book.com/book') update_data = activitypub.Note( @@ -208,10 +211,11 @@ class BaseActivity(TestCase): def test_to_model_one_to_many(self): ''' these are reversed relationships, where the secondary object keys the primary object but not vice versa ''' - status = models.Status.objects.create( - content='test status', - user=self.user, - ) + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + status = models.Status.objects.create( + content='test status', + user=self.user, + ) update_data = activitypub.Note( id=status.remote_id, content=status.content, @@ -242,10 +246,11 @@ class BaseActivity(TestCase): @responses.activate def test_set_related_field(self): ''' celery task to add back-references to created objects ''' - status = models.Status.objects.create( - content='test status', - user=self.user, - ) + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + status = models.Status.objects.create( + content='test status', + user=self.user, + ) data = { 'url': 'http://www.example.com/image.jpg', 'name': 'alt text', diff --git a/bookwyrm/tests/models/test_relationship_models.py b/bookwyrm/tests/models/test_relationship_models.py index c8d80262..97f267b6 100644 --- a/bookwyrm/tests/models/test_relationship_models.py +++ b/bookwyrm/tests/models/test_relationship_models.py @@ -39,6 +39,7 @@ class Relationship(TestCase): def test_user_follows_from_request(self): ''' convert a follow request into a follow ''' + real_broadcast = models.UserFollowRequest.broadcast def mock_broadcast(_, activity, user): ''' introspect what's being sent out ''' self.assertEqual(user.remote_id, self.local_user.remote_id) @@ -63,12 +64,13 @@ class Relationship(TestCase): self.assertEqual(rel.status, 'follows') self.assertEqual(rel.user_subject, self.local_user) self.assertEqual(rel.user_object, self.remote_user) + models.UserFollowRequest.broadcast = real_broadcast + def test_user_follows_from_request_custom_remote_id(self): ''' store a specific remote id for a relationship provided by remote ''' - with patch( - 'bookwyrm.models.activitypub_mixin.ActivitypubMixin.broadcast'): + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): request = models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user, @@ -92,6 +94,7 @@ class Relationship(TestCase): def test_follow_request_activity(self): ''' accept a request and make it a relationship ''' + real_broadcast = models.UserFollowRequest.broadcast def mock_broadcast(_, activity, user): self.assertEqual(user.remote_id, self.local_user.remote_id) self.assertEqual(activity['actor'], self.local_user.remote_id) @@ -103,10 +106,12 @@ class Relationship(TestCase): user_subject=self.local_user, user_object=self.remote_user, ) + models.UserFollowRequest.broadcast = real_broadcast def test_follow_request_accept(self): ''' accept a request and make it a relationship ''' + real_broadcast = models.UserFollowRequest.broadcast def mock_broadcast(_, activity, user): self.assertEqual(user.remote_id, self.local_user.remote_id) self.assertEqual(activity['type'], 'Accept') @@ -126,10 +131,12 @@ class Relationship(TestCase): rel = models.UserFollows.objects.get() self.assertEqual(rel.user_subject, self.remote_user) self.assertEqual(rel.user_object, self.local_user) + models.UserFollowRequest.broadcast = real_broadcast def test_follow_request_reject(self): ''' accept a request and make it a relationship ''' + real_broadcast = models.UserFollowRequest.broadcast def mock_reject(_, activity, user): self.assertEqual(user.remote_id, self.local_user.remote_id) self.assertEqual(activity['type'], 'Reject') @@ -146,3 +153,4 @@ class Relationship(TestCase): self.assertFalse(models.UserFollowRequest.objects.exists()) self.assertFalse(models.UserFollows.objects.exists()) + models.UserFollowRequest.broadcast = real_broadcast diff --git a/bookwyrm/tests/models/test_shelf_model.py b/bookwyrm/tests/models/test_shelf_model.py index 0433efe3..a9b5a8d6 100644 --- a/bookwyrm/tests/models/test_shelf_model.py +++ b/bookwyrm/tests/models/test_shelf_model.py @@ -18,16 +18,19 @@ class Shelf(TestCase): def test_remote_id(self): ''' shelves use custom remote ids ''' + real_broadcast = models.Shelf.broadcast models.Shelf.broadcast = lambda x, y, z: None shelf = models.Shelf.objects.create( name='Test Shelf', identifier='test-shelf', user=self.local_user) expected_id = 'https://%s/user/mouse/shelf/test-shelf' % settings.DOMAIN self.assertEqual(shelf.get_remote_id(), expected_id) + models.Shelf.broadcast = real_broadcast def test_to_activity(self): ''' jsonify it ''' + real_broadcast = models.Shelf.broadcast models.Shelf.broadcast = lambda x, y, z: None shelf = models.Shelf.objects.create( name='Test Shelf', identifier='test-shelf', @@ -39,10 +42,12 @@ class Shelf(TestCase): self.assertEqual(activity_json['type'], 'Shelf') self.assertEqual(activity_json['name'], 'Test Shelf') self.assertEqual(activity_json['owner'], self.local_user.remote_id) + models.Shelf.broadcast = real_broadcast def test_create_update_shelf(self): ''' create and broadcast shelf creation ''' + real_broadcast = models.Shelf.broadcast def create_mock(_, activity, user): ''' ok ''' self.assertEqual(user.remote_id, self.local_user.remote_id) @@ -65,10 +70,14 @@ class Shelf(TestCase): shelf.name = 'arthur russel' shelf.save() self.assertEqual(shelf.name, 'arthur russel') + models.Shelf.broadcast = real_broadcast def test_shelve(self): ''' create and broadcast shelf creation ''' + real_broadcast = models.Shelf.broadcast + real_shelfbook_broadcast = models.ShelfBook.broadcast + def add_mock(_, activity, user): ''' ok ''' self.assertEqual(user.remote_id, self.local_user.remote_id) @@ -99,3 +108,6 @@ class Shelf(TestCase): models.ShelfBook.broadcast = remove_mock shelf_book.delete() self.assertFalse(shelf.books.exists()) + + models.ShelfBook.broadcast = real_shelfbook_broadcast + models.Shelf.broadcast = real_broadcast diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index 7462c07d..233fd6ea 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -240,6 +240,7 @@ class Status(TestCase): def test_favorite(self): ''' fav a status ''' + real_broadcast = models.Favorite.broadcast def fav_broadcast_mock(_, activity, user): ''' ok ''' self.assertEqual(user.remote_id, self.user.remote_id) @@ -258,6 +259,7 @@ class Status(TestCase): self.assertEqual(activity['type'], 'Like') self.assertEqual(activity['actor'], self.user.remote_id) self.assertEqual(activity['object'], status.remote_id) + models.Favorite.broadcast = real_broadcast def test_boost(self): ''' boosting, this one's a bit fussy ''' diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/test_book.py index 268f16a3..b3360200 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/test_book.py @@ -93,7 +93,11 @@ class BookViews(TestCase): with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): shelf = models.Shelf.objects.create( name='Test Shelf', user=self.local_user) - shelf.books.add(edition1) + models.ShelfBook.objects.create( + book=edition1, + user=self.local_user, + shelf=shelf, + ) models.ReadThrough.objects.create( user=self.local_user, book=edition1) diff --git a/bookwyrm/tests/actions/test_readthrough.py b/bookwyrm/tests/views/test_readthrough.py similarity index 84% rename from bookwyrm/tests/actions/test_readthrough.py rename to bookwyrm/tests/views/test_readthrough.py index 41d2eaa5..41e38a1d 100644 --- a/bookwyrm/tests/actions/test_readthrough.py +++ b/bookwyrm/tests/views/test_readthrough.py @@ -1,13 +1,16 @@ +''' tests updating reading progress ''' +from datetime import datetime from unittest.mock import patch from django.test import TestCase, Client from django.utils import timezone -from datetime import datetime from bookwyrm import models -@patch('bookwyrm.broadcast.broadcast_task.delay') +@patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay') class ReadThrough(TestCase): + ''' readthrough tests ''' def setUp(self): + ''' basic user and book data ''' self.client = Client() self.work = models.Work.objects.create( @@ -25,7 +28,8 @@ class ReadThrough(TestCase): 'cinco', 'cinco@example.com', 'seissiete', local=True, localname='cinco') - self.client.force_login(self.user) + with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): + self.client.force_login(self.user) def test_create_basic_readthrough(self, delay_mock): """A basic readthrough doesn't create a progress update""" @@ -38,13 +42,15 @@ class ReadThrough(TestCase): readthroughs = self.edition.readthrough_set.all() self.assertEqual(len(readthroughs), 1) self.assertEqual(readthroughs[0].progressupdate_set.count(), 0) - self.assertEqual(readthroughs[0].start_date, + self.assertEqual( + readthroughs[0].start_date, datetime(2020, 11, 27, tzinfo=timezone.utc)) self.assertEqual(readthroughs[0].progress, None) self.assertEqual(readthroughs[0].finish_date, None) self.assertEqual(delay_mock.call_count, 1) def test_create_progress_readthrough(self, delay_mock): + ''' a readthrough with progress ''' self.assertEqual(self.edition.readthrough_set.count(), 0) self.client.post('/start-reading/{}'.format(self.edition.id), { @@ -54,7 +60,8 @@ class ReadThrough(TestCase): readthroughs = self.edition.readthrough_set.all() self.assertEqual(len(readthroughs), 1) - self.assertEqual(readthroughs[0].start_date, + self.assertEqual( + readthroughs[0].start_date, datetime(2020, 11, 27, tzinfo=timezone.utc)) self.assertEqual(readthroughs[0].progress, 50) self.assertEqual(readthroughs[0].finish_date, None) @@ -76,7 +83,9 @@ class ReadThrough(TestCase): self.assertEqual(len(progress_updates), 2) self.assertEqual(progress_updates[1].mode, models.ProgressMode.PAGE) self.assertEqual(progress_updates[1].progress, 100) - self.assertEqual(delay_mock.call_count, 1) # Edit doesn't publish anything + + # Edit doesn't publish anything + self.assertEqual(delay_mock.call_count, 1) self.client.post('/delete-readthrough', { 'id': readthroughs[0].id,