Merge pull request #912 from mouse-reeve/collection-item-refacotr

Collection item refactor
This commit is contained in:
Mouse Reeve 2021-04-11 09:51:13 -07:00 committed by GitHub
commit 32e2bea52c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 354 additions and 352 deletions

View file

@ -10,6 +10,7 @@ from .note import Note, GeneratedNote, Article, Comment, Quotation
from .note import Review, Rating from .note import Review, Rating
from .note import Tombstone from .note import Tombstone
from .ordered_collection import OrderedCollection, OrderedCollectionPage from .ordered_collection import OrderedCollection, OrderedCollectionPage
from .ordered_collection import CollectionItem, ListItem, ShelfItem
from .ordered_collection import BookList, Shelf from .ordered_collection import BookList, Shelf
from .person import Person, PublicKey from .person import Person, PublicKey
from .response import ActivitypubResponse from .response import ActivitypubResponse

View file

@ -111,7 +111,7 @@ class ActivityObject:
and hasattr(model, "ignore_activity") and hasattr(model, "ignore_activity")
and model.ignore_activity(self) and model.ignore_activity(self)
): ):
raise ActivitySerializerError() return None
# check for an existing instance # check for an existing instance
instance = instance or model.find_existing(self.serialize()) instance = instance or model.find_existing(self.serialize())

View file

@ -50,3 +50,30 @@ class OrderedCollectionPage(ActivityObject):
next: str = None next: str = None
prev: str = None prev: str = None
type: str = "OrderedCollectionPage" type: str = "OrderedCollectionPage"
@dataclass(init=False)
class CollectionItem(ActivityObject):
""" an item in a collection """
actor: str
type: str = "CollectionItem"
@dataclass(init=False)
class ListItem(CollectionItem):
""" a book on a list """
book: str
notes: str = None
approved: bool = True
order: int = None
type: str = "ListItem"
@dataclass(init=False)
class ShelfItem(CollectionItem):
""" a book on a list """
book: str
type: str = "ShelfItem"

View file

@ -4,7 +4,7 @@ from typing import List
from django.apps import apps from django.apps import apps
from .base_activity import ActivityObject, Signature, resolve_remote_id from .base_activity import ActivityObject, Signature, resolve_remote_id
from .book import Edition from .ordered_collection import CollectionItem
@dataclass(init=False) @dataclass(init=False)
@ -141,37 +141,27 @@ class Reject(Verb):
class Add(Verb): class Add(Verb):
"""Add activity """ """Add activity """
target: str target: ActivityObject
object: Edition object: CollectionItem
type: str = "Add" type: str = "Add"
notes: str = None
order: int = 0
approved: bool = True
def action(self): def action(self):
""" add obj to collection """ """ figure out the target to assign the item to a collection """
target = resolve_remote_id(self.target, refresh=False) target = resolve_remote_id(self.target)
# we want to get the related field that isn't the book, this is janky af sorry item = self.object.to_model(save=False)
model = [t for t in type(target)._meta.related_objects if t.name != "edition"][ setattr(item, item.collection_field, target)
0 item.save()
].related_model
self.to_model(model=model)
@dataclass(init=False) @dataclass(init=False)
class Remove(Verb): class Remove(Add):
"""Remove activity """ """Remove activity """
target: ActivityObject
type: str = "Remove" type: str = "Remove"
def action(self): def action(self):
""" find and remove the activity object """ """ find and remove the activity object """
target = resolve_remote_id(self.target, refresh=False) obj = self.object.to_model(save=False, allow_create=False)
model = [t for t in type(target)._meta.related_objects if t.name != "edition"][
0
].related_model
obj = self.to_model(model=model, save=False, allow_create=False)
obj.delete() obj.delete()

View file

@ -0,0 +1,28 @@
# Generated by Django 3.1.6 on 2021-04-08 22:08
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0063_auto_20210408_1556"),
]
operations = [
migrations.AlterField(
model_name="listitem",
name="book_list",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to="bookwyrm.list"
),
),
migrations.AlterField(
model_name="shelfbook",
name="shelf",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to="bookwyrm.shelf"
),
),
]

View file

