aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--config/config.exs1
-rw-r--r--lib/pleroma/notification.ex81
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex7
-rw-r--r--lib/pleroma/web/activity_pub/side_effects.ex20
-rw-r--r--lib/pleroma/web/api_spec/operations/notification_operation.ex3
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/notification_controller.ex1
-rw-r--r--lib/pleroma/web/mastodon_api/views/notification_view.ex3
-rw-r--r--lib/pleroma/web/push/subscription.ex2
-rw-r--r--lib/pleroma/workers/poll_worker.ex45
-rw-r--r--priv/repo/migrations/20210717000000_add_poll_to_notifications_enum.exs49
-rw-r--r--test/pleroma/notification_test.exs13
-rw-r--r--test/pleroma/web/activity_pub/side_effects_test.exs24
-rw-r--r--test/pleroma/web/common_api_test.exs7
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs5
-rw-r--r--test/pleroma/web/mastodon_api/views/notification_view_test.exs21
-rw-r--r--test/support/factory.ex59
17 files changed, 314 insertions, 28 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e594f174..45a365505 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- AdminAPI: return `created_at` date with users.
- `AnalyzeMetadata` upload filter for extracting image/video attachment dimensions and generating blurhashes for images. Blurhashes for videos are not generated at this time.
- Attachment dimensions and blurhashes are federated when available.
+- Mastodon API: support `poll` notification.
- Pinned posts federation
### Fixed
diff --git a/config/config.exs b/config/config.exs
index b50c910b1..828fe0085 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -560,6 +560,7 @@ config :pleroma, Oban,
mailer: 10,
transmogrifier: 20,
scheduled_activities: 10,
+ poll_notifications: 10,
background: 5,
remote_fetcher: 2,
attachments_cleanup: 1,
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 7efbdc49a..32f13df69 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -72,6 +72,7 @@ defmodule Pleroma.Notification do
pleroma:emoji_reaction
pleroma:report
reblog
+ poll
}
def changeset(%Notification{} = notification, attrs) do
@@ -379,7 +380,7 @@ defmodule Pleroma.Notification do
notifications =
Enum.map(potential_receivers, fn user ->
do_send = do_send && user in enabled_receivers
- create_notification(activity, user, do_send)
+ create_notification(activity, user, do_send: do_send)
end)
|> Enum.reject(&is_nil/1)
@@ -435,15 +436,18 @@ defmodule Pleroma.Notification do
end
# TODO move to sql, too.
- def create_notification(%Activity{} = activity, %User{} = user, do_send \\ true) do
- unless skip?(activity, user) do
+ def create_notification(%Activity{} = activity, %User{} = user, opts \\ []) do
+ do_send = Keyword.get(opts, :do_send, true)
+ type = Keyword.get(opts, :type, type_from_activity(activity))
+
+ unless skip?(activity, user, opts) do
{:ok, %{notification: notification}} =
Multi.new()
|> Multi.insert(:notification, %Notification{
user_id: user.id,
activity: activity,
seen: mark_as_read?(activity, user),
- type: type_from_activity(activity)
+ type: type
})
|> Marker.multi_set_last_read_id(user, "notifications")
|> Repo.transaction()
@@ -457,6 +461,28 @@ defmodule Pleroma.Notification do
end
end
+ def create_poll_notifications(%Activity{} = activity) do
+ with %Object{data: %{"type" => "Question", "actor" => actor} = data} <-
+ Object.normalize(activity) do
+ voters =
+ case data do
+ %{"voters" => voters} when is_list(voters) -> voters
+ _ -> []
+ end
+
+ notifications =
+ Enum.reduce([actor | voters], [], fn ap_id, acc ->
+ with %User{local: true} = user <- User.get_by_ap_id(ap_id) do
+ [create_notification(activity, user, type: "poll") | acc]
+ else
+ _ -> acc
+ end
+ end)
+
+ {:ok, notifications}
+ end
+ end
+
@doc """
Returns a tuple with 2 elements:
{notification-enabled receivers, currently disabled receivers (blocking / [thread] muting)}
@@ -572,8 +598,10 @@ defmodule Pleroma.Notification do
Enum.uniq(ap_ids) -- thread_muter_ap_ids
end
- @spec skip?(Activity.t(), User.t()) :: boolean()
- def skip?(%Activity{} = activity, %User{} = user) do
+ def skip?(activity, user, opts \\ [])
+
+ @spec skip?(Activity.t(), User.t(), Keyword.t()) :: boolean()
+ def skip?(%Activity{} = activity, %User{} = user, opts) do
[
:self,
:invisible,
@@ -581,17 +609,21 @@ defmodule Pleroma.Notification do
:recently_followed,
:filtered
]
- |> Enum.find(&skip?(&1, activity, user))
+ |> Enum.find(&skip?(&1, activity, user, opts))
end
- def skip?(_, _), do: false
+ def skip?(_activity, _user, _opts), do: false
- @spec skip?(atom(), Activity.t(), User.t()) :: boolean()
- def skip?(:self, %Activity{} = activity, %User{} = user) do
- activity.data["actor"] == user.ap_id
+ @spec skip?(atom(), Activity.t(), User.t(), Keyword.t()) :: boolean()
+ def skip?(:self, %Activity{} = activity, %User{} = user, opts) do
+ cond do
+ opts[:type] == "poll" -> false
+ activity.data["actor"] == user.ap_id -> true
+ true -> false
+ end
end
- def skip?(:invisible, %Activity{} = activity, _) do
+ def skip?(:invisible, %Activity{} = activity, _user, _opts) do
actor = activity.data["actor"]
user = User.get_cached_by_ap_id(actor)
User.invisible?(user)
@@ -600,15 +632,27 @@ defmodule Pleroma.Notification do
def skip?(
:block_from_strangers,
%Activity{} = activity,
- %User{notification_settings: %{block_from_strangers: true}} = user
+ %User{notification_settings: %{block_from_strangers: true}} = user,
+ opts
) do
actor = activity.data["actor"]
follower = User.get_cached_by_ap_id(actor)
- !User.following?(follower, user)
+
+ cond do
+ opts[:type] == "poll" -> false
+ user.ap_id == actor -> false
+ !User.following?(follower, user) -> true
+ true -> false
+ end
end
# To do: consider defining recency in hours and checking FollowingRelationship with a single SQL
- def skip?(:recently_followed, %Activity{data: %{"type" => "Follow"}} = activity, %User{} = user) do
+ def skip?(
+ :recently_followed,
+ %Activity{data: %{"type" => "Follow"}} = activity,
+ %User{} = user,
+ _opts
+ ) do
actor = activity.data["actor"]
Notification.for_user(user)
@@ -618,9 +662,10 @@ defmodule Pleroma.Notification do
end)
end
- def skip?(:filtered, %{data: %{"type" => type}}, _) when type in ["Follow", "Move"], do: false
+ def skip?(:filtered, %{data: %{"type" => type}}, _user, _opts) when type in ["Follow", "Move"],
+ do: false
- def skip?(:filtered, activity, user) do
+ def skip?(:filtered, activity, user, _opts) do
object = Object.normalize(activity, fetch: false)
cond do
@@ -638,7 +683,7 @@ defmodule Pleroma.Notification do
end
end
- def skip?(_, _, _), do: false
+ def skip?(_type, _activity, _user, _opts), do: false
def mark_as_read?(activity, target_user) do
user = Activity.user_actor(activity)
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 4c29dda35..19961a4a5 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -25,6 +25,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
alias Pleroma.Web.Streamer
alias Pleroma.Web.WebFinger
alias Pleroma.Workers.BackgroundWorker
+ alias Pleroma.Workers.PollWorker
import Ecto.Query
import Pleroma.Web.ActivityPub.Utils
@@ -288,6 +289,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
{:quick_insert, false, activity} <- {:quick_insert, quick_insert?, activity},
{:ok, _actor} <- increase_note_count_if_public(actor, activity),
_ <- notify_and_stream(activity),
+ :ok <- maybe_schedule_poll_notifications(activity),
:ok <- maybe_federate(activity) do
{:ok, activity}
else
@@ -302,6 +304,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
end
+ defp maybe_schedule_poll_notifications(activity) do
+ PollWorker.schedule_poll_end(activity)
+ :ok
+ end
+
@spec listen(map()) :: {:ok, Activity.t()} | {:error, any()}
def listen(%{to: to, actor: actor, context: context, object: object} = params) do
additional = params[:additional] || %{}
diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex
index b0ec84ade..dda48ea5f 100644
--- a/lib/pleroma/web/activity_pub/side_effects.ex
+++ b/lib/pleroma/web/activity_pub/side_effects.ex
@@ -24,6 +24,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.Push
alias Pleroma.Web.Streamer
+ alias Pleroma.Workers.PollWorker
require Logger
@@ -195,7 +196,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
# - Set up notifications
@impl true
def handle(%{data: %{"type" => "Create"}} = activity, meta) do
- with {:ok, object, meta} <- handle_object_creation(meta[:object_data], meta),
+ with {:ok, object, meta} <- handle_object_creation(meta[:object_data], activity, meta),
%User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
{:ok, notifications} = Notification.create_notifications(activity, do_send: false)
{:ok, _user} = ActivityPub.increase_note_count_if_public(user, object)
@@ -389,7 +390,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
{:ok, object, meta}
end
- def handle_object_creation(%{"type" => "ChatMessage"} = object, meta) do
+ def handle_object_creation(%{"type" => "ChatMessage"} = object, _activity, meta) do
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
actor = User.get_cached_by_ap_id(object.data["actor"])
recipient = User.get_cached_by_ap_id(hd(object.data["to"]))
@@ -424,7 +425,14 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
end
end
- def handle_object_creation(%{"type" => "Answer"} = object_map, meta) do
+ def handle_object_creation(%{"type" => "Question"} = object, activity, meta) do
+ with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
+ PollWorker.schedule_poll_end(activity)
+ {:ok, object, meta}
+ end
+ end
+
+ def handle_object_creation(%{"type" => "Answer"} = object_map, _activity, meta) do
with {:ok, object, meta} <- Pipeline.common_pipeline(object_map, meta) do
Object.increase_vote_count(
object.data["inReplyTo"],
@@ -436,15 +444,15 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
end
end
- def handle_object_creation(%{"type" => objtype} = object, meta)
- when objtype in ~w[Audio Video Question Event Article Note Page] do
+ def handle_object_creation(%{"type" => objtype} = object, _activity, meta)
+ when objtype in ~w[Audio Video Event Article Note Page] do
with {:ok, object, meta} <- Pipeline.common_pipeline(object, meta) do
{:ok, object, meta}
end
end
# Nothing to do
- def handle_object_creation(object, meta) do
+ def handle_object_creation(object, _activity, meta) do
{:ok, object, meta}
end
diff --git a/lib/pleroma/web/api_spec/operations/notification_operation.ex b/lib/pleroma/web/api_spec/operations/notification_operation.ex
index ec88eabe1..e4ce42f1c 100644
--- a/lib/pleroma/web/api_spec/operations/notification_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/notification_operation.ex
@@ -195,7 +195,8 @@ defmodule Pleroma.Web.ApiSpec.NotificationOperation do
"pleroma:chat_mention",
"pleroma:report",
"move",
- "follow_request"
+ "follow_request",
+ "poll"
],
description: """
The type of event that resulted in the notification.
diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
index 647ba661e..002d6b2ce 100644
--- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
@@ -50,6 +50,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
favourite
move
pleroma:emoji_reaction
+ poll
}
def index(%{assigns: %{user: user}} = conn, params) do
params =
diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex
index df9bedfed..35c636d4e 100644
--- a/lib/pleroma/web/mastodon_api/views/notification_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex
@@ -112,6 +112,9 @@ defmodule Pleroma.Web.MastodonAPI.NotificationView do
"move" ->
put_target(response, activity, reading_user, %{})
+ "poll" ->
+ put_status(response, activity, reading_user, status_render_opts)
+
"pleroma:emoji_reaction" ->
response
|> put_status(parent_activity_fn.(), reading_user, status_render_opts)
diff --git a/lib/pleroma/web/push/subscription.ex b/lib/pleroma/web/push/subscription.ex
index 4f6c9bc9f..35bf2e223 100644
--- a/lib/pleroma/web/push/subscription.ex
+++ b/lib/pleroma/web/push/subscription.ex
@@ -26,7 +26,7 @@ defmodule Pleroma.Web.Push.Subscription do
end
# credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
- @supported_alert_types ~w[follow favourite mention reblog pleroma:chat_mention pleroma:emoji_reaction]a
+ @supported_alert_types ~w[follow favourite mention reblog poll pleroma:chat_mention pleroma:emoji_reaction]a
defp alerts(%{data: %{alerts: alerts}}) do
alerts = Map.take(alerts, @supported_alert_types)
diff --git a/lib/pleroma/workers/poll_worker.ex b/lib/pleroma/workers/poll_worker.ex
new file mode 100644
index 000000000..3423cc889
--- /dev/null
+++ b/lib/pleroma/workers/poll_worker.ex
@@ -0,0 +1,45 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.PollWorker do
+ @moduledoc """
+ Generates notifications when a poll ends.
+ """
+ use Pleroma.Workers.WorkerHelper, queue: "poll_notifications"
+
+ alias Pleroma.Activity
+ alias Pleroma.Notification
+ alias Pleroma.Object
+
+ @impl Oban.Worker
+ def perform(%Job{args: %{"op" => "poll_end", "activity_id" => activity_id}}) do
+ with %Activity{} = activity <- find_poll_activity(activity_id) do
+ Notification.create_poll_notifications(activity)
+ end
+ end
+
+ defp find_poll_activity(activity_id) do
+ with nil <- Activity.get_by_id(activity_id) do
+ {:error, :poll_activity_not_found}
+ end
+ end
+
+ def schedule_poll_end(%Activity{data: %{"type" => "Create"}, id: activity_id} = activity) do
+ with %Object{data: %{"type" => "Question", "closed" => closed}} when is_binary(closed) <-
+ Object.normalize(activity),
+ {:ok, end_time} <- NaiveDateTime.from_iso8601(closed),
+ :gt <- NaiveDateTime.compare(end_time, NaiveDateTime.utc_now()) do
+ %{
+ op: "poll_end",
+ activity_id: activity_id
+ }
+ |> new(scheduled_at: end_time)
+ |> Oban.insert()
+ else
+ _ -> {:error, activity}
+ end
+ end
+
+ def schedule_poll_end(activity), do: {:error, activity}
+end
diff --git a/priv/repo/migrations/20210717000000_add_poll_to_notifications_enum.exs b/priv/repo/migrations/20210717000000_add_poll_to_notifications_enum.exs
new file mode 100644
index 000000000..9abf40b3d
--- /dev/null
+++ b/priv/repo/migrations/20210717000000_add_poll_to_notifications_enum.exs
@@ -0,0 +1,49 @@
+defmodule Pleroma.Repo.Migrations.AddPollToNotificationsEnum do
+ use Ecto.Migration
+
+ @disable_ddl_transaction true
+
+ def up do
+ """
+ alter type notification_type add value 'poll'
+ """
+ |> execute()
+ end
+
+ def down do
+ alter table(:notifications) do
+ modify(:type, :string)
+ end
+
+ """
+ delete from notifications where type = 'poll'
+ """
+ |> execute()
+
+ """
+ drop type if exists notification_type
+ """
+ |> execute()
+
+ """
+ create type notification_type as enum (
+ 'follow',
+ 'follow_request',
+ 'mention',
+ 'move',
+ 'pleroma:emoji_reaction',
+ 'pleroma:chat_mention',
+ 'reblog',
+ 'favourite',
+ 'pleroma:report'
+ )
+ """
+ |> execute()
+
+ """
+ alter table notifications
+ alter column type type notification_type using (type::notification_type)
+ """
+ |> execute()
+ end
+end
diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs
index 85f895f0f..716af496d 100644
--- a/test/pleroma/notification_test.exs
+++ b/test/pleroma/notification_test.exs
@@ -129,6 +129,19 @@ defmodule Pleroma.NotificationTest do
end
end
+ test "create_poll_notifications/1" do
+ [user1, user2, user3, _, _] = insert_list(5, :user)
+ question = insert(:question, user: user1)
+ activity = insert(:question_activity, question: question)
+
+ {:ok, _, _} = CommonAPI.vote(user2, question, [0])
+ {:ok, _, _} = CommonAPI.vote(user3, question, [1])
+
+ {:ok, notifications} = Notification.create_poll_notifications(activity)
+
+ assert [user2.id, user3.id, user1.id] == Enum.map(notifications, & &1.user_id)
+ end
+
describe "CommonApi.post/2 notification-related functionality" do
test_with_mock "creates but does NOT send notification to blocker user",
Push,
diff --git a/test/pleroma/web/activity_pub/side_effects_test.exs b/test/pleroma/web/activity_pub/side_effects_test.exs
index 13167f50a..d0988619d 100644
--- a/test/pleroma/web/activity_pub/side_effects_test.exs
+++ b/test/pleroma/web/activity_pub/side_effects_test.exs
@@ -157,6 +157,30 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
end
end
+ describe "Question objects" do
+ setup do
+ user = insert(:user)
+ question = build(:question, user: user)
+ question_activity = build(:question_activity, question: question)
+ activity_data = Map.put(question_activity.data, "object", question.data["id"])
+ meta = [object_data: question.data, local: false]
+
+ {:ok, activity, meta} = ActivityPub.persist(activity_data, meta)
+
+ %{activity: activity, meta: meta}
+ end
+
+ test "enqueues the poll end", %{activity: activity, meta: meta} do
+ {:ok, activity, meta} = SideEffects.handle(activity, meta)
+
+ assert_enqueued(
+ worker: Pleroma.Workers.PollWorker,
+ args: %{op: "poll_end", activity_id: activity.id},
+ scheduled_at: NaiveDateTime.from_iso8601!(meta[:object_data]["closed"])
+ )
+ end
+ end
+
describe "delete users with confirmation pending" do
setup do
user = insert(:user, is_confirmed: false)
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index a5dfd3934..4a10a5bc4 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -18,6 +18,7 @@ defmodule Pleroma.Web.CommonAPITest do
alias Pleroma.Web.ActivityPub.Visibility
alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.CommonAPI
+ alias Pleroma.Workers.PollWorker
import Pleroma.Factory
import Mock
@@ -48,6 +49,12 @@ defmodule Pleroma.Web.CommonAPITest do
assert object.data["type"] == "Question"
assert object.data["oneOf"] |> length() == 2
+
+ assert_enqueued(
+ worker: PollWorker,
+ args: %{op: "poll_end", activity_id: activity.id},
+ scheduled_at: NaiveDateTime.from_iso8601!(object.data["closed"])
+ )
end
end
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index d478a81ee..ed66d370a 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -16,6 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
+ alias Pleroma.Workers.ScheduledActivityWorker
import Pleroma.Factory
@@ -705,11 +706,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> json_response_and_validate_schema(200)
assert {:ok, %{id: activity_id}} =
- perform_job(Pleroma.Workers.ScheduledActivityWorker, %{
+ perform_job(ScheduledActivityWorker, %{
activity_id: scheduled_id
})
- assert Repo.all(Oban.Job) == []
+ refute_enqueued(worker: ScheduledActivityWorker)
object =
Activity
diff --git a/test/pleroma/web/mastodon_api/views/notification_view_test.exs b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
index 496a688d1..8070c03c9 100644
--- a/test/pleroma/web/mastodon_api/views/notification_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/notification_view_test.exs
@@ -196,6 +196,27 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], user, [expected])
end
+ test "Poll notification" do
+ user = insert(:user)
+ activity = insert(:question_activity, user: user)
+ {:ok, [notification]} = Notification.create_poll_notifications(activity)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false, is_muted: false},
+ type: "poll",
+ account:
+ AccountView.render("show.json", %{
+ user: user,
+ for: user
+ }),
+ status: StatusView.render("show.json", %{activity: activity, for: user}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ test_notifications_rendering([notification], user, [expected])
+ end
+
test "Report notification" do
reporting_user = insert(:user)
reported_user = insert(:user)
diff --git a/test/support/factory.ex b/test/support/factory.ex
index f31f64a50..4a78425ce 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -213,6 +213,38 @@ defmodule Pleroma.Factory do
}
end
+ def question_factory(attrs \\ %{}) do
+ user = attrs[:user] || insert(:user)
+
+ data = %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
+ "type" => "Question",
+ "actor" => user.ap_id,
+ "attributedTo" => user.ap_id,
+ "attachment" => [],
+ "to" => ["https://www.w3.org/ns/activitystreams#Public"],
+ "cc" => [user.follower_address],
+ "context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(),
+ "closed" => DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601(),
+ "oneOf" => [
+ %{
+ "type" => "Note",
+ "name" => "chocolate",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"}
+ },
+ %{
+ "type" => "Note",
+ "name" => "vanilla",
+ "replies" => %{"totalItems" => 0, "type" => "Collection"}
+ }
+ ]
+ }
+
+ %Pleroma.Object{
+ data: merge_attributes(data, Map.get(attrs, :data, %{}))
+ }
+ end
+
def direct_note_activity_factory do
dm = insert(:direct_note)
@@ -428,6 +460,33 @@ defmodule Pleroma.Factory do
}
end
+ def question_activity_factory(attrs \\ %{}) do
+ user = attrs[:user] || insert(:user)
+ question = attrs[:question] || insert(:question, user: user)
+
+ data_attrs = attrs[:data_attrs] || %{}
+ attrs = Map.drop(attrs, [:user, :question, :data_attrs])
+
+ data =
+ %{
+ "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
+ "type" => "Create",
+ "actor" => question.data["actor"],
+ "to" => question.data["to"],
+ "object" => question.data["id"],
+ "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
+ "context" => question.data["context"]
+ }
+ |> Map.merge(data_attrs)
+
+ %Pleroma.Activity{
+ data: data,
+ actor: data["actor"],
+ recipients: data["to"]
+ }
+ |> Map.merge(attrs)
+ end
+
def oauth_app_factory do
%Pleroma.Web.OAuth.App{
client_name: sequence(:client_name, &"Some client #{&1}"),