Handle poll votes

This commit is contained in:
rinpatch 2019-05-21 14:12:10 +03:00
parent 3f96b3e4b8
commit aafe30d94e
4 changed files with 87 additions and 0 deletions

View File

@ -188,4 +188,34 @@ def decrease_replies_count(ap_id) 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

View File

@ -108,6 +108,15 @@ def decrease_replies_count_if_reply(%Object{
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 @@ def create(%{to: to, actor: actor, context: context, object: object} = params, f
{: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),

16
test/fixtures/mastodon-vote.json vendored Normal file
View File

@ -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"
}

View File

@ -130,6 +130,37 @@ test "it works for incoming questions" 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!()