@ -64,6 +64,7 @@ class ActivitypubMixin:
) )
if hasattr(self, "property_fields"): if hasattr(self, "property_fields"):
self.activity_fields += [ self.activity_fields += [
# pylint: disable=cell-var-from-loop
PropertyField(lambda a, o: set_activity_from_property_field(a, o, f)) PropertyField(lambda a, o: set_activity_from_property_field(a, o, f))
for f in self.property_fields for f in self.property_fields
] ]
@ -356,49 +357,59 @@ class OrderedCollectionMixin(OrderedCollectionPageMixin):
class CollectionItemMixin(ActivitypubMixin): class CollectionItemMixin(ActivitypubMixin):
""" for items that are part of an (Ordered)Collection """ """ for items that are part of an (Ordered)Collection """
activity_serializer = activitypub.Add activity_serializer = activitypub.CollectionItem
object_field = collection_field = None
@property
def privacy(self):
""" inherit the privacy of the list, or direct if pending """
collection_field = getattr(self, self.collection_field)
if self.approved:
return collection_field.privacy
return "direct"
@property
def recipients(self):
""" the owner of the list is a direct recipient """
collection_field = getattr(self, self.collection_field)
return [collection_field.user]
def save(self, *args, broadcast=True, **kwargs): def save(self, *args, broadcast=True, **kwargs):
""" broadcast updated """ """ broadcast updated """
created = not bool(self.id)
# first off, we want to save normally no matter what # first off, we want to save normally no matter what
super().save(*args, **kwargs) super().save(*args, **kwargs)
# these shouldn't be edited, only created and deleted # list items can be updateda, normally you would only broadcast on created
if not broadcast or not created or not self.user.local: if not broadcast or not self.user.local:
return return
# adding an obj to the collection # adding an obj to the collection
activity = self.to_add_activity() activity = self.to_add_activity(self.user)
self.broadcast(activity, self.user) self.broadcast(activity, self.user)
def delete(self, *args, **kwargs): def delete(self, *args, broadcast=True, **kwargs):
""" broadcast a remove activity """ """ broadcast a remove activity """
activity = self.to_remove_activity() activity = self.to_remove_activity(self.user)
super().delete(*args, **kwargs) super().delete(*args, **kwargs)
if self.user.local: if self.user.local and broadcast:
self.broadcast(activity, self.user) self.broadcast(activity, self.user)
def to_add_activity(self): def to_add_activity(self, user):
""" AP for shelving a book""" """ AP for shelving a book"""
object_field = getattr(self, self.object_field)
collection_field = getattr(self, self.collection_field) collection_field = getattr(self, self.collection_field)
return activitypub.Add( return activitypub.Add(
id=self.get_remote_id(), id="{:s}#add".format(collection_field.remote_id),
actor=self.user.remote_id, actor=user.remote_id,
object=object_field, object=self.to_activity_dataclass(),
target=collection_field.remote_id, target=collection_field.remote_id,
).serialize() ).serialize()
def to_remove_activity(self): def to_remove_activity(self, user):
""" AP for un-shelving a book""" """ AP for un-shelving a book"""
object_field = getattr(self, self.object_field)
collection_field = getattr(self, self.collection_field) collection_field = getattr(self, self.collection_field)
return activitypub.Remove( return activitypub.Remove(
id=self.get_remote_id(), id="{:s}#remove".format(collection_field.remote_id),
actor=self.user.remote_id, actor=user.remote_id,
object=object_field, object=self.to_activity_dataclass(),
target=collection_field.remote_id, target=collection_field.remote_id,
).serialize() ).serialize()

View file

@ -59,11 +59,9 @@ class ListItem(CollectionItemMixin, BookWyrmModel):
""" ok """ """ ok """
book = fields.ForeignKey( book = fields.ForeignKey(
"Edition", on_delete=models.PROTECT, activitypub_field="object" "Edition", on_delete=models.PROTECT, activitypub_field="book"
)
book_list = fields.ForeignKey(
"List", on_delete=models.CASCADE, activitypub_field="target"
) )
book_list = models.ForeignKey("List", on_delete=models.CASCADE)
user = fields.ForeignKey( user = fields.ForeignKey(
"User", on_delete=models.PROTECT, activitypub_field="actor" "User", on_delete=models.PROTECT, activitypub_field="actor"
) )
@ -72,8 +70,7 @@ class ListItem(CollectionItemMixin, BookWyrmModel):
order = fields.IntegerField(blank=True, null=True) order = fields.IntegerField(blank=True, null=True)
endorsement = models.ManyToManyField("User", related_name="endorsers") endorsement = models.ManyToManyField("User", related_name="endorsers")
activity_serializer = activitypub.Add activity_serializer = activitypub.ListItem
object_field = "book"
collection_field = "book_list" collection_field = "book_list"
def save(self, *args, **kwargs): def save(self, *args, **kwargs):

View file

@ -66,17 +66,14 @@ class ShelfBook(CollectionItemMixin, BookWyrmModel):
""" many to many join table for books and shelves """ """ many to many join table for books and shelves """
book = fields.ForeignKey( book = fields.ForeignKey(
"Edition", on_delete=models.PROTECT, activitypub_field="object" "Edition", on_delete=models.PROTECT, activitypub_field="book"
)
shelf = fields.ForeignKey(
"Shelf", on_delete=models.PROTECT, activitypub_field="target"
) )
shelf = models.ForeignKey("Shelf", on_delete=models.PROTECT)
user = fields.ForeignKey( user = fields.ForeignKey(
"User", on_delete=models.PROTECT, activitypub_field="actor" "User", on_delete=models.PROTECT, activitypub_field="actor"
) )
activity_serializer = activitypub.Add activity_serializer = activitypub.ShelfItem
object_field = "book"
collection_field = "shelf" collection_field = "shelf"
def save(self, *args, **kwargs): def save(self, *args, **kwargs):

View file

