diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index e578f707e..265bf837e 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
alias Pleroma.Web.MastodonAPI.ListView
alias Pleroma.Web.MastodonAPI.MastodonAPI
alias Pleroma.Web.MastodonAPI.MastodonView
+ alias Pleroma.Web.MastodonAPI.NotificationView
alias Pleroma.Web.MastodonAPI.ReportView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy
@@ -503,19 +504,17 @@ def unmute_conversation(%{assigns: %{user: user}} = conn, %{"id" => id}) do
def notifications(%{assigns: %{user: user}} = conn, params) do
notifications = Notification.for_user(user, params)
- result =
- notifications
- |> Enum.map(fn x -> render_notification(user, x) end)
- |> Enum.filter(& &1)
-
conn
|> add_link_headers(:notifications, notifications)
- |> json(result)
+ |> put_view(NotificationView)
+ |> render("index.json", %{notifications: notifications, for: user})
end
def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
with {:ok, notification} <- Notification.get(user, id) do
- json(conn, render_notification(user, notification))
+ conn
+ |> put_view(NotificationView)
+ |> render("show.json", %{notification: notification, for: user})
else
{:error, reason} ->
conn
@@ -1309,45 +1308,6 @@ def empty_object(conn, _) do
json(conn, %{})
end
- def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do
- actor = User.get_cached_by_ap_id(activity.data["actor"])
- parent_activity = Activity.get_create_by_object_ap_id(activity.data["object"])
- mastodon_type = Activity.mastodon_notification_type(activity)
-
- response = %{
- id: to_string(id),
- type: mastodon_type,
- created_at: CommonAPI.Utils.to_masto_date(created_at),
- account: AccountView.render("account.json", %{user: actor, for: user})
- }
-
- case mastodon_type do
- "mention" ->
- response
- |> Map.merge(%{
- status: StatusView.render("status.json", %{activity: activity, for: user})
- })
-
- "favourite" ->
- response
- |> Map.merge(%{
- status: StatusView.render("status.json", %{activity: parent_activity, for: user})
- })
-
- "reblog" ->
- response
- |> Map.merge(%{
- status: StatusView.render("status.json", %{activity: parent_activity, for: user})
- })
-
- "follow" ->
- response
-
- _ ->
- nil
- end
- end
-
def get_filters(%{assigns: %{user: user}} = conn, _) do
filters = Filter.get_filters(user)
res = FilterView.render("filters.json", filters: filters)
diff --git a/lib/pleroma/web/mastodon_api/views/notification_view.ex b/lib/pleroma/web/mastodon_api/views/notification_view.ex
new file mode 100644
index 000000000..27e9cab06
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/views/notification_view.ex
@@ -0,0 +1,64 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.NotificationView do
+ use Pleroma.Web, :view
+
+ alias Pleroma.Activity
+ alias Pleroma.Notification
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.NotificationView
+ alias Pleroma.Web.MastodonAPI.StatusView
+
+ def render("index.json", %{notifications: notifications, for: user}) do
+ render_many(notifications, NotificationView, "show.json", %{for: user})
+ end
+
+ def render("show.json", %{
+ notification: %Notification{activity: activity} = notification,
+ for: user
+ }) do
+ actor = User.get_cached_by_ap_id(activity.data["actor"])
+ parent_activity = Activity.get_create_by_object_ap_id(activity.data["object"])
+ mastodon_type = Activity.mastodon_notification_type(activity)
+
+ response = %{
+ id: to_string(notification.id),
+ type: mastodon_type,
+ created_at: CommonAPI.Utils.to_masto_date(notification.inserted_at),
+ account: AccountView.render("account.json", %{user: actor, for: user}),
+ pleroma: %{
+ is_seen: notification.seen
+ }
+ }
+
+ case mastodon_type do
+ "mention" ->
+ response
+ |> Map.merge(%{
+ status: StatusView.render("status.json", %{activity: activity, for: user})
+ })
+
+ "favourite" ->
+ response
+ |> Map.merge(%{
+ status: StatusView.render("status.json", %{activity: parent_activity, for: user})
+ })
+
+ "reblog" ->
+ response
+ |> Map.merge(%{
+ status: StatusView.render("status.json", %{activity: parent_activity, for: user})
+ })
+
+ "follow" ->
+ response
+
+ _ ->
+ nil
+ end
+ end
+end
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index aec11a79f..5850a9579 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.Streamer do
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Visibility
+ alias Pleroma.Web.MastodonAPI.NotificationView
@keepalive_interval :timer.seconds(30)
@@ -106,10 +107,10 @@ def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item},
%{
event: "notification",
payload:
- Pleroma.Web.MastodonAPI.MastodonAPIController.render_notification(
- socket.assigns["user"],
- item
- )
+ NotificationView.render("show.json", %{
+ notification: item,
+ for: socket.assigns["user"]
+ })
|> Jason.encode!()
}
|> Jason.encode!()
diff --git a/test/web/mastodon_api/notification_view_test.exs b/test/web/mastodon_api/notification_view_test.exs
new file mode 100644
index 000000000..b826a7e61
--- /dev/null
+++ b/test/web/mastodon_api/notification_view_test.exs
@@ -0,0 +1,104 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Activity
+ alias Pleroma.Notification
+ alias Pleroma.Repo
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.CommonAPI.Utils
+ alias Pleroma.Web.MastodonAPI.AccountView
+ alias Pleroma.Web.MastodonAPI.NotificationView
+ alias Pleroma.Web.MastodonAPI.StatusView
+ import Pleroma.Factory
+
+ test "Mention notification" do
+ user = insert(:user)
+ mentioned_user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"})
+ {:ok, [notification]} = Notification.create_notifications(activity)
+ user = Repo.get(User, user.id)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false},
+ type: "mention",
+ account: AccountView.render("account.json", %{user: user, for: mentioned_user}),
+ status: StatusView.render("status.json", %{activity: activity, for: mentioned_user}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ result =
+ NotificationView.render("index.json", %{notifications: [notification], for: mentioned_user})
+
+ assert [expected] == result
+ end
+
+ test "Favourite notification" do
+ user = insert(:user)
+ another_user = insert(:user)
+ {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
+ {:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user)
+ {:ok, [notification]} = Notification.create_notifications(favorite_activity)
+ create_activity = Repo.get(Activity, create_activity.id)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false},
+ type: "favourite",
+ account: AccountView.render("account.json", %{user: another_user, for: user}),
+ status: StatusView.render("status.json", %{activity: create_activity, for: user}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ result = NotificationView.render("index.json", %{notifications: [notification], for: user})
+
+ assert [expected] == result
+ end
+
+ test "Reblog notification" do
+ user = insert(:user)
+ another_user = insert(:user)
+ {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
+ {:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user)
+ {:ok, [notification]} = Notification.create_notifications(reblog_activity)
+ reblog_activity = Repo.get(Activity, create_activity.id)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false},
+ type: "reblog",
+ account: AccountView.render("account.json", %{user: another_user, for: user}),
+ status: StatusView.render("status.json", %{activity: reblog_activity, for: user}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ result = NotificationView.render("index.json", %{notifications: [notification], for: user})
+
+ assert [expected] == result
+ end
+
+ test "Follow notification" do
+ follower = insert(:user)
+ followed = insert(:user)
+ {:ok, follower, followed, _activity} = CommonAPI.follow(follower, followed)
+ notification = Notification |> Repo.one() |> Repo.preload(:activity)
+
+ expected = %{
+ id: to_string(notification.id),
+ pleroma: %{is_seen: false},
+ type: "follow",
+ account: AccountView.render("account.json", %{user: follower, for: followed}),
+ created_at: Utils.to_masto_date(notification.inserted_at)
+ }
+
+ result =
+ NotificationView.render("index.json", %{notifications: [notification], for: followed})
+
+ assert [expected] == result
+ end
+end