From 07cb89823f2a33bc540fe53bd784e4b8e9197506 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 18:59:51 -0400 Subject: [PATCH 01/10] More robust validation the vapid config is set --- lib/pleroma/web/push.ex | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/pleroma/web/push.ex b/lib/pleroma/web/push.ex index 0d43f402e..af895467b 100644 --- a/lib/pleroma/web/push.ex +++ b/lib/pleroma/web/push.ex @@ -20,16 +20,10 @@ defmodule Pleroma.Web.Push do end def vapid_config do - Application.get_env(:web_push_encryption, :vapid_details, []) + Application.get_env(:web_push_encryption, :vapid_details, nil) end - def enabled do - case vapid_config() do - [] -> false - list when is_list(list) -> true - _ -> false - end - end + def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config()) def send(notification) do WebPusherWorker.enqueue("web_push", %{"notification_id" => notification.id}) From db88bf30d50a546114d3ee22a3c67b53975257d4 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:20:38 -0400 Subject: [PATCH 02/10] Add spec for send/1 --- lib/pleroma/web/push.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pleroma/web/push.ex b/lib/pleroma/web/push.ex index af895467b..d4693f63e 100644 --- a/lib/pleroma/web/push.ex +++ b/lib/pleroma/web/push.ex @@ -25,6 +25,8 @@ defmodule Pleroma.Web.Push do def enabled, do: match?([subject: _, public_key: _, private_key: _], vapid_config()) + @spec send(Pleroma.Notification.t()) :: + {:ok, Oban.Job.t()} | {:error, Oban.Job.changeset() | term()} def send(notification) do WebPusherWorker.enqueue("web_push", %{"notification_id" => notification.id}) end From 86fa0889bc9906aced78b60ada932b569743340a Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:30:27 -0400 Subject: [PATCH 03/10] Remove unnecessary mastodon_type hack --- lib/pleroma/web/push/impl.ex | 53 ++++++++++++------------------------ 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 53334e72c..1853fdc2d 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -29,7 +29,6 @@ defmodule Pleroma.Web.Push.Impl do when activity_type in @types do actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) - mastodon_type = notification.type gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key) avatar_url = User.avatar_url(actor) object = Object.normalize(activity, fetch: false) @@ -37,11 +36,11 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id = Activity.direct_conversation_id(activity, user) for subscription <- fetch_subscriptions(user_id), - Subscription.enabled?(subscription, mastodon_type) do + Subscription.enabled?(subscription, notification.type) do %{ access_token: subscription.token.token, notification_id: notification.id, - notification_type: mastodon_type, + notification_type: notification.type, icon: avatar_url, preferred_locale: "en", pleroma: %{ @@ -49,7 +48,7 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id: direct_conversation_id } } - |> Map.merge(build_content(notification, actor, object, mastodon_type)) + |> Map.merge(build_content(notification, actor, object)) |> Jason.encode!() |> push_message(build_sub(subscription), gcm_api_key, subscription) end @@ -106,31 +105,24 @@ defmodule Pleroma.Web.Push.Impl do } end - def build_content(notification, actor, object, mastodon_type \\ nil) - def build_content( %{ user: %{notification_settings: %{hide_notification_contents: true}} } = notification, _actor, - _object, - mastodon_type + _object ) do - %{body: format_title(notification, mastodon_type)} + %{body: format_title(notification)} end - def build_content(notification, actor, object, mastodon_type) do - mastodon_type = mastodon_type || notification.type - + def build_content(notification, actor, object) do %{ - title: format_title(notification, mastodon_type), - body: format_body(notification, actor, object, mastodon_type) + title: format_title(notification), + body: format_body(notification, actor, object) } end - def format_body(activity, actor, object, mastodon_type \\ nil) - - def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}, _) do + def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}) do case data["content"] do nil -> "@#{actor.nickname}: (Attachment)" content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" @@ -140,8 +132,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Create"}}}, actor, - %{data: %{"content" => content}}, - _mastodon_type + %{data: %{"content" => content}} ) do "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end @@ -149,8 +140,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Announce"}}}, actor, - %{data: %{"content" => content}}, - _mastodon_type + %{data: %{"content" => content}} ) do "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" end @@ -158,8 +148,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "EmojiReact", "content" => content}}}, actor, - _object, - _mastodon_type + _object ) do "@#{actor.nickname} reacted with #{content}" end @@ -167,13 +156,10 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => type}}} = notification, actor, - _object, - mastodon_type + _object ) when type in ["Follow", "Like"] do - mastodon_type = mastodon_type || notification.type - - case mastodon_type do + case notification.type do "follow" -> "@#{actor.nickname} has followed you" "follow_request" -> "@#{actor.nickname} has requested to follow you" "favourite" -> "@#{actor.nickname} has favorited your post" @@ -183,20 +169,17 @@ defmodule Pleroma.Web.Push.Impl do def format_body( %{activity: %{data: %{"type" => "Update"}}}, actor, - _object, - _mastodon_type + _object ) do "@#{actor.nickname} edited a status" end - def format_title(activity, mastodon_type \\ nil) - - def format_title(%{activity: %{data: %{"directMessage" => true}}}, _mastodon_type) do + def format_title(%{activity: %{data: %{"directMessage" => true}}}) do "New Direct Message" end - def format_title(%{type: type}, mastodon_type) do - case mastodon_type || type do + def format_title(%{type: type}) do + case type do "mention" -> "New Mention" "status" -> "New Status" "follow" -> "New Follower" From b1ef6e5e9ad5afc9d556a4d88ff34c9b62f5fea2 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 19:48:41 -0400 Subject: [PATCH 04/10] Cleanup to make the code easier to follow --- lib/pleroma/web/push/impl.ex | 46 +++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 1853fdc2d..df7e0c53f 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -27,10 +27,10 @@ defmodule Pleroma.Web.Push.Impl do } = notification ) when activity_type in @types do - actor = User.get_cached_by_ap_id(notification.activity.data["actor"]) + user = User.get_cached_by_ap_id(notification.activity.data["actor"]) gcm_api_key = Application.get_env(:web_push_encryption, :gcm_api_key) - avatar_url = User.avatar_url(actor) + avatar_url = User.avatar_url(user) object = Object.normalize(activity, fetch: false) user = User.get_cached_by_id(user_id) direct_conversation_id = Activity.direct_conversation_id(activity, user) @@ -48,7 +48,7 @@ defmodule Pleroma.Web.Push.Impl do direct_conversation_id: direct_conversation_id } } - |> Map.merge(build_content(notification, actor, object)) + |> Map.merge(build_content(notification, user, object)) |> Jason.encode!() |> push_message(build_sub(subscription), gcm_api_key, subscription) end @@ -109,71 +109,73 @@ defmodule Pleroma.Web.Push.Impl do %{ user: %{notification_settings: %{hide_notification_contents: true}} } = notification, - _actor, + _user, _object ) do %{body: format_title(notification)} end - def build_content(notification, actor, object) do + def build_content(notification, user, object) do %{ title: format_title(notification), - body: format_body(notification, actor, object) + body: format_body(notification, user, object) } end - def format_body(_activity, actor, %{data: %{"type" => "ChatMessage"} = data}) do - case data["content"] do - nil -> "@#{actor.nickname}: (Attachment)" - content -> "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + @spec format_body(Notification.t(), User.t(), Object.t()) :: String.t() + def format_body(_notification, user, %{data: %{"type" => "ChatMessage"} = object}) do + case object["content"] do + nil -> "@#{user.nickname}: (Attachment)" + content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end end def format_body( %{activity: %{data: %{"type" => "Create"}}}, - actor, + user, %{data: %{"content" => content}} ) do - "@#{actor.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" end def format_body( %{activity: %{data: %{"type" => "Announce"}}}, - actor, + user, %{data: %{"content" => content}} ) do - "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" end def format_body( %{activity: %{data: %{"type" => "EmojiReact", "content" => content}}}, - actor, + user, _object ) do - "@#{actor.nickname} reacted with #{content}" + "@#{user.nickname} reacted with #{content}" end def format_body( %{activity: %{data: %{"type" => type}}} = notification, - actor, + user, _object ) when type in ["Follow", "Like"] do case notification.type do - "follow" -> "@#{actor.nickname} has followed you" - "follow_request" -> "@#{actor.nickname} has requested to follow you" - "favourite" -> "@#{actor.nickname} has favorited your post" + "follow" -> "@#{user.nickname} has followed you" + "follow_request" -> "@#{user.nickname} has requested to follow you" + "favourite" -> "@#{user.nickname} has favorited your post" end end def format_body( %{activity: %{data: %{"type" => "Update"}}}, - actor, + user, _object ) do - "@#{actor.nickname} edited a status" + "@#{user.nickname} edited a status" end + @spec format_title(Notification.t()) :: String.t() def format_title(%{activity: %{data: %{"directMessage" => true}}}) do "New Direct Message" end From 3211557f742e07d5144426a71c39267480656a38 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 20:30:43 -0400 Subject: [PATCH 05/10] Render nice web push notifications for polls --- changelog.d/webpush-polls.change | 1 + lib/pleroma/web/push/impl.ex | 19 +++++++++++++++++++ test/pleroma/web/push/impl_test.exs | 21 +++++++++++++++++++++ test/support/factory.ex | 1 + 4 files changed, 42 insertions(+) create mode 100644 changelog.d/webpush-polls.change diff --git a/changelog.d/webpush-polls.change b/changelog.d/webpush-polls.change new file mode 100644 index 000000000..5607d6bfc --- /dev/null +++ b/changelog.d/webpush-polls.change @@ -0,0 +1 @@ +Render nice web push notifications for polls diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index df7e0c53f..98e7659ab 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -130,6 +130,24 @@ defmodule Pleroma.Web.Push.Impl do end end + def format_body( + %{type: "poll"} = _notification, + _user, + %{data: %{"content" => content} = data} = _object + ) do + options = Map.get(data, "anyOf") || Map.get(data, "oneOf") + + content_text = content <> "\n" + + options_text = + Enum.map(options, fn x -> "○ #{x["name"]}" end) + |> Enum.join("\n") + + [content_text, options_text] + |> Enum.join("\n") + |> Utils.scrub_html_and_truncate(80) + end + def format_body( %{activity: %{data: %{"type" => "Create"}}}, user, @@ -191,6 +209,7 @@ defmodule Pleroma.Web.Push.Impl do "update" -> "New Update" "pleroma:chat_mention" -> "New Chat Message" "pleroma:emoji_reaction" -> "New Reaction" + "poll" -> "Poll Results" type -> "New #{String.capitalize(type || "event")}" end end diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs index 3ceea3d71..e1bbf8d17 100644 --- a/test/pleroma/web/push/impl_test.exs +++ b/test/pleroma/web/push/impl_test.exs @@ -232,6 +232,27 @@ defmodule Pleroma.Web.Push.ImplTest do "New Direct Message" end + test "renders poll notification" do + user = insert(:user) + question = insert(:question, user: user) + activity = insert(:question_activity, question: question) + + {:ok, [notification]} = Notification.create_poll_notifications(activity) + + assert Impl.format_title(notification) == "Poll Results" + + expected_body = + """ + Which flavor of ice cream do you prefer? + + ○ chocolate + ○ vanilla + """ + |> String.trim_trailing("\n") + + assert Impl.format_body(notification, user, question) == expected_body + end + describe "build_content/3" do test "builds content for chat messages" do user = insert(:user) diff --git a/test/support/factory.ex b/test/support/factory.ex index 20bc5162e..b248508fa 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -249,6 +249,7 @@ defmodule Pleroma.Factory do "cc" => [user.follower_address], "context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(), "closed" => DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601(), + "content" => "Which flavor of ice cream do you prefer?", "oneOf" => [ %{ "type" => "Note", From dcc50da4009f19303dec36e0969f3fca0f690e4f Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:40:08 -0400 Subject: [PATCH 06/10] Stream the notifications as part of the job --- lib/pleroma/notification.ex | 2 -- lib/pleroma/workers/poll_worker.ex | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index b9694a353..de2508b93 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -479,8 +479,6 @@ defmodule Pleroma.Notification do end end) - stream(notifications) - {:ok, notifications} end end diff --git a/lib/pleroma/workers/poll_worker.ex b/lib/pleroma/workers/poll_worker.ex index 70df54193..3fcac9bc3 100644 --- a/lib/pleroma/workers/poll_worker.ex +++ b/lib/pleroma/workers/poll_worker.ex @@ -14,8 +14,9 @@ defmodule Pleroma.Workers.PollWorker do @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) + with %Activity{} = activity <- find_poll_activity(activity_id), + {:ok, notifications} <- Notification.create_poll_notifications(activity) do + Notification.stream(notifications) end end From c1b84edefcd8db998a7eabff110f2dabecfc8dde Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:48:38 -0400 Subject: [PATCH 07/10] Increase web push character limit for the body --- lib/pleroma/web/push/impl.ex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index 98e7659ab..13c054e05 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -16,6 +16,7 @@ defmodule Pleroma.Web.Push.Impl do require Logger import Ecto.Query + @body_chars 140 @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact", "Update"] @doc "Performs sending notifications for user subscriptions" @@ -126,7 +127,7 @@ defmodule Pleroma.Web.Push.Impl do def format_body(_notification, user, %{data: %{"type" => "ChatMessage"} = object}) do case object["content"] do nil -> "@#{user.nickname}: (Attachment)" - content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + content -> "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end end @@ -145,7 +146,7 @@ defmodule Pleroma.Web.Push.Impl do [content_text, options_text] |> Enum.join("\n") - |> Utils.scrub_html_and_truncate(80) + |> Utils.scrub_html_and_truncate(@body_chars) end def format_body( @@ -153,7 +154,7 @@ defmodule Pleroma.Web.Push.Impl do user, %{data: %{"content" => content}} ) do - "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname}: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end def format_body( @@ -161,7 +162,7 @@ defmodule Pleroma.Web.Push.Impl do user, %{data: %{"content" => content}} ) do - "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" + "@#{user.nickname} repeated: #{Utils.scrub_html_and_truncate(content, @body_chars)}" end def format_body( From 8468d78882fb004eb5f64e6e0a0dca1ef3284c93 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:48:38 -0400 Subject: [PATCH 08/10] Increase web push character limit for the body --- test/pleroma/web/push/impl_test.exs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs index e1bbf8d17..969c7a605 100644 --- a/test/pleroma/web/push/impl_test.exs +++ b/test/pleroma/web/push/impl_test.exs @@ -41,7 +41,7 @@ defmodule Pleroma.Web.Push.ImplTest do } } @api_key "BASgACIHpN1GYgzSRp" - @message "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..." + @message "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis." test "performs sending notifications" do user = insert(:user) @@ -129,7 +129,7 @@ defmodule Pleroma.Web.Push.ImplTest do user, object ) == - "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..." + "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis." assert Impl.format_title(%{activity: activity, type: "mention"}) == "New Mention" @@ -161,7 +161,7 @@ defmodule Pleroma.Web.Push.ImplTest do object = Object.normalize(activity, fetch: false) assert Impl.format_body(%{activity: announce_activity}, user, object) == - "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..." + "@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis." assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) == "New Repeat" @@ -365,7 +365,7 @@ defmodule Pleroma.Web.Push.ImplTest do assert Impl.build_content(notif, actor, object) == %{ body: - "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...", + "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis.", title: "New Direct Message" } @@ -383,7 +383,7 @@ defmodule Pleroma.Web.Push.ImplTest do assert Impl.build_content(notif, actor, object) == %{ body: - "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...", + "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis finibus turpis.", title: "New Mention" } From f000dab372993e1cbd494535b82c248d44595ab5 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sat, 8 Jun 2024 22:54:47 -0400 Subject: [PATCH 09/10] Switch test case to Impl.build_content/3 --- test/pleroma/web/push/impl_test.exs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/pleroma/web/push/impl_test.exs b/test/pleroma/web/push/impl_test.exs index 969c7a605..c263a1280 100644 --- a/test/pleroma/web/push/impl_test.exs +++ b/test/pleroma/web/push/impl_test.exs @@ -239,7 +239,7 @@ defmodule Pleroma.Web.Push.ImplTest do {:ok, [notification]} = Notification.create_poll_notifications(activity) - assert Impl.format_title(notification) == "Poll Results" + expected_title = "Poll Results" expected_body = """ @@ -250,7 +250,9 @@ defmodule Pleroma.Web.Push.ImplTest do """ |> String.trim_trailing("\n") - assert Impl.format_body(notification, user, question) == expected_body + content = Impl.build_content(notification, user, question) + + assert match?(%{title: ^expected_title, body: ^expected_body}, content) end describe "build_content/3" do From 2fd155fb9bb82401131b40cc62dd17fc44086361 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 11 Jun 2024 15:59:48 -0400 Subject: [PATCH 10/10] Add PollWorker test; move the streaming notification test to it --- test/pleroma/notification_test.exs | 27 +------------ test/pleroma/workers/poll_worker_test.exs | 49 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 25 deletions(-) create mode 100644 test/pleroma/workers/poll_worker_test.exs diff --git a/test/pleroma/notification_test.exs b/test/pleroma/notification_test.exs index 02ae06c63..2c582c708 100644 --- a/test/pleroma/notification_test.exs +++ b/test/pleroma/notification_test.exs @@ -5,7 +5,6 @@ defmodule Pleroma.NotificationTest do use Pleroma.DataCase, async: false - import Mock import Pleroma.Factory alias Pleroma.FollowingRelationship @@ -184,31 +183,9 @@ defmodule Pleroma.NotificationTest do {:ok, _, _} = CommonAPI.vote(user2, question, [0]) {:ok, _, _} = CommonAPI.vote(user3, question, [1]) - with_mocks([ - { - Pleroma.Web.Streamer, - [], - [ - stream: fn _, _ -> nil end - ] - }, - { - Pleroma.Web.Push, - [], - [ - send: fn _ -> nil end - ] - } - ]) do - {:ok, notifications} = Notification.create_poll_notifications(activity) + {:ok, notifications} = Notification.create_poll_notifications(activity) - Enum.each(notifications, fn notification -> - assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification)) - assert called(Pleroma.Web.Push.send(notification)) - end) - - assert [user2.id, user3.id, user1.id] == Enum.map(notifications, & &1.user_id) - end + assert [user2.id, user3.id, user1.id] == Enum.map(notifications, & &1.user_id) end describe "create_notification" do diff --git a/test/pleroma/workers/poll_worker_test.exs b/test/pleroma/workers/poll_worker_test.exs new file mode 100644 index 000000000..749df8aff --- /dev/null +++ b/test/pleroma/workers/poll_worker_test.exs @@ -0,0 +1,49 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Workers.PollWorkerTest do + use Pleroma.DataCase + use Oban.Testing, repo: Pleroma.Repo + + import Mock + import Pleroma.Factory + + alias Pleroma.Workers.PollWorker + + test "poll notification job" do + user = insert(:user) + question = insert(:question, user: user) + activity = insert(:question_activity, question: question) + + PollWorker.schedule_poll_end(activity) + + expected_job_args = %{"activity_id" => activity.id, "op" => "poll_end"} + + assert_enqueued(args: expected_job_args) + + with_mocks([ + { + Pleroma.Web.Streamer, + [], + [ + stream: fn _, _ -> nil end + ] + }, + { + Pleroma.Web.Push, + [], + [ + send: fn _ -> nil end + ] + } + ]) do + [job] = all_enqueued(worker: PollWorker) + PollWorker.perform(job) + + # Ensure notifications were streamed out when job executes + assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], :_)) + assert called(Pleroma.Web.Push.send(:_)) + end + end +end