@ -11,45 +11,64 @@ class List(TestCase):
def setUp(self): def setUp(self):
""" look, a list """ """ look, a list """
self.user = models.User.objects.create_user( self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse" "mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
) )
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): work = models.Work.objects.create(title="hello")
self.list = models.List.objects.create(name="Test List", user=self.user) self.book = models.Edition.objects.create(title="hi", parent_work=work)
def test_remote_id(self, _): def test_remote_id(self, _):
""" shelves use custom remote ids """ """ shelves use custom remote ids """
expected_id = "https://%s/list/%d" % (settings.DOMAIN, self.list.id) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
self.assertEqual(self.list.get_remote_id(), expected_id) book_list = models.List.objects.create(
name="Test List", user=self.local_user
)
expected_id = "https://%s/list/%d" % (settings.DOMAIN, book_list.id)
self.assertEqual(book_list.get_remote_id(), expected_id)
def test_to_activity(self, _): def test_to_activity(self, _):
""" jsonify it """ """ jsonify it """
activity_json = self.list.to_activity() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
book_list = models.List.objects.create(
name="Test List", user=self.local_user
)
activity_json = book_list.to_activity()
self.assertIsInstance(activity_json, dict) self.assertIsInstance(activity_json, dict)
self.assertEqual(activity_json["id"], self.list.remote_id) self.assertEqual(activity_json["id"], book_list.remote_id)
self.assertEqual(activity_json["totalItems"], 0) self.assertEqual(activity_json["totalItems"], 0)
self.assertEqual(activity_json["type"], "BookList") self.assertEqual(activity_json["type"], "BookList")
self.assertEqual(activity_json["name"], "Test List") self.assertEqual(activity_json["name"], "Test List")
self.assertEqual(activity_json["owner"], self.user.remote_id) self.assertEqual(activity_json["owner"], self.local_user.remote_id)
def test_list_item(self, _): def test_list_item(self, _):
""" a list entry """ """ a list entry """
work = models.Work.objects.create(title="hello") with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
book = models.Edition.objects.create(title="hi", parent_work=work) book_list = models.List.objects.create(
name="Test List", user=self.local_user, privacy="unlisted"
)
item = models.ListItem.objects.create( item = models.ListItem.objects.create(
book_list=self.list, book_list=book_list,
book=book, book=self.book,
user=self.user, user=self.local_user,
) )
self.assertTrue(item.approved) self.assertTrue(item.approved)
self.assertEqual(item.privacy, "unlisted")
self.assertEqual(item.recipients, [self.local_user])
add_activity = item.to_add_activity() def test_list_item_pending(self, _):
self.assertEqual(add_activity["actor"], self.user.remote_id) """ a list entry """
self.assertEqual(add_activity["object"]["id"], book.remote_id) with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
self.assertEqual(add_activity["target"], self.list.remote_id) book_list = models.List.objects.create(
name="Test List", user=self.local_user
)
remove_activity = item.to_remove_activity() item = models.ListItem.objects.create(
self.assertEqual(remove_activity["actor"], self.user.remote_id) book_list=book_list, book=self.book, user=self.local_user, approved=False
self.assertEqual(remove_activity["object"]["id"], book.remote_id) )
self.assertEqual(remove_activity["target"], self.list.remote_id)
self.assertFalse(item.approved)
self.assertEqual(item.book_list.privacy, "public")
self.assertEqual(item.privacy, "direct")
self.assertEqual(item.recipients, [self.local_user])

View file

