Move subscription notifications to a separate controller
This commit is contained in:
		
							parent
							
								
									56b60798c2
								
							
						
					
					
						commit
						6042e21b25
					
				
					 8 changed files with 343 additions and 277 deletions
				
			
		| 
						 | 
				
			
			@ -23,7 +23,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 | 
			
		|||
  alias Pleroma.Repo
 | 
			
		||||
  alias Pleroma.ScheduledActivity
 | 
			
		||||
  alias Pleroma.Stats
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web
 | 
			
		||||
  alias Pleroma.Web.ActivityPub.ActivityPub
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 | 
			
		|||
  alias Pleroma.Web.MastodonAPI.ReportView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.ScheduledActivityView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.StatusView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.SubscriptionNotificationView
 | 
			
		||||
  alias Pleroma.Web.MediaProxy
 | 
			
		||||
  alias Pleroma.Web.OAuth.App
 | 
			
		||||
  alias Pleroma.Web.OAuth.Authorization
 | 
			
		||||
| 
						 | 
				
			
			@ -727,28 +725,6 @@ def notifications(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
    |> render("index.json", %{notifications: notifications, for: user})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def subscription_notifications(%{assigns: %{user: user}} = conn, params) do
 | 
			
		||||
    notifications = MastodonAPI.get_subscription_notifications(user, params)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:subscription_notifications, notifications)
 | 
			
		||||
    |> put_view(SubscriptionNotificationView)
 | 
			
		||||
    |> render("index.json", %{notifications: notifications, for: user})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_subscription_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, notification} <- SubscriptionNotification.get(user, id) do
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(SubscriptionNotificationView)
 | 
			
		||||
      |> render("show.json", %{subscription_notification: notification, for: user})
 | 
			
		||||
    else
 | 
			
		||||
      {:error, reason} ->
 | 
			
		||||
        conn
 | 
			
		||||
        |> put_status(:forbidden)
 | 
			
		||||
        |> json(%{"error" => reason})
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, notification} <- Notification.get(user, id) do
 | 
			
		||||
      conn
 | 
			
		||||
| 
						 | 
				
			
			@ -767,11 +743,6 @@ def clear_notifications(%{assigns: %{user: user}} = conn, _params) do
 | 
			
		|||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def clear_subscription_notifications(%{assigns: %{user: user}} = conn, _params) do
 | 
			
		||||
    SubscriptionNotification.clear(user)
 | 
			
		||||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, _notif} <- Notification.dismiss(user, id) do
 | 
			
		||||
      json(conn, %{})
 | 
			
		||||
| 
						 | 
				
			
			@ -783,30 +754,11 @@ def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _para
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dismiss_subscription_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, _notif} <- SubscriptionNotification.dismiss(user, id) do
 | 
			
		||||
      json(conn, %{})
 | 
			
		||||
    else
 | 
			
		||||
      {:error, reason} ->
 | 
			
		||||
        conn
 | 
			
		||||
        |> put_status(:forbidden)
 | 
			
		||||
        |> json(%{"error" => reason})
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def destroy_multiple(%{assigns: %{user: user}} = conn, %{"ids" => ids} = _params) do
 | 
			
		||||
    Notification.destroy_multiple(user, ids)
 | 
			
		||||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def destroy_multiple_subscription_notifications(
 | 
			
		||||
        %{assigns: %{user: user}} = conn,
 | 
			
		||||
        %{"ids" => ids} = _params
 | 
			
		||||
      ) do
 | 
			
		||||
    SubscriptionNotification.destroy_multiple(user, ids)
 | 
			
		||||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
 | 
			
		||||
    id = List.wrap(id)
 | 
			
		||||
    q = from(u in User, where: u.id in ^id)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
 | 
			
		|||
  alias Pleroma.Notification
 | 
			
		||||
  alias Pleroma.Pagination
 | 
			
		||||
  alias Pleroma.ScheduledActivity
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -63,15 +62,6 @@ def get_notifications(user, params \\ %{}) do
 | 
			
		|||
    |> Pagination.fetch_paginated(params)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_subscription_notifications(user, params \\ %{}) do
 | 
			
		||||
    options = cast_params(params)
 | 
			
		||||
 | 
			
		||||
    user
 | 
			
		||||
    |> SubscriptionNotification.for_user_query(options)
 | 
			
		||||
    |> restrict(:exclude_types, options)
 | 
			
		||||
    |> Pagination.fetch_paginated(params)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get_scheduled_activities(user, params \\ %{}) do
 | 
			
		||||
    user
 | 
			
		||||
    |> ScheduledActivity.for_user_query()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										40
									
								
								lib/pleroma/web/pleroma_api/pleroma_api.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								lib/pleroma/web/pleroma_api/pleroma_api.ex
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,40 @@
 | 
			
		|||
