Normalize poll votes to Answer objects
authorrinpatch <rinpatch@sdf.org>
Wed, 22 May 2019 18:17:57 +0000 (21:17 +0300)
committerrinpatch <rinpatch@sdf.org>
Wed, 22 May 2019 18:17:57 +0000 (21:17 +0300)
lib/pleroma/web/activity_pub/activity_pub.ex
lib/pleroma/web/activity_pub/transmogrifier.ex
lib/pleroma/web/activity_pub/utils.ex
test/web/activity_pub/transmogrifier_test.exs

index fdebf1f6b515bc9501983eec2d79b8f4feaeeae0..5b3fb7e843f87f03b2e8016bc5d166a56e0693d8 100644 (file)
@@ -194,7 +194,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     if activity.data["type"] in ["Create", "Announce", "Delete"] do
       object = Object.normalize(activity)
       # Do not stream out poll replies
-      unless object.data["name"] do
+      unless object.data["type"] == "Answer" do
         Pleroma.Web.Streamer.stream("user", activity)
         Pleroma.Web.Streamer.stream("list", activity)
 
@@ -493,7 +493,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
     from(activity in Activity)
     |> restrict_blocked(opts)
-    |> restrict_poll_replies(opts)
     |> restrict_recipients(recipients, opts["user"])
     |> where(
       [activity],
@@ -833,16 +832,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   defp restrict_muted_reblogs(query, _), do: query
 
-  defp restrict_poll_replies(query, %{"include_poll_replies" => "true"}), do: query
-
-  defp restrict_poll_replies(query, _) do
-    if has_named_binding?(query, :object) do
-      from([activity, object: o] in query, where: fragment("?->'name' is null", o.data))
-    else
-      query
-    end
-  end
-
   defp maybe_preload_objects(query, %{"skip_preload" => true}), do: query
 
   defp maybe_preload_objects(query, _) do
@@ -896,7 +885,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
     |> restrict_pinned(opts)
     |> restrict_muted_reblogs(opts)
     |> Activity.restrict_deactivated_users()
-    |> restrict_poll_replies(opts)
   end
 
   def fetch_activities(recipients, opts \\ %{}) do
index 8b2427258947f7cfe6f84aead98084ef5c9924f9..70b467b3f1553bad84aa876aa888a1ef74f850dd 100644 (file)
@@ -35,6 +35,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     |> fix_likes
     |> fix_addressing
     |> fix_summary
+    |> fix_type
   end
 
   def fix_summary(%{"summary" => nil} = object) do
@@ -328,6 +329,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
 
   def fix_content_map(object), do: object
 
+  def fix_type(%{"inReplyTo" => reply_id} = object) when is_binary(reply_id) do
+    reply = Object.normalize(reply_id)
+
+    if reply.data["type"] == "Question" and object["name"] do
+      Map.put(object, "type", "Answer")
+    else
+      object
+    end
+  end
+
+  def fix_type(object), do: object
+
   defp mastodon_follow_hack(%{"id" => id, "actor" => follower_id}, followed) do
     with true <- id =~ "follows",
          %User{local: true} = follower <- User.get_cached_by_ap_id(follower_id),
@@ -398,7 +411,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
   # - tags
   # - emoji
   def handle_incoming(%{"type" => "Create", "object" => %{"type" => objtype} = object} = data)
-      when objtype in ["Article", "Note", "Video", "Page", "Question"] do
+      when objtype in ["Article", "Note", "Video", "Page", "Question", "Answer"] do
     actor = Containment.get_actor(data)
 
     data =
@@ -731,6 +744,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     |> set_reply_to_uri
     |> strip_internal_fields
     |> strip_internal_tags
+    |> set_type
   end
 
   #  @doc
@@ -895,6 +909,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
     Map.put(object, "sensitive", "nsfw" in tags)
   end
 
+  def set_type(%{"type" => "Answer"} = object) do
+    Map.put(object, "type", "Note")
+  end
+
+  def set_type(object), do: object
+
   def add_attributed_to(object) do
     attributed_to = object["attributedTo"] || object["actor"]
 
index 63454e3f70a1fda6567b9f5773ff435c5b348280..9646bbee9ec421aa97c99486a797fb1cfc011669 100644 (file)
@@ -19,7 +19,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
 
   require Logger
 
-  @supported_object_types ["Article", "Note", "Video", "Page", "Question"]
+  @supported_object_types ["Article", "Note", "Video", "Page", "Question", "Answer"]
   @supported_report_states ~w(open closed resolved)
   @valid_visibilities ~w(public unlisted private direct)
 
index 32d94e3e9123e46db406a9ba1c719e8c3093cae1..8422fc3d587c82d5d79e7291dc7aada910280abb 100644 (file)
@@ -130,7 +130,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
              end)
     end
 
-    test "in increments vote counters on question activities" do
+    test "it rewrites Note votes to Answers and increments vote counters on question activities" do
       user = insert(:user)
 
       {:ok, activity} =
@@ -148,8 +148,9 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
         |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
         |> Kernel.put_in(["object", "to"], user.ap_id)
 
-      {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
-
+      {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+      answer_object = Object.normalize(activity)
+      assert answer_object.data["type"] == "Answer"
       object = Object.get_by_ap_id(object.data["id"])
 
       assert Enum.any?(
@@ -1257,4 +1258,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
       {:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
     end
   end
+
+  test "Rewrites Answers to Notes" do
+    user = insert(:user)
+
+    {:ok, poll_activity} =
+      CommonAPI.post(user, %{
+        "status" => "suya...",
+        "poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10}
+      })
+
+    poll_object = Object.normalize(poll_activity)
+    # TODO: Replace with CommonAPI vote creation when implemented
+    data =
+      File.read!("test/fixtures/mastodon-vote.json")
+      |> Poison.decode!()
+      |> Kernel.put_in(["to"], user.ap_id)
+      |> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
+      |> Kernel.put_in(["object", "to"], user.ap_id)
+
+    {:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
+    {:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
+
+    assert data["object"]["type"] == "Note"
+  end
 end