@ -1,4 +1,6 @@
""" testing models """ """ testing models """
import json
from unittest.mock import patch
from django.test import TestCase from django.test import TestCase
from bookwyrm import models, settings from bookwyrm import models, settings
@ -18,27 +20,16 @@ class Shelf(TestCase):
def test_remote_id(self): def test_remote_id(self):
""" shelves use custom remote ids """ """ shelves use custom remote ids """
real_broadcast = models.Shelf.broadcast with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
def broadcast_mock(_, activity, user, **kwargs):
""" nah """
models.Shelf.broadcast = broadcast_mock
shelf = models.Shelf.objects.create( shelf = models.Shelf.objects.create(
name="Test Shelf", identifier="test-shelf", user=self.local_user name="Test Shelf", identifier="test-shelf", user=self.local_user
) )
expected_id = "https://%s/user/mouse/books/test-shelf" % settings.DOMAIN expected_id = "https://%s/user/mouse/books/test-shelf" % settings.DOMAIN
self.assertEqual(shelf.get_remote_id(), expected_id) self.assertEqual(shelf.get_remote_id(), expected_id)
models.Shelf.broadcast = real_broadcast
def test_to_activity(self): def test_to_activity(self):
""" jsonify it """ """ jsonify it """
real_broadcast = models.Shelf.broadcast with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
def empty_mock(_, activity, user, **kwargs):
""" nah """
models.Shelf.broadcast = empty_mock
shelf = models.Shelf.objects.create( shelf = models.Shelf.objects.create(
name="Test Shelf", identifier="test-shelf", user=self.local_user name="Test Shelf", identifier="test-shelf", user=self.local_user
) )
@ -49,77 +40,53 @@ class Shelf(TestCase):
self.assertEqual(activity_json["type"], "Shelf") self.assertEqual(activity_json["type"], "Shelf")
self.assertEqual(activity_json["name"], "Test Shelf") self.assertEqual(activity_json["name"], "Test Shelf")
self.assertEqual(activity_json["owner"], self.local_user.remote_id) self.assertEqual(activity_json["owner"], self.local_user.remote_id)
models.Shelf.broadcast = real_broadcast
def test_create_update_shelf(self): def test_create_update_shelf(self):
""" create and broadcast shelf creation """ """ create and broadcast shelf creation """
real_broadcast = models.Shelf.broadcast
def create_mock(_, activity, user, **kwargs): with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
""" ok """ shelf = models.Shelf.objects.create(
self.assertEqual(user.remote_id, self.local_user.remote_id) name="Test Shelf", identifier="test-shelf", user=self.local_user
)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Create") self.assertEqual(activity["type"], "Create")
self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["name"], "Test Shelf") self.assertEqual(activity["object"]["name"], "Test Shelf")
models.Shelf.broadcast = create_mock shelf.name = "arthur russel"
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
shelf = models.Shelf.objects.create( shelf.save()
name="Test Shelf", identifier="test-shelf", user=self.local_user activity = json.loads(mock.call_args[0][1])
)
def update_mock(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Update") self.assertEqual(activity["type"], "Update")
self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["name"], "arthur russel") self.assertEqual(activity["object"]["name"], "arthur russel")
models.Shelf.broadcast = update_mock
shelf.name = "arthur russel"
shelf.save()
self.assertEqual(shelf.name, "arthur russel") self.assertEqual(shelf.name, "arthur russel")
models.Shelf.broadcast = real_broadcast
def test_shelve(self): def test_shelve(self):
""" create and broadcast shelf creation """ """ create and broadcast shelf creation """
real_broadcast = models.Shelf.broadcast with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
real_shelfbook_broadcast = models.ShelfBook.broadcast
def add_mock(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], self.book.remote_id)
self.assertEqual(activity["target"], shelf.remote_id)
def remove_mock(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Remove")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], self.book.remote_id)
self.assertEqual(activity["target"], shelf.remote_id)
def empty_mock(_, activity, user, **kwargs):
""" nah """
models.Shelf.broadcast = empty_mock
shelf = models.Shelf.objects.create( shelf = models.Shelf.objects.create(
name="Test Shelf", identifier="test-shelf", user=self.local_user name="Test Shelf", identifier="test-shelf", user=self.local_user
) )
models.ShelfBook.broadcast = add_mock with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
shelf_book = models.ShelfBook.objects.create( shelf_book = models.ShelfBook.objects.create(
shelf=shelf, user=self.local_user, book=self.book shelf=shelf, user=self.local_user, book=self.book
) )
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], shelf_book.remote_id)
self.assertEqual(activity["target"], shelf.remote_id)
self.assertEqual(shelf.books.first(), self.book) self.assertEqual(shelf.books.first(), self.book)
models.ShelfBook.broadcast = remove_mock with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
shelf_book.delete() shelf_book.delete()
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Remove")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], shelf_book.remote_id)
self.assertEqual(activity["target"], shelf.remote_id)
self.assertFalse(shelf.books.exists()) self.assertFalse(shelf.books.exists())
models.ShelfBook.broadcast = real_shelfbook_broadcast
models.Shelf.broadcast = real_broadcast

View file

