Repository: bookwyrm-social/bookwyrm

Issue:
Book context missing in boosts from remote posts
**Describe the bug**
In some cases, a post federates and the associated book is not shown.

**Screenshots**
Screenshot from a review where the associated book is not shown. It's a remote post and the booster is on another instance as well.
![image](https://user-images.githubusercontent.com/66644064/113485135-74cfe700-94ac-11eb-9217-cfa510bb52e2.png)

Screenshot from the original instance with the book
![image](https://user-images.githubusercontent.com/66644064/113485156-992bc380-94ac-11eb-93c0-eb9a3b8ccc09.png)

Screenshots from the federated tl where the remote review is there once with book, once without.
![image](https://user-images.githubusercontent.com/66644064/113485238-d6905100-94ac-11eb-99ff-d64f84c6133e.png)

**Additional context**
Will post more matching posts. In other cases, it works properly - it may be that it works if the OP is followed from my instance so the post is already known but not enough examples yet.


Discussion:
That's not good! It looks like boosted are being received in "pure" mode intended for non-bookwyrm services, which could be a problem on either side of the transaction. I'll look further.

Resolving patch:
diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py
--- a/bookwyrm/activitypub/base_activity.py
+++ b/bookwyrm/activitypub/base_activity.py
@@ -265,7 +265,8 @@ def resolve_remote_id(
             "Could not connect to host for remote_id in: %s" % (remote_id)
         )
     # determine the model implicitly, if not provided
-    if not model:
+    # or if it's a model with subclasses like Status, check again
+    if not model or hasattr(model.objects, "select_subclasses"):
         model = get_model_from_type(data.get("type"))
 
     # check for existing items with shared unique identifiers


Test patch:
diff --git a/bookwyrm/tests/views/test_inbox.py b/bookwyrm/tests/views/test_inbox.py
--- a/bookwyrm/tests/views/test_inbox.py
+++ b/bookwyrm/tests/views/test_inbox.py
@@ -572,6 +572,56 @@ def test_handle_boost(self, _):
         self.assertEqual(notification.user, self.local_user)
         self.assertEqual(notification.related_status, self.status)
 
+    @responses.activate
+    @patch("bookwyrm.activitystreams.ActivityStream.add_status")
+    def test_handle_boost_remote_status(self, redis_mock):
+        """ boost a status """
+        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,
+        )
+        self.assertEqual(models.Notification.objects.count(), 0)
+        activity = {
+            "type": "Announce",
+            "id": "%s/boost" % self.status.remote_id,
+            "actor": self.remote_user.remote_id,
+            "object": "https://remote.com/status/1",
+            "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.GET,
+            "https://remote.com/status/1",
+            json={
+                "id": "https://remote.com/status/1",
+                "type": "Comment",
+                "published": "2021-04-05T18:04:59.735190+00:00",
+                "attributedTo": self.remote_user.remote_id,
+                "content": "<p>a comment</p>",
+                "to": ["https://www.w3.org/ns/activitystreams#Public"],
+                "cc": ["https://b875df3d118b.ngrok.io/user/mouse/followers"],
+                "inReplyTo": "",
+                "inReplyToBook": book.remote_id,
+                "summary": "",
+                "tag": [],
+                "sensitive": False,
+                "@context": "https://www.w3.org/ns/activitystreams",
+            },
+        )
+
+        with patch("bookwyrm.models.status.Status.ignore_activity") as discarder:
+            discarder.return_value = False
+            views.inbox.activity_task(activity)
+            self.assertTrue(redis_mock.called)
+
+        boost = models.Boost.objects.get()
+        self.assertEqual(boost.boosted_status.remote_id, "https://remote.com/status/1")
+        self.assertEqual(boost.boosted_status.comment.status_type, "Comment")
+        self.assertEqual(boost.boosted_status.comment.book, book)
+
     @responses.activate
     def test_handle_discarded_boost(self):
         """ test a boost of a mastodon status that will be discarded """