From f4b43af600380b45e003a562efab13c088ace40e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 10:24:09 -0700 Subject: [PATCH 1/7] Creates test files for activitystreams --- bookwyrm/tests/activitystreams/__init__.py | 1 + .../test_activitystreams.py | 0 .../test_activitystreams_tasks.py | 32 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 bookwyrm/tests/activitystreams/__init__.py rename bookwyrm/tests/{ => activitystreams}/test_activitystreams.py (100%) create mode 100644 bookwyrm/tests/activitystreams/test_activitystreams_tasks.py diff --git a/bookwyrm/tests/activitystreams/__init__.py b/bookwyrm/tests/activitystreams/__init__.py new file mode 100644 index 000000000..b6e690fd5 --- /dev/null +++ b/bookwyrm/tests/activitystreams/__init__.py @@ -0,0 +1 @@ +from . import * diff --git a/bookwyrm/tests/test_activitystreams.py b/bookwyrm/tests/activitystreams/test_activitystreams.py similarity index 100% rename from bookwyrm/tests/test_activitystreams.py rename to bookwyrm/tests/activitystreams/test_activitystreams.py diff --git a/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py b/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py new file mode 100644 index 000000000..313177001 --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py @@ -0,0 +1,32 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +class Activitystreams(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + work = models.Work.objects.create(title="test work") + self.book = models.Edition.objects.create(title="test book", parent_work=work) + + class TestStream(activitystreams.ActivityStream): + """test stream, don't have to do anything here""" + + key = "test" + + self.test_stream = TestStream() + + def test_add_book_statuses_task(self): + """statuses related to a book""" + with patch("bookwyrm.activitystreams.BooksStream") as mock: + activitystreams.add_book_statuses_task(self.local_user.id, self.book.id) + self.assertTrue(mock.called) From a4041911c6f94c6333bea79d3f8c0c9b0293feeb Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 11:01:27 -0700 Subject: [PATCH 2/7] Adds tests more activitystreams tasks --- .../activitystreams/test_activitystreams.py | 68 ------- .../test_activitystreams_tasks.py | 171 +++++++++++++++++- 2 files changed, 163 insertions(+), 76 deletions(-) diff --git a/bookwyrm/tests/activitystreams/test_activitystreams.py b/bookwyrm/tests/activitystreams/test_activitystreams.py index add5875f7..4e91c5bea 100644 --- a/bookwyrm/tests/activitystreams/test_activitystreams.py +++ b/bookwyrm/tests/activitystreams/test_activitystreams.py @@ -290,71 +290,3 @@ class Activitystreams(TestCase): # yes book, yes audience result = activitystreams.BooksStream().get_statuses_for_user(self.local_user) self.assertEqual(list(result), [status]) - - @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") - @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - def test_boost_to_another_timeline(self, *_): - """add a boost and deduplicate the boosted status on the timeline""" - status = models.Status.objects.create(user=self.local_user, content="hi") - with patch("bookwyrm.activitystreams.handle_boost_task.delay"): - boost = models.Boost.objects.create( - boosted_status=status, - user=self.another_user, - ) - with patch( - "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" - ) as mock: - activitystreams.handle_boost_task(boost.id) - - self.assertTrue(mock.called) - call_args = mock.call_args - self.assertEqual(call_args[0][0], status) - self.assertEqual( - call_args[1]["stores"], ["{:d}-home".format(self.another_user.id)] - ) - - @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") - @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - def test_boost_to_following_timeline(self, *_): - """add a boost and deduplicate the boosted status on the timeline""" - self.local_user.following.add(self.another_user) - status = models.Status.objects.create(user=self.local_user, content="hi") - with patch("bookwyrm.activitystreams.handle_boost_task.delay"): - boost = models.Boost.objects.create( - boosted_status=status, - user=self.another_user, - ) - with patch( - "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" - ) as mock: - activitystreams.handle_boost_task(boost.id) - self.assertTrue(mock.called) - call_args = mock.call_args - self.assertEqual(call_args[0][0], status) - self.assertTrue( - "{:d}-home".format(self.another_user.id) in call_args[1]["stores"] - ) - self.assertTrue( - "{:d}-home".format(self.local_user.id) in call_args[1]["stores"] - ) - - @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") - @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - def test_boost_to_same_timeline(self, *_): - """add a boost and deduplicate the boosted status on the timeline""" - status = models.Status.objects.create(user=self.local_user, content="hi") - with patch("bookwyrm.activitystreams.handle_boost_task.delay"): - boost = models.Boost.objects.create( - boosted_status=status, - user=self.local_user, - ) - with patch( - "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" - ) as mock: - activitystreams.handle_boost_task(boost.id) - self.assertTrue(mock.called) - call_args = mock.call_args - self.assertEqual(call_args[0][0], status) - self.assertEqual( - call_args[1]["stores"], ["{:d}-home".format(self.local_user.id)] - ) diff --git a/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py b/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py index 313177001..a51549ca6 100644 --- a/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py +++ b/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py @@ -15,18 +15,173 @@ class Activitystreams(TestCase): self.local_user = models.User.objects.create_user( "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" ) + self.another_user = models.User.objects.create_user( + "nutria", + "nutria@nutria.nutria", + "password", + local=True, + localname="nutria", + ) work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) - - class TestStream(activitystreams.ActivityStream): - """test stream, don't have to do anything here""" - - key = "test" - - self.test_stream = TestStream() + self.status = models.Status.objects.create(content="hi", user=self.local_user) def test_add_book_statuses_task(self): """statuses related to a book""" - with patch("bookwyrm.activitystreams.BooksStream") as mock: + with patch("bookwyrm.activitystreams.BooksStream.add_book_statuses") as mock: activitystreams.add_book_statuses_task(self.local_user.id, self.book.id) self.assertTrue(mock.called) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.book) + + def test_remove_book_statuses_task(self): + """remove stauses related to a book""" + with patch("bookwyrm.activitystreams.BooksStream.remove_book_statuses") as mock: + activitystreams.remove_book_statuses_task(self.local_user.id, self.book.id) + self.assertTrue(mock.called) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.book) + + def test_populate_stream_task(self): + """populate a given stream""" + with patch("bookwyrm.activitystreams.BooksStream.populate_streams") as mock: + activitystreams.populate_stream_task("books", self.local_user.id) + self.assertTrue(mock.called) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + + with patch("bookwyrm.activitystreams.HomeStream.populate_streams") as mock: + activitystreams.populate_stream_task("home", self.local_user.id) + self.assertTrue(mock.called) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + + def test_remove_status_task(self): + """remove a status from all streams""" + with patch( + "bookwyrm.activitystreams.ActivityStream.remove_object_from_related_stores" + ) as mock: + activitystreams.remove_status_task(self.status.id) + self.assertEqual(mock.call_count, 3) + args = mock.call_args[0] + self.assertEqual(args[0], self.status) + + def test_add_status_task(self): + """add a status to all streams""" + with patch("bookwyrm.activitystreams.ActivityStream.add_status") as mock: + activitystreams.add_status_task(self.status.id) + self.assertEqual(mock.call_count, 3) + args = mock.call_args[0] + self.assertEqual(args[0], self.status) + + def test_remove_user_statuses_task(self): + """remove all statuses by a user from another users' feeds""" + with patch( + "bookwyrm.activitystreams.ActivityStream.remove_user_statuses" + ) as mock: + activitystreams.remove_user_statuses_task( + self.local_user.id, self.another_user.id + ) + self.assertEqual(mock.call_count, 3) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.another_user) + + with patch("bookwyrm.activitystreams.HomeStream.remove_user_statuses") as mock: + activitystreams.remove_user_statuses_task( + self.local_user.id, self.another_user.id, stream_list=["home"] + ) + self.assertEqual(mock.call_count, 1) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.another_user) + + def test_add_user_statuses_task(self): + """add a user's statuses to another users feeds""" + with patch("bookwyrm.activitystreams.ActivityStream.add_user_statuses") as mock: + activitystreams.add_user_statuses_task( + self.local_user.id, self.another_user.id + ) + self.assertEqual(mock.call_count, 3) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.another_user) + + with patch("bookwyrm.activitystreams.HomeStream.add_user_statuses") as mock: + activitystreams.add_user_statuses_task( + self.local_user.id, self.another_user.id, stream_list=["home"] + ) + self.assertEqual(mock.call_count, 1) + args = mock.call_args[0] + self.assertEqual(args[0], self.local_user) + self.assertEqual(args[1], self.another_user) + + @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") + @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + def test_boost_to_another_timeline(self, *_): + """add a boost and deduplicate the boosted status on the timeline""" + status = models.Status.objects.create(user=self.local_user, content="hi") + with patch("bookwyrm.activitystreams.handle_boost_task.delay"): + boost = models.Boost.objects.create( + boosted_status=status, + user=self.another_user, + ) + with patch( + "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" + ) as mock: + activitystreams.handle_boost_task(boost.id) + + self.assertTrue(mock.called) + call_args = mock.call_args + self.assertEqual(call_args[0][0], status) + self.assertEqual( + call_args[1]["stores"], ["{:d}-home".format(self.another_user.id)] + ) + + @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") + @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + def test_boost_to_following_timeline(self, *_): + """add a boost and deduplicate the boosted status on the timeline""" + self.local_user.following.add(self.another_user) + status = models.Status.objects.create(user=self.local_user, content="hi") + with patch("bookwyrm.activitystreams.handle_boost_task.delay"): + boost = models.Boost.objects.create( + boosted_status=status, + user=self.another_user, + ) + with patch( + "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" + ) as mock: + activitystreams.handle_boost_task(boost.id) + self.assertTrue(mock.called) + call_args = mock.call_args + self.assertEqual(call_args[0][0], status) + self.assertTrue( + "{:d}-home".format(self.another_user.id) in call_args[1]["stores"] + ) + self.assertTrue( + "{:d}-home".format(self.local_user.id) in call_args[1]["stores"] + ) + + @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") + @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + def test_boost_to_same_timeline(self, *_): + """add a boost and deduplicate the boosted status on the timeline""" + status = models.Status.objects.create(user=self.local_user, content="hi") + with patch("bookwyrm.activitystreams.handle_boost_task.delay"): + boost = models.Boost.objects.create( + boosted_status=status, + user=self.local_user, + ) + with patch( + "bookwyrm.activitystreams.HomeStream.remove_object_from_related_stores" + ) as mock: + activitystreams.handle_boost_task(boost.id) + self.assertTrue(mock.called) + call_args = mock.call_args + self.assertEqual(call_args[0][0], status) + self.assertEqual( + call_args[1]["stores"], ["{:d}-home".format(self.local_user.id)] + ) From d147c6ac2f84d35f78e443139362c7f5eb356bec Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 11:09:52 -0700 Subject: [PATCH 3/7] Separate tests into more files --- .../activitystreams/test_abstractstream.py | 145 +++++++++ .../activitystreams/test_activitystreams.py | 292 ------------------ .../tests/activitystreams/test_booksstream.py | 55 ++++ .../tests/activitystreams/test_homestream.py | 67 ++++ .../tests/activitystreams/test_localstream.py | 139 +++++++++ ...activitystreams_tasks.py => test_tasks.py} | 0 6 files changed, 406 insertions(+), 292 deletions(-) create mode 100644 bookwyrm/tests/activitystreams/test_abstractstream.py delete mode 100644 bookwyrm/tests/activitystreams/test_activitystreams.py create mode 100644 bookwyrm/tests/activitystreams/test_booksstream.py create mode 100644 bookwyrm/tests/activitystreams/test_homestream.py create mode 100644 bookwyrm/tests/activitystreams/test_localstream.py rename bookwyrm/tests/activitystreams/{test_activitystreams_tasks.py => test_tasks.py} (100%) diff --git a/bookwyrm/tests/activitystreams/test_abstractstream.py b/bookwyrm/tests/activitystreams/test_abstractstream.py new file mode 100644 index 000000000..f96742865 --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_abstractstream.py @@ -0,0 +1,145 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.activitystreams.add_status_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +class Activitystreams(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + self.another_user = models.User.objects.create_user( + "nutria", + "nutria@nutria.nutria", + "password", + local=True, + localname="nutria", + ) + with patch("bookwyrm.models.user.set_remote_server.delay"): + 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", + ) + work = models.Work.objects.create(title="test work") + self.book = models.Edition.objects.create(title="test book", parent_work=work) + + class TestStream(activitystreams.ActivityStream): + """test stream, don't have to do anything here""" + + key = "test" + + self.test_stream = TestStream() + + def test_activitystream_class_ids(self, *_): + """the abstract base class for stream objects""" + self.assertEqual( + self.test_stream.stream_id(self.local_user), + "{}-test".format(self.local_user.id), + ) + self.assertEqual( + self.test_stream.unread_id(self.local_user), + "{}-test-unread".format(self.local_user.id), + ) + + def test_abstractstream_get_audience(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + users = self.test_stream.get_audience(status) + # remote users don't have feeds + self.assertFalse(self.remote_user in users) + self.assertTrue(self.local_user in users) + self.assertTrue(self.another_user in users) + + def test_abstractstream_get_audience_direct(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, + content="hi", + privacy="direct", + ) + status.mention_users.add(self.local_user) + users = self.test_stream.get_audience(status) + self.assertEqual(users, []) + + status = models.Comment.objects.create( + user=self.remote_user, + content="hi", + privacy="direct", + book=self.book, + ) + status.mention_users.add(self.local_user) + users = self.test_stream.get_audience(status) + self.assertTrue(self.local_user in users) + self.assertFalse(self.another_user in users) + self.assertFalse(self.remote_user in users) + + def test_abstractstream_get_audience_followers_remote_user(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, + content="hi", + privacy="followers", + ) + users = self.test_stream.get_audience(status) + self.assertFalse(users.exists()) + + def test_abstractstream_get_audience_followers_self(self, *_): + """get a list of users that should see a status""" + status = models.Comment.objects.create( + user=self.local_user, + content="hi", + privacy="direct", + book=self.book, + ) + users = self.test_stream.get_audience(status) + self.assertTrue(self.local_user in users) + self.assertFalse(self.another_user in users) + self.assertFalse(self.remote_user in users) + + def test_abstractstream_get_audience_followers_with_mention(self, *_): + """get a list of users that should see a status""" + status = models.Comment.objects.create( + user=self.remote_user, + content="hi", + privacy="direct", + book=self.book, + ) + status.mention_users.add(self.local_user) + + users = self.test_stream.get_audience(status) + self.assertTrue(self.local_user in users) + self.assertFalse(self.another_user in users) + self.assertFalse(self.remote_user in users) + + def test_abstractstream_get_audience_followers_with_relationship(self, *_): + """get a list of users that should see a status""" + self.remote_user.followers.add(self.local_user) + status = models.Comment.objects.create( + user=self.remote_user, + content="hi", + privacy="direct", + book=self.book, + ) + users = self.test_stream.get_audience(status) + self.assertFalse(self.local_user in users) + self.assertFalse(self.another_user in users) + self.assertFalse(self.remote_user in users) diff --git a/bookwyrm/tests/activitystreams/test_activitystreams.py b/bookwyrm/tests/activitystreams/test_activitystreams.py deleted file mode 100644 index 4e91c5bea..000000000 --- a/bookwyrm/tests/activitystreams/test_activitystreams.py +++ /dev/null @@ -1,292 +0,0 @@ -""" testing activitystreams """ -from unittest.mock import patch -from django.test import TestCase -from bookwyrm import activitystreams, models - - -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") -@patch("bookwyrm.activitystreams.add_status_task.delay") -@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") -@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") -@patch("bookwyrm.activitystreams.populate_stream_task.delay") -# pylint: disable=too-many-public-methods -class Activitystreams(TestCase): - """using redis to build activity streams""" - - def setUp(self): - """use a test csv""" - with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( - "bookwyrm.activitystreams.populate_stream_task.delay" - ): - self.local_user = models.User.objects.create_user( - "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" - ) - self.another_user = models.User.objects.create_user( - "nutria", - "nutria@nutria.nutria", - "password", - local=True, - localname="nutria", - ) - with patch("bookwyrm.models.user.set_remote_server.delay"): - 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", - ) - work = models.Work.objects.create(title="test work") - self.book = models.Edition.objects.create(title="test book", parent_work=work) - - class TestStream(activitystreams.ActivityStream): - """test stream, don't have to do anything here""" - - key = "test" - - self.test_stream = TestStream() - - def test_activitystream_class_ids(self, *_): - """the abstract base class for stream objects""" - self.assertEqual( - self.test_stream.stream_id(self.local_user), - "{}-test".format(self.local_user.id), - ) - self.assertEqual( - self.test_stream.unread_id(self.local_user), - "{}-test-unread".format(self.local_user.id), - ) - - def test_abstractstream_get_audience(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, content="hi", privacy="public" - ) - users = self.test_stream.get_audience(status) - # remote users don't have feeds - self.assertFalse(self.remote_user in users) - self.assertTrue(self.local_user in users) - self.assertTrue(self.another_user in users) - - def test_abstractstream_get_audience_direct(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, - content="hi", - privacy="direct", - ) - status.mention_users.add(self.local_user) - users = self.test_stream.get_audience(status) - self.assertEqual(users, []) - - status = models.Comment.objects.create( - user=self.remote_user, - content="hi", - privacy="direct", - book=self.book, - ) - status.mention_users.add(self.local_user) - users = self.test_stream.get_audience(status) - self.assertTrue(self.local_user in users) - self.assertFalse(self.another_user in users) - self.assertFalse(self.remote_user in users) - - def test_abstractstream_get_audience_followers_remote_user(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, - content="hi", - privacy="followers", - ) - users = self.test_stream.get_audience(status) - self.assertFalse(users.exists()) - - def test_abstractstream_get_audience_followers_self(self, *_): - """get a list of users that should see a status""" - status = models.Comment.objects.create( - user=self.local_user, - content="hi", - privacy="direct", - book=self.book, - ) - users = self.test_stream.get_audience(status) - self.assertTrue(self.local_user in users) - self.assertFalse(self.another_user in users) - self.assertFalse(self.remote_user in users) - - def test_abstractstream_get_audience_followers_with_mention(self, *_): - """get a list of users that should see a status""" - status = models.Comment.objects.create( - user=self.remote_user, - content="hi", - privacy="direct", - book=self.book, - ) - status.mention_users.add(self.local_user) - - users = self.test_stream.get_audience(status) - self.assertTrue(self.local_user in users) - self.assertFalse(self.another_user in users) - self.assertFalse(self.remote_user in users) - - def test_abstractstream_get_audience_followers_with_relationship(self, *_): - """get a list of users that should see a status""" - self.remote_user.followers.add(self.local_user) - status = models.Comment.objects.create( - user=self.remote_user, - content="hi", - privacy="direct", - book=self.book, - ) - users = self.test_stream.get_audience(status) - self.assertFalse(self.local_user in users) - self.assertFalse(self.another_user in users) - self.assertFalse(self.remote_user in users) - - def test_homestream_get_audience(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, content="hi", privacy="public" - ) - users = activitystreams.HomeStream().get_audience(status) - self.assertFalse(users.exists()) - - def test_homestream_get_audience_with_mentions(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, content="hi", privacy="public" - ) - status.mention_users.add(self.local_user) - users = activitystreams.HomeStream().get_audience(status) - self.assertFalse(self.local_user in users) - self.assertFalse(self.another_user in users) - - def test_homestream_get_audience_with_relationship(self, *_): - """get a list of users that should see a status""" - self.remote_user.followers.add(self.local_user) - status = models.Status.objects.create( - user=self.remote_user, content="hi", privacy="public" - ) - users = activitystreams.HomeStream().get_audience(status) - self.assertTrue(self.local_user in users) - self.assertFalse(self.another_user in users) - - def test_localstream_get_audience_remote_status(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.remote_user, content="hi", privacy="public" - ) - users = activitystreams.LocalStream().get_audience(status) - self.assertEqual(users, []) - - def test_localstream_get_audience_local_status(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.local_user, content="hi", privacy="public" - ) - users = activitystreams.LocalStream().get_audience(status) - self.assertTrue(self.local_user in users) - self.assertTrue(self.another_user in users) - - def test_localstream_get_audience_unlisted(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.local_user, content="hi", privacy="unlisted" - ) - users = activitystreams.LocalStream().get_audience(status) - self.assertEqual(users, []) - - def test_localstream_get_audience_books_no_book(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.local_user, content="hi", privacy="public" - ) - audience = activitystreams.BooksStream().get_audience(status) - # no books, no audience - self.assertEqual(audience, []) - - def test_localstream_get_audience_books_mention_books(self, *_): - """get a list of users that should see a status""" - status = models.Status.objects.create( - user=self.local_user, content="hi", privacy="public" - ) - status.mention_books.add(self.book) - status.save(broadcast=False) - models.ShelfBook.objects.create( - user=self.local_user, - shelf=self.local_user.shelf_set.first(), - book=self.book, - ) - # yes book, yes audience - audience = activitystreams.BooksStream().get_audience(status) - self.assertTrue(self.local_user in audience) - - def test_localstream_get_audience_books_book_field(self, *_): - """get a list of users that should see a status""" - status = models.Comment.objects.create( - user=self.local_user, content="hi", privacy="public", book=self.book - ) - models.ShelfBook.objects.create( - user=self.local_user, - shelf=self.local_user.shelf_set.first(), - book=self.book, - ) - # yes book, yes audience - audience = activitystreams.BooksStream().get_audience(status) - self.assertTrue(self.local_user in audience) - - def test_localstream_get_audience_books_alternate_edition(self, *_): - """get a list of users that should see a status""" - alt_book = models.Edition.objects.create( - title="hi", parent_work=self.book.parent_work - ) - status = models.Comment.objects.create( - user=self.remote_user, content="hi", privacy="public", book=alt_book - ) - models.ShelfBook.objects.create( - user=self.local_user, - shelf=self.local_user.shelf_set.first(), - book=self.book, - ) - # yes book, yes audience - audience = activitystreams.BooksStream().get_audience(status) - self.assertTrue(self.local_user in audience) - - def test_localstream_get_audience_books_non_public(self, *_): - """get a list of users that should see a status""" - alt_book = models.Edition.objects.create( - title="hi", parent_work=self.book.parent_work - ) - status = models.Comment.objects.create( - user=self.remote_user, content="hi", privacy="unlisted", book=alt_book - ) - models.ShelfBook.objects.create( - user=self.local_user, - shelf=self.local_user.shelf_set.first(), - book=self.book, - ) - # yes book, yes audience - audience = activitystreams.BooksStream().get_audience(status) - self.assertEqual(audience, []) - - def test_get_statuses_for_user_books(self, *_): - """create a stream for a user""" - alt_book = models.Edition.objects.create( - title="hi", parent_work=self.book.parent_work - ) - status = models.Status.objects.create( - user=self.local_user, content="hi", privacy="public" - ) - status = models.Comment.objects.create( - user=self.remote_user, content="hi", privacy="public", book=alt_book - ) - models.ShelfBook.objects.create( - user=self.local_user, - shelf=self.local_user.shelf_set.first(), - book=self.book, - ) - # yes book, yes audience - result = activitystreams.BooksStream().get_statuses_for_user(self.local_user) - self.assertEqual(list(result), [status]) diff --git a/bookwyrm/tests/activitystreams/test_booksstream.py b/bookwyrm/tests/activitystreams/test_booksstream.py new file mode 100644 index 000000000..5730dccf7 --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_booksstream.py @@ -0,0 +1,55 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.activitystreams.add_status_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +class Activitystreams(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + with patch("bookwyrm.models.user.set_remote_server.delay"): + 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", + ) + work = models.Work.objects.create(title="test work") + self.book = models.Edition.objects.create(title="test book", parent_work=work) + + + def test_get_statuses_for_user_books(self, *_): + """create a stream for a user""" + alt_book = models.Edition.objects.create( + title="hi", parent_work=self.book.parent_work + ) + status = models.Status.objects.create( + user=self.local_user, content="hi", privacy="public" + ) + status = models.Comment.objects.create( + user=self.remote_user, content="hi", privacy="public", book=alt_book + ) + models.ShelfBook.objects.create( + user=self.local_user, + shelf=self.local_user.shelf_set.first(), + book=self.book, + ) + # yes book, yes audience + result = activitystreams.BooksStream().get_statuses_for_user(self.local_user) + self.assertEqual(list(result), [status]) diff --git a/bookwyrm/tests/activitystreams/test_homestream.py b/bookwyrm/tests/activitystreams/test_homestream.py new file mode 100644 index 000000000..42a73f3cf --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_homestream.py @@ -0,0 +1,67 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.activitystreams.add_status_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +class Activitystreams(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + self.another_user = models.User.objects.create_user( + "nutria", + "nutria@nutria.nutria", + "password", + local=True, + localname="nutria", + ) + with patch("bookwyrm.models.user.set_remote_server.delay"): + 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", + ) + + def test_homestream_get_audience(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + users = activitystreams.HomeStream().get_audience(status) + self.assertFalse(users.exists()) + + def test_homestream_get_audience_with_mentions(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + status.mention_users.add(self.local_user) + users = activitystreams.HomeStream().get_audience(status) + self.assertFalse(self.local_user in users) + self.assertFalse(self.another_user in users) + + def test_homestream_get_audience_with_relationship(self, *_): + """get a list of users that should see a status""" + self.remote_user.followers.add(self.local_user) + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + users = activitystreams.HomeStream().get_audience(status) + self.assertTrue(self.local_user in users) + self.assertFalse(self.another_user in users) diff --git a/bookwyrm/tests/activitystreams/test_localstream.py b/bookwyrm/tests/activitystreams/test_localstream.py new file mode 100644 index 000000000..e6b05557f --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_localstream.py @@ -0,0 +1,139 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.activitystreams.add_status_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +class Activitystreams(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + self.another_user = models.User.objects.create_user( + "nutria", + "nutria@nutria.nutria", + "password", + local=True, + localname="nutria", + ) + with patch("bookwyrm.models.user.set_remote_server.delay"): + 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", + ) + work = models.Work.objects.create(title="test work") + self.book = models.Edition.objects.create(title="test book", parent_work=work) + + def test_localstream_get_audience_remote_status(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + users = activitystreams.LocalStream().get_audience(status) + self.assertEqual(users, []) + + def test_localstream_get_audience_local_status(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.local_user, content="hi", privacy="public" + ) + users = activitystreams.LocalStream().get_audience(status) + self.assertTrue(self.local_user in users) + self.assertTrue(self.another_user in users) + + def test_localstream_get_audience_unlisted(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.local_user, content="hi", privacy="unlisted" + ) + users = activitystreams.LocalStream().get_audience(status) + self.assertEqual(users, []) + + def test_localstream_get_audience_books_no_book(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.local_user, content="hi", privacy="public" + ) + audience = activitystreams.BooksStream().get_audience(status) + # no books, no audience + self.assertEqual(audience, []) + + def test_localstream_get_audience_books_mention_books(self, *_): + """get a list of users that should see a status""" + status = models.Status.objects.create( + user=self.local_user, content="hi", privacy="public" + ) + status.mention_books.add(self.book) + status.save(broadcast=False) + models.ShelfBook.objects.create( + user=self.local_user, + shelf=self.local_user.shelf_set.first(), + book=self.book, + ) + # yes book, yes audience + audience = activitystreams.BooksStream().get_audience(status) + self.assertTrue(self.local_user in audience) + + def test_localstream_get_audience_books_book_field(self, *_): + """get a list of users that should see a status""" + status = models.Comment.objects.create( + user=self.local_user, content="hi", privacy="public", book=self.book + ) + models.ShelfBook.objects.create( + user=self.local_user, + shelf=self.local_user.shelf_set.first(), + book=self.book, + ) + # yes book, yes audience + audience = activitystreams.BooksStream().get_audience(status) + self.assertTrue(self.local_user in audience) + + def test_localstream_get_audience_books_alternate_edition(self, *_): + """get a list of users that should see a status""" + alt_book = models.Edition.objects.create( + title="hi", parent_work=self.book.parent_work + ) + status = models.Comment.objects.create( + user=self.remote_user, content="hi", privacy="public", book=alt_book + ) + models.ShelfBook.objects.create( + user=self.local_user, + shelf=self.local_user.shelf_set.first(), + book=self.book, + ) + # yes book, yes audience + audience = activitystreams.BooksStream().get_audience(status) + self.assertTrue(self.local_user in audience) + + def test_localstream_get_audience_books_non_public(self, *_): + """get a list of users that should see a status""" + alt_book = models.Edition.objects.create( + title="hi", parent_work=self.book.parent_work + ) + status = models.Comment.objects.create( + user=self.remote_user, content="hi", privacy="unlisted", book=alt_book + ) + models.ShelfBook.objects.create( + user=self.local_user, + shelf=self.local_user.shelf_set.first(), + book=self.book, + ) + # yes book, yes audience + audience = activitystreams.BooksStream().get_audience(status) + self.assertEqual(audience, []) diff --git a/bookwyrm/tests/activitystreams/test_activitystreams_tasks.py b/bookwyrm/tests/activitystreams/test_tasks.py similarity index 100% rename from bookwyrm/tests/activitystreams/test_activitystreams_tasks.py rename to bookwyrm/tests/activitystreams/test_tasks.py From 82ad1abe9aa9a7a3be5c7501557249db578f2f3e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 11:53:41 -0700 Subject: [PATCH 4/7] more activitystreams tests --- .../tests/activitystreams/test_signals.py | 69 +++++++++++++++++++ bookwyrm/tests/activitystreams/test_tasks.py | 6 +- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/tests/activitystreams/test_signals.py diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py new file mode 100644 index 000000000..ef1ac97c9 --- /dev/null +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -0,0 +1,69 @@ +""" testing activitystreams """ +from unittest.mock import patch +from django.test import TestCase +from bookwyrm import activitystreams, models + + +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +class ActivitystreamsSignals(TestCase): + """using redis to build activity streams""" + + def setUp(self): + """use a test csv""" + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True, localname="mouse" + ) + with patch("bookwyrm.models.user.set_remote_server.delay"): + 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", + ) + work = models.Work.objects.create(title="test work") + self.book = models.Edition.objects.create(title="test book", parent_work=work) + + + def test_add_status_on_create_ignore(self, _): + """a new statuses has entered""" + activitystreams.add_status_on_create(models.User, self.local_user, False) + + def test_add_status_on_create_deleted(self, _): + """a new statuses has entered""" + with patch("bookwyrm.activitystreams.remove_status_task.delay"): + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public", deleted=True + ) + with patch("bookwyrm.activitystreams.remove_status_task.delay") as mock: + activitystreams.add_status_on_create(models.Status, status, False) + self.assertEqual(mock.call_count, 1) + args = mock.call_args[0] + self.assertEqual(args[0], status.id) + + def test_add_status_on_create_created(self, _): + """a new statuses has entered""" + status = models.Status.objects.create( + user=self.remote_user, content="hi", privacy="public" + ) + with patch("bookwyrm.activitystreams.add_status_task.delay") as mock: + activitystreams.add_status_on_create_command(models.Status, status, False) + self.assertEqual(mock.call_count, 1) + args = mock.call_args[0] + self.assertEqual(args[0], status.id) + + def test_populate_streams_on_account_create(self): + """create streams for a user""" + with patch("bookwyrm.activitystreams.populate_stream_task") as mock: + activitystreams.populate_streams_on_account_create( + models.User, self.local_user, True + ) + self.assertEqual(mock.call_count, 3) + args = mock.call_args[0] + self.assertEqual(args[0], "home") + self.assertEqual(args[1], self.local_user.id) diff --git a/bookwyrm/tests/activitystreams/test_tasks.py b/bookwyrm/tests/activitystreams/test_tasks.py index a51549ca6..287bf6bc0 100644 --- a/bookwyrm/tests/activitystreams/test_tasks.py +++ b/bookwyrm/tests/activitystreams/test_tasks.py @@ -24,7 +24,8 @@ class Activitystreams(TestCase): ) work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) - self.status = models.Status.objects.create(content="hi", user=self.local_user) + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + self.status = models.Status.objects.create(content="hi", user=self.local_user) def test_add_book_statuses_task(self): """statuses related to a book""" @@ -120,6 +121,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") def test_boost_to_another_timeline(self, *_): """add a boost and deduplicate the boosted status on the timeline""" status = models.Status.objects.create(user=self.local_user, content="hi") @@ -142,6 +144,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") def test_boost_to_following_timeline(self, *_): """add a boost and deduplicate the boosted status on the timeline""" self.local_user.following.add(self.another_user) @@ -167,6 +170,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") def test_boost_to_same_timeline(self, *_): """add a boost and deduplicate the boosted status on the timeline""" status = models.Status.objects.create(user=self.local_user, content="hi") From b717c2fcd81dc594f943b63345d7800f6b12676a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 11:57:18 -0700 Subject: [PATCH 5/7] Fixes mock arg on test --- bookwyrm/tests/activitystreams/test_signals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py index ef1ac97c9..ed5b4a169 100644 --- a/bookwyrm/tests/activitystreams/test_signals.py +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -57,7 +57,7 @@ class ActivitystreamsSignals(TestCase): args = mock.call_args[0] self.assertEqual(args[0], status.id) - def test_populate_streams_on_account_create(self): + def test_populate_streams_on_account_create(self, _): """create streams for a user""" with patch("bookwyrm.activitystreams.populate_stream_task") as mock: activitystreams.populate_streams_on_account_create( From 6bc4bf45038eca21b23ff9c7bb7b6d170b1d0417 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 12:02:29 -0700 Subject: [PATCH 6/7] Fixes mock --- bookwyrm/tests/activitystreams/test_signals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py index ed5b4a169..2cf26edd4 100644 --- a/bookwyrm/tests/activitystreams/test_signals.py +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -59,7 +59,7 @@ class ActivitystreamsSignals(TestCase): def test_populate_streams_on_account_create(self, _): """create streams for a user""" - with patch("bookwyrm.activitystreams.populate_stream_task") as mock: + with patch("bookwyrm.activitystreams.populate_stream_task.delay") as mock: activitystreams.populate_streams_on_account_create( models.User, self.local_user, True ) From da3bc1e59160b0f3bd2bb3e5ae6de166c7dc84ba Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 12:05:34 -0700 Subject: [PATCH 7/7] Python formatting --- bookwyrm/tests/activitystreams/test_booksstream.py | 1 - bookwyrm/tests/activitystreams/test_signals.py | 3 +-- bookwyrm/tests/activitystreams/test_tasks.py | 4 +++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bookwyrm/tests/activitystreams/test_booksstream.py b/bookwyrm/tests/activitystreams/test_booksstream.py index 5730dccf7..d6d94b738 100644 --- a/bookwyrm/tests/activitystreams/test_booksstream.py +++ b/bookwyrm/tests/activitystreams/test_booksstream.py @@ -33,7 +33,6 @@ class Activitystreams(TestCase): work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) - def test_get_statuses_for_user_books(self, *_): """create a stream for a user""" alt_book = models.Edition.objects.create( diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py index 2cf26edd4..1c94cc9f5 100644 --- a/bookwyrm/tests/activitystreams/test_signals.py +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -29,7 +29,6 @@ class ActivitystreamsSignals(TestCase): work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) - def test_add_status_on_create_ignore(self, _): """a new statuses has entered""" activitystreams.add_status_on_create(models.User, self.local_user, False) @@ -65,5 +64,5 @@ class ActivitystreamsSignals(TestCase): ) self.assertEqual(mock.call_count, 3) args = mock.call_args[0] - self.assertEqual(args[0], "home") + self.assertEqual(args[0], "books") self.assertEqual(args[1], self.local_user.id) diff --git a/bookwyrm/tests/activitystreams/test_tasks.py b/bookwyrm/tests/activitystreams/test_tasks.py index 287bf6bc0..f4c85e1bf 100644 --- a/bookwyrm/tests/activitystreams/test_tasks.py +++ b/bookwyrm/tests/activitystreams/test_tasks.py @@ -25,7 +25,9 @@ class Activitystreams(TestCase): work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - self.status = models.Status.objects.create(content="hi", user=self.local_user) + self.status = models.Status.objects.create( + content="hi", user=self.local_user + ) def test_add_book_statuses_task(self): """statuses related to a book"""