@ -8,20 +8,20 @@ from bookwyrm import models, views
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
class InboxActivities(TestCase): class InboxAdd(TestCase):
""" inbox tests """ """ inbox tests """
def setUp(self): def setUp(self):
""" basic user and book data """ """ basic user and book data """
self.local_user = models.User.objects.create_user( local_user = models.User.objects.create_user(
"mouse@example.com", "mouse@example.com",
"mouse@mouse.com", "mouse@mouse.com",
"mouseword", "mouseword",
local=True, local=True,
localname="mouse", localname="mouse",
) )
self.local_user.remote_id = "https://example.com/user/mouse" local_user.remote_id = "https://example.com/user/mouse"
self.local_user.save(broadcast=False) local_user.save(broadcast=False)
with patch("bookwyrm.models.user.set_remote_server.delay"): with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user( self.remote_user = models.User.objects.create_user(
"rat", "rat",
@ -32,17 +32,17 @@ class InboxActivities(TestCase):
inbox="https://example.com/users/rat/inbox", inbox="https://example.com/users/rat/inbox",
outbox="https://example.com/users/rat/outbox", outbox="https://example.com/users/rat/outbox",
) )
work = models.Work.objects.create(title="work title")
self.book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=work,
)
models.SiteSettings.objects.create() models.SiteSettings.objects.create()
def test_handle_add_book_to_shelf(self): def test_handle_add_book_to_shelf(self):
""" shelving a book """ """ shelving a book """
work = models.Work.objects.create(title="work title")
book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=work,
)
shelf = models.Shelf.objects.create(user=self.remote_user, name="Test Shelf") shelf = models.Shelf.objects.create(user=self.remote_user, name="Test Shelf")
shelf.remote_id = "https://bookwyrm.social/user/mouse/shelf/to-read" shelf.remote_id = "https://bookwyrm.social/user/mouse/shelf/to-read"
shelf.save() shelf.save()
@ -52,27 +52,20 @@ class InboxActivities(TestCase):
"type": "Add", "type": "Add",
"actor": "https://example.com/users/rat", "actor": "https://example.com/users/rat",
"object": { "object": {
"type": "Edition", "actor": self.remote_user.remote_id,
"title": "Test Title", "type": "ShelfItem",
"work": work.remote_id, "book": self.book.remote_id,
"id": "https://bookwyrm.social/book/37292", "id": "https://bookwyrm.social/shelfbook/6189",
}, },
"target": "https://bookwyrm.social/user/mouse/shelf/to-read", "target": "https://bookwyrm.social/user/mouse/shelf/to-read",
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
} }
views.inbox.activity_task(activity) views.inbox.activity_task(activity)
self.assertEqual(shelf.books.first(), book) self.assertEqual(shelf.books.first(), self.book)
@responses.activate @responses.activate
def test_handle_add_book_to_list(self): def test_handle_add_book_to_list(self):
""" listing a book """ """ listing a book """
work = models.Work.objects.create(title="work title")
book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=work,
)
responses.add( responses.add(
responses.GET, responses.GET,
"https://bookwyrm.social/user/mouse/list/to-read", "https://bookwyrm.social/user/mouse/list/to-read",
@ -97,10 +90,10 @@ class InboxActivities(TestCase):
"type": "Add", "type": "Add",
"actor": "https://example.com/users/rat", "actor": "https://example.com/users/rat",
"object": { "object": {
"type": "Edition", "actor": self.remote_user.remote_id,
"title": "Test Title", "type": "ListItem",
"work": work.remote_id, "book": self.book.remote_id,
"id": "https://bookwyrm.social/book/37292", "id": "https://bookwyrm.social/listbook/6189",
}, },
"target": "https://bookwyrm.social/user/mouse/list/to-read", "target": "https://bookwyrm.social/user/mouse/list/to-read",
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
@ -108,49 +101,7 @@ class InboxActivities(TestCase):
views.inbox.activity_task(activity) views.inbox.activity_task(activity)
booklist = models.List.objects.get() booklist = models.List.objects.get()
listitem = models.ListItem.objects.get()
self.assertEqual(booklist.name, "Test List") self.assertEqual(booklist.name, "Test List")
self.assertEqual(booklist.books.first(), book) self.assertEqual(booklist.books.first(), self.book)
self.assertEqual(listitem.remote_id, "https://bookwyrm.social/listbook/6189")
@responses.activate
def test_handle_tag_book(self):
""" listing a book """
work = models.Work.objects.create(title="work title")
book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=work,
)
responses.add(
responses.GET,
"https://www.example.com/tag/cool-tag",
json={
"id": "https://1b1a78582461.ngrok.io/tag/tag",
"type": "OrderedCollection",
"totalItems": 0,
"first": "https://1b1a78582461.ngrok.io/tag/tag?page=1",
"last": "https://1b1a78582461.ngrok.io/tag/tag?page=1",
"name": "cool tag",
"@context": "https://www.w3.org/ns/activitystreams",
},
)
activity = {
"id": "https://bookwyrm.social/listbook/6189#add",
"type": "Add",
"actor": "https://example.com/users/rat",
"object": {
"type": "Edition",
"title": "Test Title",
"work": work.remote_id,
"id": "https://bookwyrm.social/book/37292",
},
"target": "https://www.example.com/tag/cool-tag",
"@context": "https://www.w3.org/ns/activitystreams",
}
views.inbox.activity_task(activity)
tag = models.Tag.objects.get()
self.assertFalse(models.List.objects.exists())
self.assertEqual(tag.name, "cool tag")
self.assertEqual(tag.books.first(), book)

View file

@ -136,6 +136,9 @@ class InboxActivities(TestCase):
"id": "http://www.faraway.com/boost/12", "id": "http://www.faraway.com/boost/12",
"actor": self.remote_user.remote_id, "actor": self.remote_user.remote_id,
"object": status.remote_id, "object": status.remote_id,
"to": ["https://www.w3.org/ns/activitystreams#public"],
"cc": ["https://example.com/user/mouse/followers"],
"published": "Mon, 25 May 2020 19:31:20 GMT",
} }
responses.add( responses.add(
responses.GET, status.remote_id, json=status.to_activity(), status=200 responses.GET, status.remote_id, json=status.to_activity(), status=200
@ -185,6 +188,7 @@ class InboxActivities(TestCase):
"id": "http://fake.com/unknown/boost", "id": "http://fake.com/unknown/boost",
"actor": self.remote_user.remote_id, "actor": self.remote_user.remote_id,
"object": self.status.remote_id, "object": self.status.remote_id,
"published": "Mon, 25 May 2020 19:31:20 GMT",
}, },
} }
views.inbox.activity_task(activity) views.inbox.activity_task(activity)

View file

@ -9,7 +9,7 @@ from bookwyrm import models, views
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
class InboxActivities(TestCase): class InboxCreate(TestCase):
""" readthrough tests """ """ readthrough tests """
def setUp(self): def setUp(self):

View file

