Handle poll votes
authorrinpatch <rinpatch@sdf.org>
Tue, 21 May 2019 11:12:10 +0000 (14:12 +0300)
committerrinpatch <rinpatch@sdf.org>
Tue, 21 May 2019 11:12:10 +0000 (14:12 +0300)
lib/pleroma/object.ex
lib/pleroma/web/activity_pub/activity_pub.ex
test/fixtures/mastodon-vote.json [new file with mode: 0644]
test/web/activity_pub/transmogrifier_test.exs

index 740d687a3505fc03ea0cc2161aa44bba4a5f8872..a0f7659eb18f2dbfc7686d2b314293a3f0c406bb 100644 (file)
@@ -188,4 +188,34 @@ defmodule Pleroma.Object do
       _ -> {:error, "Not found"}
     end
   end
+
+  def increase_vote_count(ap_id, name) do
+    with %Object{} = object <- Object.normalize(ap_id),
+         "Question" <- object.data["type"] do
+      multiple = Map.has_key?(object.data, "anyOf")
+
+      options =
+        (object.data["anyOf"] || object.data["oneOf"] || [])
+        |> Enum.map(fn
+          %{"name" => ^name} = option ->
+            Kernel.update_in(option["replies"]["totalItems"], &(&1 + 1))
+
+          option ->
+            option
+        end)
+
+      data =
+        if multiple do
+          Map.put(object.data, "anyOf", options)
+        else
+          Map.put(object.data, "oneOf", options)
+        end
+
+      object
+      |> Object.change(%{data: data})
+      |> update_and_set_cache()
+    else
+      _ -> :noop
+    end
+  end
 end
index 035fb75d58a423b34a5af50bb6f58ba31521e074..ce78d895bf9107ec39de7b4bcd474e4b864bf249 100644 (file)
@@ -108,6 +108,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
 
   def decrease_replies_count_if_reply(_object), do: :noop
 
+  def increase_poll_votes_if_vote(%{
+        "object" => %{"inReplyTo" => reply_ap_id, "name" => name},
+        "type" => "Create"
+      }) do
+    Object.increase_vote_count(reply_ap_id, name)
+  end
+
+  def increase_poll_votes_if_vote(_create_data), do: :noop
+
   def insert(map, local \\ true, fake \\ false) when is_map(map) do
     with nil <- Activity.normalize(map),
          map <- lazy_put_activity_defaults(map, fake),
@@ -235,6 +244,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
          {:ok, activity} <- insert(create_data, local, fake),
          {:fake, false, activity} <- {:fake, fake, activity},
          _ <- increase_replies_count_if_reply(create_data),
+         _ <- increase_poll_votes_if_vote(create_data),
          # Changing note count prior to enqueuing federation task in order to avoid
          # race conditions on updating user.info
          {:ok, _actor} <- increase_note_count_if_public(actor, activity),
diff --git a/test/fixtures/mastodon-vote.json b/test/fixtures/mastodon-vote.json
new file mode 100644 (file)
index 0000000..c2c5f40
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "@context": "https://www.w3.org/ns/activitystreams",
+  "actor": "https://mastodon.sdf.org/users/rinpatch",
+  "id": "https://mastodon.sdf.org/users/rinpatch#votes/387/activity",
+  "nickname": "rin",
+  "object": {
+    "attributedTo": "https://mastodon.sdf.org/users/rinpatch",
+    "id": "https://mastodon.sdf.org/users/rinpatch#votes/387",
+    "inReplyTo": "https://testing.uguu.ltd/objects/9d300947-2dcb-445d-8978-9a3b4b84fa14",
+    "name": "suya..",
+    "to": "https://testing.uguu.ltd/users/rin",
+    "type": "Note"
+  },
+  "to": "https://testing.uguu.ltd/users/rin",
+  "type": "Create"
+}
index 727abbd17c7f50f82aa162a816a5299fc6617c38..32d94e3e9123e46db406a9ba1c719e8c3093cae1 100644 (file)
@@ -130,6 +130,37 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
              end)
     end
 
+    test "in increments vote counters on question activities" do
+      user = insert(:user)
+
+      {:ok, activity} =
+        CommonAPI.post(user, %{
+          "status" => "suya...",
+          "poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10}
+        })
+
+      object = Object.normalize(activity)
+
+      data =
+        File.read!("test/fixtures/mastodon-vote.json")
+        |> Poison.decode!()
+        |> Kernel.put_in(["to"], user.ap_id)
+        |> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
+        |> Kernel.put_in(["object", "to"], user.ap_id)
+
+      {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
+
+      object = Object.get_by_ap_id(object.data["id"])
+
+      assert Enum.any?(
+               object.data["oneOf"],
+               fn
+                 %{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
+                 _ -> false
+               end
+             )
+    end
+
     test "it works for incoming notices with contentMap" do
       data =
         File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()