pin/unpin for activities with expires_at option
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 4 Sep 2020 08:40:32 +0000 (11:40 +0300)
committerrinpatch <rinpatch@sdf.org>
Thu, 10 Sep 2020 18:50:41 +0000 (21:50 +0300)
lib/pleroma/activity.ex
lib/pleroma/user.ex
lib/pleroma/workers/purge_expired_activity.ex
test/web/mastodon_api/controllers/status_controller_test.exs
test/workers/purge_expired_activity_test.exs

index 84aba9572a7fb9bf49971eee41ca54ddcf9bde1b..17af042573f22ccad27cbf29d4d87e7d149f9541 100644 (file)
@@ -343,9 +343,4 @@ defmodule Pleroma.Activity do
     actor = user_actor(activity)
     activity.id in actor.pinned_activities
   end
-
-  @spec pinned_by_actor?(Activity.t(), User.t()) :: boolean()
-  def pinned_by_actor?(%Activity{id: id}, %User{} = user) do
-    id in user.pinned_activities
-  end
 end
index f323fc6edcc0fbec15ab17e4844764c41e0f5c40..e73d199648f616d0a57a1c9ad2014cc83fc77ac9 100644 (file)
@@ -2315,6 +2315,11 @@ defmodule Pleroma.User do
       max_pinned_statuses = Config.get([:instance, :max_pinned_statuses], 0)
       params = %{pinned_activities: user.pinned_activities ++ [id]}
 
+      # if pinned activity was scheduled for deletion, we remove job
+      if expiration = Pleroma.Workers.PurgeExpiredActivity.get_expiration(id) do
+        Oban.cancel_job(expiration.id)
+      end
+
       user
       |> cast(params, [:pinned_activities])
       |> validate_length(:pinned_activities,
@@ -2327,9 +2332,19 @@ defmodule Pleroma.User do
     |> update_and_set_cache()
   end
 
-  def remove_pinnned_activity(user, %Pleroma.Activity{id: id}) do
+  def remove_pinnned_activity(user, %Pleroma.Activity{id: id, data: data}) do
     params = %{pinned_activities: List.delete(user.pinned_activities, id)}
 
+    # if pinned activity was scheduled for deletion, we reschedule it for deletion
+    if data["expires_at"] do
+      {:ok, expires_at, _} = DateTime.from_iso8601(data["expires_at"])
+
+      Pleroma.Workers.PurgeExpiredActivity.enqueue(%{
+        activity_id: id,
+        expires_at: expires_at
+      })
+    end
+
     user
     |> cast(params, [:pinned_activities])
     |> update_and_set_cache()
index 4be1461949fd056b439aa5808433fefd251ede08..f981eda8eca9573b6dc31dd4853d276a49cce573 100644 (file)
@@ -31,18 +31,8 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do
   @impl true
   def perform(%Oban.Job{args: %{"activity_id" => id}}) do
     with %Activity{} = activity <- find_activity(id),
-         %Pleroma.User{} = user <- find_user(activity.object.data["actor"]),
-         false <- pinned_by_actor?(activity, user) do
+         %Pleroma.User{} = user <- find_user(activity.object.data["actor"]) do
       Pleroma.Web.CommonAPI.delete(activity.id, user)
-    else
-      :pinned_by_actor ->
-        # if activity is pinned, schedule deletion on next day
-        enqueue(%{activity_id: id, expires_at: DateTime.add(DateTime.utc_now(), 24 * 3600)})
-
-        :ok
-
-      error ->
-        error
     end
   end
 
@@ -74,12 +64,6 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do
     end
   end
 
-  defp pinned_by_actor?(activity, user) do
-    with true <- Activity.pinned_by_actor?(activity, user) do
-      :pinned_by_actor
-    end
-  end
-
   def get_expiration(id) do
     from(j in Oban.Job,
       where: j.state == "scheduled",
index 17a156be8a4bbb1239bc4a242dd3f858f1c4dbae..82ea7389869b965fc6371640e2ffb6eb577b4e87 100644 (file)
@@ -115,8 +115,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
           "expires_in" => expires_in
         })
 
-      assert fourth_response =
-               %{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
+      assert %{"id" => fourth_id} = json_response_and_validate_schema(conn_four, 200)
 
       assert Activity.get_by_id(fourth_id)
 
@@ -1142,6 +1141,52 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
                |> post("/api/v1/statuses/#{activity_two.id}/pin")
                |> json_response_and_validate_schema(400)
     end
+
+    test "on pin removes deletion job, on unpin reschedule deletion" do
+      %{conn: conn} = oauth_access(["write:accounts", "write:statuses"])
+      expires_in = 2 * 60 * 60
+
+      expires_at = DateTime.add(DateTime.utc_now(), expires_in)
+
+      assert %{"id" => id} =
+               conn
+               |> put_req_header("content-type", "application/json")
+               |> post("api/v1/statuses", %{
+                 "status" => "oolong",
+                 "expires_in" => expires_in
+               })
+               |> json_response_and_validate_schema(200)
+
+      assert_enqueued(
+        worker: Pleroma.Workers.PurgeExpiredActivity,
+        args: %{activity_id: id},
+        scheduled_at: expires_at
+      )
+
+      assert %{"id" => ^id, "pinned" => true} =
+               conn
+               |> put_req_header("content-type", "application/json")
+               |> post("/api/v1/statuses/#{id}/pin")
+               |> json_response_and_validate_schema(200)
+
+      refute_enqueued(
+        worker: Pleroma.Workers.PurgeExpiredActivity,
+        args: %{activity_id: id},
+        scheduled_at: expires_at
+      )
+
+      assert %{"id" => ^id, "pinned" => false} =
+               conn
+               |> put_req_header("content-type", "application/json")
+               |> post("/api/v1/statuses/#{id}/unpin")
+               |> json_response_and_validate_schema(200)
+
+      assert_enqueued(
+        worker: Pleroma.Workers.PurgeExpiredActivity,
+        args: %{activity_id: id},
+        scheduled_at: expires_at
+      )
+    end
   end
 
   describe "cards" do
index 736d7d5673e4bbf7dc847b8cd19a13f35dd92306..8b5dc9fd208d694d64cbd90f772fe35f3a3c4844 100644 (file)
@@ -44,25 +44,4 @@ defmodule Pleroma.Workers.PurgeExpiredActivityTest do
 
     assert %Oban.Job{} = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
   end
-
-  test "don't delete pinned posts, schedule deletion on next day" do
-    activity = insert(:note_activity)
-
-    assert {:ok, _} =
-             PurgeExpiredActivity.enqueue(%{
-               activity_id: activity.id,
-               expires_at: DateTime.utc_now(),
-               validate: false
-             })
-
-    user = Pleroma.User.get_by_ap_id(activity.actor)
-    {:ok, activity} = Pleroma.Web.CommonAPI.pin(activity.id, user)
-
-    assert %{success: 1, failure: 0} ==
-             Oban.drain_queue(queue: :activity_expiration, with_scheduled: true)
-
-    job = Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
-
-    assert DateTime.diff(job.scheduled_at, DateTime.add(DateTime.utc_now(), 24 * 3600)) in [0, 1]
-  end
 end