@ -7,11 +7,20 @@ from bookwyrm import models, views
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
class InboxActivities(TestCase): class InboxRemove(TestCase):
""" inbox tests """ """ inbox tests """
def setUp(self): def setUp(self):
""" basic user and book data """ """ basic user and book data """
self.local_user = models.User.objects.create_user(
"mouse@example.com",
"mouse@mouse.com",
"mouseword",
local=True,
localname="mouse",
)
self.local_user.remote_id = "https://example.com/user/mouse"
self.local_user.save(broadcast=False)
with patch("bookwyrm.models.user.set_remote_server.delay"): with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user( self.remote_user = models.User.objects.create_user(
"rat", "rat",
@ -22,26 +31,26 @@ class InboxActivities(TestCase):
inbox="https://example.com/users/rat/inbox", inbox="https://example.com/users/rat/inbox",
outbox="https://example.com/users/rat/outbox", outbox="https://example.com/users/rat/outbox",
) )
self.work = models.Work.objects.create(title="work title")
self.book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=self.work,
)
models.SiteSettings.objects.create() models.SiteSettings.objects.create()
def test_handle_unshelve_book(self): def test_handle_unshelve_book(self):
""" remove a book from a shelf """ """ remove a book from a shelf """
work = models.Work.objects.create(title="work title")
book = models.Edition.objects.create(
title="Test",
remote_id="https://bookwyrm.social/book/37292",
parent_work=work,
)
shelf = models.Shelf.objects.create(user=self.remote_user, name="Test Shelf") shelf = models.Shelf.objects.create(user=self.remote_user, name="Test Shelf")
shelf.remote_id = "https://bookwyrm.social/user/mouse/shelf/to-read" shelf.remote_id = "https://bookwyrm.social/user/mouse/shelf/to-read"
shelf.save() shelf.save()
shelfbook = models.ShelfBook.objects.create( shelfbook = models.ShelfBook.objects.create(
user=self.remote_user, shelf=shelf, book=book user=self.remote_user, shelf=shelf, book=self.book
) )
self.assertEqual(shelf.books.first(), book) self.assertEqual(shelf.books.first(), self.book)
self.assertEqual(shelf.books.count(), 1) self.assertEqual(shelf.books.count(), 1)
activity = { activity = {
@ -49,13 +58,44 @@ class InboxActivities(TestCase):
"type": "Remove", "type": "Remove",
"actor": "https://example.com/users/rat", "actor": "https://example.com/users/rat",
"object": { "object": {
"type": "Edition", "actor": self.remote_user.remote_id,
"title": "Test Title", "type": "ShelfItem",
"work": work.remote_id, "book": self.book.remote_id,
"id": "https://bookwyrm.social/book/37292", "id": shelfbook.remote_id,
}, },
"target": "https://bookwyrm.social/user/mouse/shelf/to-read", "target": "https://bookwyrm.social/user/mouse/shelf/to-read",
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
} }
views.inbox.activity_task(activity) views.inbox.activity_task(activity)
self.assertFalse(shelf.books.exists()) self.assertFalse(shelf.books.exists())
def test_handle_remove_book_from_list(self):
""" listing a book """
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
booklist = models.List.objects.create(
name="test list",
user=self.local_user,
)
listitem = models.ListItem.objects.create(
user=self.local_user,
book=self.book,
book_list=booklist,
)
self.assertEqual(booklist.books.count(), 1)
activity = {
"id": listitem.remote_id,
"type": "Remove",
"actor": "https://example.com/users/rat",
"object": {
"actor": self.remote_user.remote_id,
"type": "ListItem",
"book": self.book.remote_id,
"id": listitem.remote_id,
},
"target": booklist.remote_id,
"@context": "https://www.w3.org/ns/activitystreams",
}
views.inbox.activity_task(activity)
self.assertEqual(booklist.books.count(), 0)

View file