defmodule Pleroma.Web.PleromaAPI.PleromaAPI do
 | 
			
		||||
  import Ecto.Query
 | 
			
		||||
  import Ecto.Changeset
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Activity
 | 
			
		||||
  alias Pleroma.Pagination
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
 | 
			
		||||
  def get_subscription_notifications(user, params \\ %{}) do
 | 
			
		||||
    options = cast_params(params)
 | 
			
		||||
 | 
			
		||||
    user
 | 
			
		||||
    |> SubscriptionNotification.for_user_query(options)
 | 
			
		||||
    |> restrict(:exclude_types, options)
 | 
			
		||||
    |> Pagination.fetch_paginated(params)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp cast_params(params) do
 | 
			
		||||
    param_types = %{
 | 
			
		||||
      exclude_types: {:array, :string},
 | 
			
		||||
      reblogs: :boolean,
 | 
			
		||||
      with_muted: :boolean
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    changeset = cast({%{}, param_types}, params, Map.keys(param_types))
 | 
			
		||||
    changeset.changes
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp restrict(query, :exclude_types, %{exclude_types: mastodon_types = [_ | _]}) do
 | 
			
		||||
    ap_types =
 | 
			
		||||
      mastodon_types
 | 
			
		||||
      |> Enum.map(&Activity.from_mastodon_notification_type/1)
 | 
			
		||||
      |> Enum.filter(& &1)
 | 
			
		||||
 | 
			
		||||
    query
 | 
			
		||||
    |> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp restrict(query, _, _), do: query
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.PleromaAPI.SubscriptionNotificationController do
 | 
			
		||||
  use Pleroma.Web, :controller
 | 
			
		||||
 | 
			
		||||
  import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
  alias Pleroma.Web.PleromaAPI.PleromaAPI
 | 
			
		||||
  alias Pleroma.Web.PleromaAPI.SubscriptionNotificationView
 | 
			
		||||
 | 
			
		||||
  def list(%{assigns: %{user: user}} = conn, params) do
 | 
			
		||||
    notifications = PleromaAPI.get_subscription_notifications(user, params)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(notifications)
 | 
			
		||||
    |> put_view(SubscriptionNotificationView)
 | 
			
		||||
    |> render("index.json", %{notifications: notifications, for: user})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def get(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, notification} <- SubscriptionNotification.get(user, id) do
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(SubscriptionNotificationView)
 | 
			
		||||
      |> render("show.json", %{subscription_notification: notification, for: user})
 | 
			
		||||
    else
 | 
			
		||||
      {:error, reason} ->
 | 
			
		||||
        conn
 | 
			
		||||
        |> put_status(:forbidden)
 | 
			
		||||
        |> json(%{"error" => reason})
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def clear(%{assigns: %{user: user}} = conn, _params) do
 | 
			
		||||
    SubscriptionNotification.clear(user)
 | 
			
		||||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def dismiss(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do
 | 
			
		||||
    with {:ok, _notif} <- SubscriptionNotification.dismiss(user, id) do
 | 
			
		||||
      json(conn, %{})
 | 
			
		||||
    else
 | 
			
		||||
      {:error, reason} ->
 | 
			
		||||
        conn
 | 
			
		||||
        |> put_status(:forbidden)
 | 
			
		||||
        |> json(%{"error" => reason})
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def destroy_multiple(
 | 
			
		||||
        %{assigns: %{user: user}} = conn,
 | 
			
		||||
        %{"ids" => ids} = _params
 | 
			
		||||
      ) do
 | 
			
		||||
    SubscriptionNotification.destroy_multiple(user, ids)
 | 
			
		||||
    json(conn, %{})
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -2,15 +2,15 @@
 | 
			
		|||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.MastodonAPI.SubscriptionNotificationView do
 | 
			
		||||
defmodule Pleroma.Web.PleromaAPI.SubscriptionNotificationView do
 | 
			
		||||
  use Pleroma.Web, :view
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Activity
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.AccountView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.SubscriptionNotificationView
 | 
			
		||||
  alias Pleroma.Web.MastodonAPI.StatusView
 | 
			
		||||
  alias Pleroma.Web.PleromaAPI.SubscriptionNotificationView
 | 
			
		||||
 | 
			
		||||
  def render("index.json", %{notifications: notifications, for: user}) do
 | 
			
		||||
    safe_render_many(notifications, SubscriptionNotificationView, "show.json", %{for: user})
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +268,14 @@ defmodule Pleroma.Web.Router do
 | 
			
		|||
      pipe_through(:oauth_read)
 | 
			
		||||
      get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
 | 
			
		||||
      get("/conversations/:id", PleromaAPIController, :conversation)
 | 
			
		||||
 | 
			
		||||
      scope "/subscription_notifications" do
 | 
			
		||||
        post("/clear", SubscriptionNotificationController, :clear)
 | 
			
		||||
        post("/dismiss", SubscriptionNotificationController, :dismiss)
 | 
			
		||||
        delete("/destroy_multiple", SubscriptionNotificationController, :destroy_multiple)
 | 
			
		||||
        get("/", SubscriptionNotificationController, :list)
 | 
			
		||||
        get("/id", SubscriptionNotificationController, :get)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    scope [] do
 | 
			
		||||
| 
						 | 
				
			
			@ -302,38 +310,13 @@ defmodule Pleroma.Web.Router do
 | 
			
		|||
 | 
			
		||||
      post("/notifications/clear", MastodonAPIController, :clear_notifications)
 | 
			
		||||
 | 
			
		||||
      post(
 | 
			
		||||
        "/notifications/subscription/clear",
 | 
			
		||||
        MastodonAPIController,
 | 
			
		||||
        :clear_subscription_notifications
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      post("/notifications/dismiss", MastodonAPIController, :dismiss_notification)
 | 
			
		||||
 | 
			
		||||
      post(
 | 
			
		||||
        "/notifications/subscription/dismiss",
 | 
			
		||||
        MastodonAPIController,
 | 
			
		||||
        :dismiss_subscription_notification
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      get("/notifications", MastodonAPIController, :notifications)
 | 
			
		||||
      get("/notifications/subscription", MastodonAPIController, :subscription_notifications)
 | 
			
		||||
      get("/notifications/:id", MastodonAPIController, :get_notification)
 | 
			
		||||
 | 
			
		||||
      get(
 | 
			
		||||
        "/notifications/subscription/:id",
 | 
			
		||||
        MastodonAPIController,
 | 
			
		||||
        :get_subscription_notification
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      delete("/notifications/destroy_multiple", MastodonAPIController, :destroy_multiple)
 | 
			
		||||
 | 
			
		||||
      delete(
 | 
			
		||||
        "/notifications/subscription/destroy_multiple",
 | 
			
		||||
        MastodonAPIController,
 | 
			
		||||
        :destroy_multiple_subscription_notifications
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      get("/scheduled_statuses", MastodonAPIController, :scheduled_statuses)
 | 
			
		||||
      get("/scheduled_statuses/:id", MastodonAPIController, :show_scheduled_status)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
 | 
			
		|||
  alias Pleroma.Object
 | 
			
		||||
  alias Pleroma.Repo
 | 
			
		||||
  alias Pleroma.ScheduledActivity
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
  alias Pleroma.Tests.ObanHelpers
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web.ActivityPub.ActivityPub
 | 
			
		||||
| 
						 | 
				
			
			@ -1275,197 +1274,6 @@ test "see notifications after muting user with notifications and with_muted para
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "subscription_notifications" do
 | 
			
		||||
    setup do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      subscriber = insert(:user)
 | 
			
		||||
 | 
			
		||||
      User.subscribe(subscriber, user)
 | 
			
		||||
 | 
			
		||||
      {:ok, %{user: user, subscriber: subscriber}}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "list of notifications", %{conn: conn, user: user, subscriber: subscriber} do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get("/api/v1/notifications/subscription")
 | 
			
		||||
 | 
			
		||||
      assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
 | 
			
		||||
      assert response == status_text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "getting a single notification", %{conn: conn, user: user, subscriber: subscriber} do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
      [notification] = Repo.all(SubscriptionNotification)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get("/api/v1/notifications/subscription/#{notification.id}")
 | 
			
		||||
 | 
			
		||||
      assert %{"status" => %{"content" => response}} = json_response(conn, 200)
 | 
			
		||||
      assert response == status_text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "dismissing a single notification also deletes it", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
 | 
			
		||||
      [notification] = Repo.all(SubscriptionNotification)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> post("/api/v1/notifications/subscription/dismiss", %{"id" => notification.id})
 | 
			
		||||
 | 
			
		||||
      assert %{} = json_response(conn, 200)
 | 
			
		||||
 | 
			
		||||
      assert Repo.all(SubscriptionNotification) == []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "clearing all notifications also deletes them", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      status_text1 = "Hello"
 | 
			
		||||
      status_text2 = "Hello again"
 | 
			
		||||
      {:ok, _activity1} = CommonAPI.post(user, %{"status" => status_text1})
 | 
			
		||||
      {:ok, _activity2} = CommonAPI.post(user, %{"status" => status_text2})
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> post("/api/v1/notifications/subscription/clear")
 | 
			
		||||
 | 
			
		||||
      assert %{} = json_response(conn, 200)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        build_conn()
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get("/api/v1/notifications/subscription")
 | 
			
		||||
 | 
			
		||||
      assert json_response(conn, 200) == []
 | 
			
		||||
 | 
			
		||||
      assert Repo.all(SubscriptionNotification) == []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "paginates notifications using min_id, since_id, max_id, and limit", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      {:ok, activity1} = CommonAPI.post(user, %{"status" => "Hello 1"})
 | 
			
		||||
      {:ok, activity2} = CommonAPI.post(user, %{"status" => "Hello 2"})
 | 
			
		||||
      {:ok, activity3} = CommonAPI.post(user, %{"status" => "Hello 3"})
 | 
			
		||||
      {:ok, activity4} = CommonAPI.post(user, %{"status" => "Hello 4"})
 | 
			
		||||
 | 
			
		||||
      notification1_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity1.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification2_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity2.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification3_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity3.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification4_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity4.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      conn = assign(conn, :user, subscriber)
 | 
			
		||||
 | 
			
		||||
      # min_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(conn, "/api/v1/notifications/subscription?limit=2&min_id=#{notification1_id}")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
 | 
			
		||||
 | 
			
		||||
      # since_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(conn, "/api/v1/notifications/subscription?limit=2&since_id=#{notification1_id}")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
 | 
			
		||||
 | 
			
		||||
      # max_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(conn, "/api/v1/notifications/subscription?limit=2&max_id=#{notification4_id}")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "destroy multiple", %{conn: conn, user: user1, subscriber: user2} do
 | 
			
		||||
      # mutual subscription
 | 
			
		||||
      User.subscribe(user1, user2)
 | 
			
		||||
 | 
			
		||||
      {:ok, activity1} = CommonAPI.post(user1, %{"status" => "Hello 1"})
 | 
			
		||||
      {:ok, activity2} = CommonAPI.post(user1, %{"status" => "World 1"})
 | 
			
		||||
      {:ok, activity3} = CommonAPI.post(user2, %{"status" => "Hello 2"})
 | 
			
		||||
      {:ok, activity4} = CommonAPI.post(user2, %{"status" => "World 2"})
 | 
			
		||||
 | 
			
		||||
      notification1_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity1.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification2_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity2.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification3_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity3.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification4_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity4.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      conn = assign(conn, :user, user1)
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn, "/api/v1/notifications/subscription")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification3_id, notification4_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      conn2 = assign(conn, :user, user2)
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn2, "/api/v1/notifications/subscription")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification1_id, notification2_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      conn_destroy =
 | 
			
		||||
        delete(conn, "/api/v1/notifications/subscription/destroy_multiple", %{
 | 
			
		||||
          "ids" => [notification3_id, notification4_id]
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      assert json_response(conn_destroy, 200) == %{}
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn2, "/api/v1/notifications/subscription")
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification1_id, notification2_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      assert length(Repo.all(SubscriptionNotification)) == 2
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "reblogging" do
 | 
			
		||||
    test "reblogs and returns the reblogged status", %{conn: conn} do
 | 
			
		||||
      activity = insert(:note_activity)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,234 @@
 | 
			
		|||
# Pleroma: A lightweight social networking server
 | 
			
		||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
 | 
			
		||||
# SPDX-License-Identifier: AGPL-3.0-only
 | 
			
		||||
 | 
			
		||||
defmodule Pleroma.Web.PleromaAPI.SubscriptionNotificationControllerTest do
 | 
			
		||||
  use Pleroma.Web.ConnCase
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Repo
 | 
			
		||||
  alias Pleroma.SubscriptionNotification
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
  import Pleroma.Factory
 | 
			
		||||
  import Tesla.Mock
 | 
			
		||||
 | 
			
		||||
  setup do
 | 
			
		||||
    mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
 | 
			
		||||
    :ok
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  clear_config([:instance, :public])
 | 
			
		||||
  clear_config([:rich_media, :enabled])
 | 
			
		||||
 | 
			
		||||
  describe "subscription_notifications" do
 | 
			
		||||
    setup do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      subscriber = insert(:user)
 | 
			
		||||
 | 
			
		||||
      User.subscribe(subscriber, user)
 | 
			
		||||
 | 
			
		||||
      {:ok, %{user: user, subscriber: subscriber}}
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "list of notifications", %{conn: conn, user: user, subscriber: subscriber} do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
      path = subscription_notification_path(conn, :list)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get(path)
 | 
			
		||||
 | 
			
		||||
      assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
 | 
			
		||||
      assert response == status_text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "getting a single notification", %{conn: conn, user: user, subscriber: subscriber} do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
      [notification] = Repo.all(SubscriptionNotification)
 | 
			
		||||
 | 
			
		||||
      path = subscription_notification_path(conn, :get, id: notification.id)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get(path)
 | 
			
		||||
 | 
			
		||||
      assert %{"status" => %{"content" => response}} = json_response(conn, 200)
 | 
			
		||||
      assert response == status_text
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "dismissing a single notification also deletes it", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      status_text = "Hello"
 | 
			
		||||
      {:ok, _activity} = CommonAPI.post(user, %{"status" => status_text})
 | 
			
		||||
 | 
			
		||||
      [notification] = Repo.all(SubscriptionNotification)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> post(subscription_notification_path(conn, :dismiss), %{"id" => notification.id})
 | 
			
		||||
 | 
			
		||||
      assert %{} = json_response(conn, 200)
 | 
			
		||||
 | 
			
		||||
      assert Repo.all(SubscriptionNotification) == []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "clearing all notifications also deletes them", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      status_text1 = "Hello"
 | 
			
		||||
      status_text2 = "Hello again"
 | 
			
		||||
      {:ok, _activity1} = CommonAPI.post(user, %{"status" => status_text1})
 | 
			
		||||
      {:ok, _activity2} = CommonAPI.post(user, %{"status" => status_text2})
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        conn
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> post(subscription_notification_path(conn, :clear))
 | 
			
		||||
 | 
			
		||||
      assert %{} = json_response(conn, 200)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
        build_conn()
 | 
			
		||||
        |> assign(:user, subscriber)
 | 
			
		||||
        |> get(subscription_notification_path(conn, :list))
 | 
			
		||||
 | 
			
		||||
      assert json_response(conn, 200) == []
 | 
			
		||||
 | 
			
		||||
      assert Repo.all(SubscriptionNotification) == []
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "paginates notifications using min_id, since_id, max_id, and limit", %{
 | 
			
		||||
      conn: conn,
 | 
			
		||||
      user: user,
 | 
			
		||||
      subscriber: subscriber
 | 
			
		||||
    } do
 | 
			
		||||
      {:ok, activity1} = CommonAPI.post(user, %{"status" => "Hello 1"})
 | 
			
		||||
      {:ok, activity2} = CommonAPI.post(user, %{"status" => "Hello 2"})
 | 
			
		||||
      {:ok, activity3} = CommonAPI.post(user, %{"status" => "Hello 3"})
 | 
			
		||||
      {:ok, activity4} = CommonAPI.post(user, %{"status" => "Hello 4"})
 | 
			
		||||
 | 
			
		||||
      notification1_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity1.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification2_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity2.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification3_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity3.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification4_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity4.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      conn = assign(conn, :user, subscriber)
 | 
			
		||||
 | 
			
		||||
      # min_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(
 | 
			
		||||
          conn,
 | 
			
		||||
          subscription_notification_path(conn, :list, %{
 | 
			
		||||
            "limit" => 2,
 | 
			
		||||
            "min_id" => notification1_id
 | 
			
		||||
          })
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
 | 
			
		||||
 | 
			
		||||
      # since_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(
 | 
			
		||||
          conn,
 | 
			
		||||
          subscription_notification_path(conn, :list, %{
 | 
			
		||||
            "limit" => 2,
 | 
			
		||||
            "since_id" => notification1_id
 | 
			
		||||
          })
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
 | 
			
		||||
 | 
			
		||||
      # max_id
 | 
			
		||||
      conn_res =
 | 
			
		||||
        get(
 | 
			
		||||
          conn,
 | 
			
		||||
          subscription_notification_path(conn, :list, %{
 | 
			
		||||
            "limit" => 2,
 | 
			
		||||
            "max_id" => notification4_id
 | 
			
		||||
          })
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
      assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "destroy multiple", %{conn: conn, user: user1, subscriber: user2} do
 | 
			
		||||
      # mutual subscription
 | 
			
		||||
      User.subscribe(user1, user2)
 | 
			
		||||
 | 
			
		||||
      {:ok, activity1} = CommonAPI.post(user1, %{"status" => "Hello 1"})
 | 
			
		||||
      {:ok, activity2} = CommonAPI.post(user1, %{"status" => "World 1"})
 | 
			
		||||
      {:ok, activity3} = CommonAPI.post(user2, %{"status" => "Hello 2"})
 | 
			
		||||
      {:ok, activity4} = CommonAPI.post(user2, %{"status" => "World 2"})
 | 
			
		||||
 | 
			
		||||
      notification1_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity1.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification2_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity2.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification3_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity3.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      notification4_id =
 | 
			
		||||
        Repo.get_by(SubscriptionNotification, activity_id: activity4.id).id |> to_string()
 | 
			
		||||
 | 
			
		||||
      conn = assign(conn, :user, user1)
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn, subscription_notification_path(conn, :list))
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification3_id, notification4_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      conn2 = assign(conn, :user, user2)
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn2, subscription_notification_path(conn, :list))
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification1_id, notification2_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      conn_destroy =
 | 
			
		||||
        delete(conn, subscription_notification_path(conn, :destroy_multiple), %{
 | 
			
		||||
          "ids" => [notification3_id, notification4_id]
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      assert json_response(conn_destroy, 200) == %{}
 | 
			
		||||
 | 
			
		||||
      conn_res = get(conn2, subscription_notification_path(conn, :list))
 | 
			
		||||
 | 
			
		||||
      result = json_response(conn_res, 200)
 | 
			
		||||
 | 
			
		||||
      Enum.each(result, fn %{"id" => id} ->
 | 
			
		||||
        assert id in [notification1_id, notification2_id]
 | 
			
		||||
      end)
 | 
			
		||||
 | 
			
		||||
      assert length(Repo.all(SubscriptionNotification)) == 2
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
		Reference in a new issue