commit: 45611c9881bf53d23478464c0b8c08b52310dd31
parent c06fcc7f5ded25968138a7170414ab1c17477ad9
Author: nicole mikołajczyk <me@mkljczk.pl>
Date: Wed, 17 Dec 2025 20:52:08 +0100
Merge branch 'mastodon-quote-id-api' into 'develop'
Support `quoted_status_id` parameter in post creation request
See merge request pleroma/pleroma!4392
Diffstat:
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
@@ -620,6 +620,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],
@@ -640,15 +654,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,
@@ -664,7 +669,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
@@ -865,7 +865,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
@@ -437,8 +437,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})
@@ -509,7 +511,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
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.PleromaAPI.StatusControllerTest do
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