@ -1,4 +1,5 @@
""" test for app action functionality """ """ test for app action functionality """
import json
from unittest.mock import patch from unittest.mock import patch
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
@ -71,16 +72,6 @@ class ListViews(TestCase):
def test_lists_create(self): def test_lists_create(self):
""" create list view """ """ create list view """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Create")
self.assertEqual(activity["actor"], self.local_user.remote_id)
models.List.broadcast = mock_broadcast
view = views.Lists.as_view() view = views.Lists.as_view()
request = self.factory.post( request = self.factory.post(
"", "",
@ -93,13 +84,19 @@ class ListViews(TestCase):
}, },
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
result = view(request) result = view(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Create")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
new_list = models.List.objects.filter(name="A list").get() new_list = models.List.objects.filter(name="A list").get()
self.assertEqual(new_list.description, "wow") self.assertEqual(new_list.description, "wow")
self.assertEqual(new_list.privacy, "unlisted") self.assertEqual(new_list.privacy, "unlisted")
self.assertEqual(new_list.curation, "open") self.assertEqual(new_list.curation, "open")
models.List.broadcast = real_broadcast
def test_list_page(self): def test_list_page(self):
""" there are so many views, this just makes sure it LOADS """ """ there are so many views, this just makes sure it LOADS """
@ -138,17 +135,6 @@ class ListViews(TestCase):
def test_list_edit(self): def test_list_edit(self):
""" edit a list """ """ edit a list """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Update")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], self.list.remote_id)
models.List.broadcast = mock_broadcast
view = views.List.as_view() view = views.List.as_view()
request = self.factory.post( request = self.factory.post(
"", "",
@ -162,7 +148,15 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
result = view(request, self.list.id) result = view(request, self.list.id)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Update")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], self.list.remote_id)
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
self.list.refresh_from_db() self.list.refresh_from_db()
@ -170,7 +164,6 @@ class ListViews(TestCase):
self.assertEqual(self.list.description, "wow") self.assertEqual(self.list.description, "wow")
self.assertEqual(self.list.privacy, "direct") self.assertEqual(self.list.privacy, "direct")
self.assertEqual(self.list.curation, "curated") self.assertEqual(self.list.curation, "curated")
models.List.broadcast = real_broadcast
def test_curate_page(self): def test_curate_page(self):
""" there are so many views, this just makes sure it LOADS """ """ there are so many views, this just makes sure it LOADS """
@ -194,17 +187,6 @@ class ListViews(TestCase):
def test_curate_approve(self): def test_curate_approve(self):
""" approve a pending item """ """ approve a pending item """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user, **kwargs):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
models.ListItem.broadcast = mock_broadcast
view = views.Curate.as_view() view = views.Curate.as_view()
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
pending = models.ListItem.objects.create( pending = models.ListItem.objects.create(
@ -223,12 +205,19 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
view(request, self.list.id) view(request, self.list.id)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
pending.refresh_from_db() pending.refresh_from_db()
self.assertEqual(self.list.books.count(), 1) self.assertEqual(self.list.books.count(), 1)
self.assertEqual(self.list.listitem_set.first(), pending) self.assertEqual(self.list.listitem_set.first(), pending)
self.assertTrue(pending.approved) self.assertTrue(pending.approved)
models.ListItem.broadcast = real_broadcast
def test_curate_reject(self): def test_curate_reject(self):
""" approve a pending item """ """ approve a pending item """
@ -250,23 +239,13 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
view(request, self.list.id) view(request, self.list.id)
self.assertFalse(self.list.books.exists()) self.assertFalse(self.list.books.exists())
self.assertFalse(models.ListItem.objects.exists()) self.assertFalse(models.ListItem.objects.exists())
def test_add_book(self): def test_add_book(self):
""" put a book on a list """ """ put a book on a list """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
models.ListItem.broadcast = mock_broadcast
request = self.factory.post( request = self.factory.post(
"", "",
{ {
@ -276,25 +255,21 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.list.add_book(request) views.list.add_book(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
item = self.list.listitem_set.get() item = self.list.listitem_set.get()
self.assertEqual(item.book, self.book) self.assertEqual(item.book, self.book)
self.assertEqual(item.user, self.local_user) self.assertEqual(item.user, self.local_user)
self.assertTrue(item.approved) self.assertTrue(item.approved)
models.ListItem.broadcast = real_broadcast
def test_add_book_outsider(self): def test_add_book_outsider(self):
""" put a book on a list """ """ put a book on a list """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user):
""" ok """
self.assertEqual(user.remote_id, self.rat.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.rat.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
models.ListItem.broadcast = mock_broadcast
self.list.curation = "open" self.list.curation = "open"
self.list.save(broadcast=False) self.list.save(broadcast=False)
request = self.factory.post( request = self.factory.post(
@ -306,26 +281,21 @@ class ListViews(TestCase):
) )
request.user = self.rat request.user = self.rat
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.list.add_book(request) views.list.add_book(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.rat.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
item = self.list.listitem_set.get() item = self.list.listitem_set.get()
self.assertEqual(item.book, self.book) self.assertEqual(item.book, self.book)
self.assertEqual(item.user, self.rat) self.assertEqual(item.user, self.rat)
self.assertTrue(item.approved) self.assertTrue(item.approved)
models.ListItem.broadcast = real_broadcast
def test_add_book_pending(self): def test_add_book_pending(self):
""" put a book on a list awaiting approval """ """ put a book on a list awaiting approval """
real_broadcast = models.List.broadcast
def mock_broadcast(_, activity, user):
""" ok """
self.assertEqual(user.remote_id, self.rat.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.rat.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
self.assertEqual(activity["object"]["id"], self.book.remote_id)
models.ListItem.broadcast = mock_broadcast
self.list.curation = "curated" self.list.curation = "curated"
self.list.save(broadcast=False) self.list.save(broadcast=False)
request = self.factory.post( request = self.factory.post(
@ -337,26 +307,25 @@ class ListViews(TestCase):
) )
request.user = self.rat request.user = self.rat
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.list.add_book(request) views.list.add_book(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.rat.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
item = self.list.listitem_set.get() item = self.list.listitem_set.get()
self.assertEqual(activity["object"]["id"], item.remote_id)
self.assertEqual(item.book, self.book) self.assertEqual(item.book, self.book)
self.assertEqual(item.user, self.rat) self.assertEqual(item.user, self.rat)
self.assertFalse(item.approved) self.assertFalse(item.approved)
models.ListItem.broadcast = real_broadcast
def test_add_book_self_curated(self): def test_add_book_self_curated(self):
""" put a book on a list automatically approved """ """ put a book on a list automatically approved """
real_broadcast = models.ListItem.broadcast
def mock_broadcast(_, activity, user):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
models.ListItem.broadcast = mock_broadcast
self.list.curation = "curated" self.list.curation = "curated"
self.list.save(broadcast=False) self.list.save(broadcast=False)
request = self.factory.post( request = self.factory.post(
@ -368,16 +337,21 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.list.add_book(request) views.list.add_book(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
item = self.list.listitem_set.get() item = self.list.listitem_set.get()
self.assertEqual(item.book, self.book) self.assertEqual(item.book, self.book)
self.assertEqual(item.user, self.local_user) self.assertEqual(item.user, self.local_user)
self.assertTrue(item.approved) self.assertTrue(item.approved)
models.ListItem.broadcast = real_broadcast
def test_remove_book(self): def test_remove_book(self):
""" take an item off a list """ """ take an item off a list """
real_broadcast = models.ListItem.broadcast
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
item = models.ListItem.objects.create( item = models.ListItem.objects.create(
@ -387,14 +361,6 @@ class ListViews(TestCase):
) )
self.assertTrue(self.list.listitem_set.exists()) self.assertTrue(self.list.listitem_set.exists())
def mock_broadcast(_, activity, user):
""" ok """
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Remove")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["target"], self.list.remote_id)
models.ListItem.broadcast = mock_broadcast
request = self.factory.post( request = self.factory.post(
"", "",
{ {
@ -403,10 +369,9 @@ class ListViews(TestCase):
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
views.list.remove_book(request, self.list.id) views.list.remove_book(request, self.list.id)
self.assertFalse(self.list.listitem_set.exists()) self.assertFalse(self.list.listitem_set.exists())
models.ListItem.broadcast = real_broadcast
def test_remove_book_unauthorized(self): def test_remove_book_unauthorized(self):
""" take an item off a list """ """ take an item off a list """
@ -426,5 +391,4 @@ class ListViews(TestCase):
request.user = self.rat request.user = self.rat
views.list.remove_book(request, self.list.id) views.list.remove_book(request, self.list.id)
self.assertTrue(self.list.listitem_set.exists()) self.assertTrue(self.list.listitem_set.exists())

View file

@ -1,4 +1,5 @@
""" test for app action functionality """ """ test for app action functionality """
import json
from unittest.mock import patch from unittest.mock import patch
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
@ -120,8 +121,15 @@ class ShelfViews(TestCase):
"", {"book": self.book.id, "shelf": self.shelf.identifier} "", {"book": self.book.id, "shelf": self.shelf.identifier}
) )
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.shelve(request) views.shelve(request)
self.assertEqual(mock.call_count, 1)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Add")
item = models.ShelfBook.objects.get()
self.assertEqual(activity["object"]["id"], item.remote_id)
# make sure the book is on the shelf # make sure the book is on the shelf
self.assertEqual(self.shelf.books.get(), self.book) self.assertEqual(self.shelf.books.get(), self.book)
@ -170,10 +178,15 @@ class ShelfViews(TestCase):
models.ShelfBook.objects.create( models.ShelfBook.objects.create(
book=self.book, user=self.local_user, shelf=self.shelf book=self.book, user=self.local_user, shelf=self.shelf
) )
item = models.ShelfBook.objects.get()
self.shelf.save() self.shelf.save()
self.assertEqual(self.shelf.books.count(), 1) self.assertEqual(self.shelf.books.count(), 1)
request = self.factory.post("", {"book": self.book.id, "shelf": self.shelf.id}) request = self.factory.post("", {"book": self.book.id, "shelf": self.shelf.id})
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
views.unshelve(request) views.unshelve(request)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Remove")
self.assertEqual(activity["object"]["id"], item.remote_id)
self.assertEqual(self.shelf.books.count(), 0) self.assertEqual(self.shelf.books.count(), 0)

View file

@ -58,18 +58,11 @@ class Inbox(View):
def activity_task(activity_json): def activity_task(activity_json):
""" do something with this json we think is legit """ """ do something with this json we think is legit """
# lets see if the activitypub module can make sense of this json # lets see if the activitypub module can make sense of this json
try:
activity = activitypub.parse(activity_json) activity = activitypub.parse(activity_json)
except activitypub.ActivitySerializerError:
return
# cool that worked, now we should do the action described by the type # cool that worked, now we should do the action described by the type
# (create, update, delete, etc) # (create, update, delete, etc)
try:
activity.action() activity.action()
except activitypub.ActivitySerializerError:
# this is raised if the activity is discarded
return
def has_valid_signature(request, activity): def has_valid_signature(request, activity):

View file

@ -168,7 +168,7 @@ class Curate(View):
suggestion.approved = True suggestion.approved = True
suggestion.save() suggestion.save()
else: else:
suggestion.delete() suggestion.delete(broadcast=False)
return redirect("list-curate", book_list.id) return redirect("list-curate", book_list.id)