logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/
commit: c1699c6e60a90ad969e73d44b40c82a17cc76f00
parent 606c9ae4b1ae6456fe4a17a9328c35ba87bbd652
Author: nicole mikołajczyk <git@mkljczk.pl>
Date:   Fri, 31 Oct 2025 15:50:13 +0100

Support `quoted_status_id` parameter in post creation request

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>

Diffstat:

Achangelog.d/mastodon-quote-id-api.change1+
Mlib/pleroma/web/api_spec/operations/status_operation.ex26++++++++++++++++----------
Mlib/pleroma/web/common_api/activity_draft.ex6+++++-
Mtest/pleroma/web/activity_pub/activity_pub_test.exs2+-
Mtest/pleroma/web/activity_pub/transmogrifier_test.exs2+-
Mtest/pleroma/web/common_api/activity_draft_test.exs24+++++++++++++++---------
Mtest/pleroma/web/common_api_test.exs36+++++++++++++++++++++++++-----------
Mtest/pleroma/web/mastodon_api/views/status_view_test.exs8+++++---
Mtest/pleroma/web/pleroma_api/controllers/status_controller_test.exs2+-
9 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/changelog.d/mastodon-quote-id-api.change b/changelog.d/mastodon-quote-id-api.change @@ -0,0 +1 @@ +Support `quoted_status_id` parameter in post creation request diff --git a/lib/pleroma/web/api_spec/operations/status_operation.ex b/lib/pleroma/web/api_spec/operations/status_operation.ex @@ -599,6 +599,20 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do nullable: true, description: "ISO 639 language code for this status." }, + visibility: %Schema{ + nullable: true, + anyOf: [ + VisibilityScope, + %Schema{type: :string, description: "`list:LIST_ID`", example: "LIST:123"} + ], + description: + "Visibility of the posted status. Besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID`" + }, + quoted_status_id: %Schema{ + nullable: true, + allOf: [FlakeID], + description: "ID of the status being quoted, if any" + }, # Pleroma-specific properties: preview: %Schema{ allOf: [BooleanLike], @@ -619,15 +633,6 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do description: "A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply" }, - visibility: %Schema{ - nullable: true, - anyOf: [ - VisibilityScope, - %Schema{type: :string, description: "`list:LIST_ID`", example: "LIST:123"} - ], - description: - "Visibility of the posted status. Besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID`" - }, expires_in: %Schema{ nullable: true, type: :integer, @@ -643,7 +648,8 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do quote_id: %Schema{ nullable: true, allOf: [FlakeID], - description: "ID of the status being quoted, if any" + description: "Deprecated in favor of `quoted_status_id`", + deprecated: true } }, example: %{ diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex @@ -160,7 +160,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do defp in_reply_to(draft), do: draft - defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do + defp quote_post(%{params: %{quoted_status_id: id}} = draft) when not_empty_string(id) do case Activity.get_by_id_with_object(id) do %Activity{} = activity -> %__MODULE__{draft | quote_post: activity} @@ -170,6 +170,10 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do end end + defp quote_post(%{params: %{quote_id: id}} = draft) when not_empty_string(id) do + quote_post(%{draft | params: Map.put(draft.params, :quoted_status_id, id)}) + end + defp quote_post(draft), do: draft defp in_reply_to_conversation(draft) do diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -831,7 +831,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, activity} = CommonAPI.post(user, %{status: "1", visibility: "public"}) ap_id = activity.data["id"] - quote_data = %{status: "1", quote_id: activity.id} + quote_data = %{status: "1", quoted_status_id: activity.id} # public {:ok, _} = CommonAPI.post(user2, Map.put(quote_data, :visibility, "public")) diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -615,7 +615,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do user = insert(:user) {:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"}) - {:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id}) + {:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quoted_status_id: quoted_post.id}) {:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data) diff --git a/test/pleroma/web/common_api/activity_draft_test.exs b/test/pleroma/web/common_api/activity_draft_test.exs @@ -20,14 +20,20 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraftTest do {:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"}) {:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"}) - {:error, _} = ActivityDraft.create(user, %{status: "nice", quote_id: direct.id}) - {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: private.id}) - {:error, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: private.id}) - {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: unlisted.id}) - {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: unlisted.id}) - {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: local.id}) - {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: local.id}) - {:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: public.id}) - {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: public.id}) + {:error, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: direct.id}) + {:ok, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: private.id}) + + {:error, _} = + ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: private.id}) + + {:ok, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: unlisted.id}) + + {:ok, _} = + ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: unlisted.id}) + + {:ok, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: local.id}) + {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: local.id}) + {:ok, _} = ActivityDraft.create(user, %{status: "nice", quoted_status_id: public.id}) + {:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quoted_status_id: public.id}) end end diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs @@ -830,7 +830,9 @@ defmodule Pleroma.Web.CommonAPITest do user = insert(:user) {:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"}) - {:ok, quote_post} = CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id}) + + {:ok, quote_post} = + CommonAPI.post(user, %{status: "nice post", quoted_status_id: quoted.id}) quoted = Object.normalize(quoted) quote_post = Object.normalize(quote_post) @@ -841,13 +843,25 @@ defmodule Pleroma.Web.CommonAPITest do refute quoted.data["actor"] in quote_post.data["to"] end + test "it supports fallback from `quote_id`" do + user = insert(:user) + + {:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"}) + {:ok, quote_post} = CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id}) + + quoted = Object.normalize(quoted) + quote_post = Object.normalize(quote_post) + + assert quote_post.data["quoteUrl"] == quoted.data["id"] + end + test "quote posting with explicit addressing doesn't mention the OP" do user = insert(:user) {:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"}) {:ok, quote_post} = - CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id, to: []}) + CommonAPI.post(user, %{status: "nice post", quoted_status_id: quoted.id, to: []}) assert Object.normalize(quote_post).data["to"] == [Pleroma.Constants.as_public()] end @@ -862,15 +876,15 @@ defmodule Pleroma.Web.CommonAPITest do {:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"}) {:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"}) - {:error, _} = CommonAPI.post(user, %{status: "nice", quote_id: direct.id}) - {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: private.id}) - {:error, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: private.id}) - {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: unlisted.id}) - {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: unlisted.id}) - {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: local.id}) - {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: local.id}) - {:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: public.id}) - {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: public.id}) + {:error, _} = CommonAPI.post(user, %{status: "nice", quoted_status_id: direct.id}) + {:ok, _} = CommonAPI.post(user, %{status: "nice", quoted_status_id: private.id}) + {:error, _} = CommonAPI.post(another_user, %{status: "nice", quoted_status_id: private.id}) + {:ok, _} = CommonAPI.post(user, %{status: "nice", quoted_status_id: unlisted.id}) + {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quoted_status_id: unlisted.id}) + {:ok, _} = CommonAPI.post(user, %{status: "nice", quoted_status_id: local.id}) + {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quoted_status_id: local.id}) + {:ok, _} = CommonAPI.post(user, %{status: "nice", quoted_status_id: public.id}) + {:ok, _} = CommonAPI.post(another_user, %{status: "nice", quoted_status_id: public.id}) end test "it properly mentions punycode domain" do diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs @@ -436,8 +436,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do post = insert(:note_activity) user = insert(:user) - {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id}) - {:ok, quoted_quote_post} = CommonAPI.post(user, %{status: "yo", quote_id: quote_post.id}) + {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quoted_status_id: post.id}) + + {:ok, quoted_quote_post} = + CommonAPI.post(user, %{status: "yo", quoted_status_id: quote_post.id}) status = StatusView.render("show.json", %{activity: quoted_quote_post}) @@ -508,7 +510,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do post = insert(:note_activity) user = insert(:user) - {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id}) + {:ok, quote_post} = CommonAPI.post(user, %{status: "he", quoted_status_id: post.id}) {:ok, repost} = CommonAPI.repeat(quote_post.id, user) [status] = StatusView.render("index.json", %{activities: [repost], as: :activity}) diff --git a/test/pleroma/web/pleroma_api/controllers/status_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/status_controller_test.exs @@ -20,7 +20,7 @@ defmodule Pleroma.Web.PleromaAPI.StatusControllerTest do user = insert(:user) activity = insert(:note_activity) - {:ok, quote_post} = CommonAPI.post(user, %{status: "quoat", quote_id: activity.id}) + {:ok, quote_post} = CommonAPI.post(user, %{status: "quoat", quoted_status_id: activity.id}) response = conn