Merge branch 'replies_collection' into 'develop'
Provide full replies collection in ActivityPub objects (ported from akkoma) See merge request pleroma/pleroma!4370
This commit is contained in:
commit
1a313fa30c
17 changed files with 508 additions and 158 deletions
|
|
@ -430,7 +430,133 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "/objects/:uuid/replies" do
|
||||
test "it renders the top-level collection", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
note = insert(:note_activity)
|
||||
note = Pleroma.Activity.get_by_id_with_object(note.id)
|
||||
uuid = String.split(note.object.data["id"], "/") |> List.last()
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: note.id})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}/replies")
|
||||
|
||||
assert match?(
|
||||
%{
|
||||
"id" => _,
|
||||
"type" => "OrderedCollection",
|
||||
"totalItems" => 1,
|
||||
"first" => %{
|
||||
"id" => _,
|
||||
"type" => "OrderedCollectionPage",
|
||||
"orderedItems" => [_]
|
||||
}
|
||||
},
|
||||
json_response(conn, 200)
|
||||
)
|
||||
end
|
||||
|
||||
test "first page id includes `?page=true`", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note = insert(:note_activity)
|
||||
note = Pleroma.Activity.get_by_id_with_object(note.id)
|
||||
uuid = String.split(note.object.data["id"], "/") |> List.last()
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: note.id})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}/replies")
|
||||
|
||||
%{"id" => collection_id, "first" => %{"id" => page_id, "partOf" => part_of}} =
|
||||
json_response(conn, 200)
|
||||
|
||||
assert part_of == collection_id
|
||||
assert String.contains?(page_id, "page=true")
|
||||
end
|
||||
|
||||
test "unknown query params do not crash the endpoint", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note = insert(:note_activity)
|
||||
note = Pleroma.Activity.get_by_id_with_object(note.id)
|
||||
uuid = String.split(note.object.data["id"], "/") |> List.last()
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: note.id})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}/replies?unknown_param=1")
|
||||
|
||||
assert %{"type" => "OrderedCollection"} = json_response(conn, 200)
|
||||
end
|
||||
|
||||
test "it renders a collection page", %{
|
||||
conn: conn
|
||||
} do
|
||||
user = insert(:user)
|
||||
note = insert(:note_activity)
|
||||
note = Pleroma.Activity.get_by_id_with_object(note.id)
|
||||
uuid = String.split(note.object.data["id"], "/") |> List.last()
|
||||
|
||||
{:ok, r1} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: note.id})
|
||||
|
||||
{:ok, r2} =
|
||||
CommonAPI.post(user, %{status: "reply2", in_reply_to_status_id: note.id})
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{status: "reply3", in_reply_to_status_id: note.id})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}/replies?page=true&min_id=#{r1.object.id}&limit=1")
|
||||
|
||||
expected_uris = [r2.object.data["id"]]
|
||||
|
||||
assert match?(
|
||||
%{
|
||||
"id" => _,
|
||||
"type" => "OrderedCollectionPage",
|
||||
"prev" => _,
|
||||
"next" => _,
|
||||
"orderedItems" => ^expected_uris
|
||||
},
|
||||
json_response(conn, 200)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "/activities/:uuid" do
|
||||
test "it does not include a top-level replies collection on activities", %{conn: conn} do
|
||||
clear_config([:activitypub, :note_replies_output_limit], 1)
|
||||
|
||||
activity = insert(:note_activity)
|
||||
activity = Activity.get_by_id_with_object(activity.id)
|
||||
|
||||
uuid = String.split(activity.data["id"], "/") |> List.last()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/activities/#{uuid}")
|
||||
|
||||
res = json_response(conn, 200)
|
||||
|
||||
refute Map.has_key?(res, "replies")
|
||||
assert get_in(res, ["object", "replies", "id"]) == activity.object.data["id"] <> "/replies"
|
||||
end
|
||||
|
||||
test "it doesn't return a local-only activity", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "test", visibility: "local"})
|
||||
|
|
|
|||
|
|
@ -696,12 +696,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
describe "set_replies/1" do
|
||||
setup do: clear_config([:activitypub, :note_replies_output_limit], 2)
|
||||
|
||||
test "returns unmodified object if activity doesn't have self-replies" do
|
||||
test "still provides reply collection id even if activity doesn't have replies yet" do
|
||||
data = Jason.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
|
||||
assert Transmogrifier.set_replies(data) == data
|
||||
object = data["object"] |> Map.delete("replies")
|
||||
modified = Transmogrifier.set_replies(object)
|
||||
|
||||
refute object["replies"]
|
||||
assert modified["replies"]
|
||||
assert match?(%{"id" => "http" <> _, "totalItems" => 0}, modified["replies"])
|
||||
# first page should be omitted if there are no entries anyway
|
||||
refute modified["replies"]["first"]
|
||||
end
|
||||
|
||||
test "sets `replies` collection with a limited number of self-replies" do
|
||||
test "sets `replies` collection with a limited number of replies, preferring oldest" do
|
||||
[user, another_user] = insert_list(2, :user)
|
||||
|
||||
{:ok, %{id: id1} = activity} = CommonAPI.post(user, %{status: "1"})
|
||||
|
|
@ -730,7 +737,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
object = Object.normalize(activity, fetch: false)
|
||||
replies_uris = Enum.map([self_reply1, self_reply2], fn a -> a.object.data["id"] end)
|
||||
|
||||
assert %{"type" => "Collection", "items" => ^replies_uris} =
|
||||
assert %{"type" => "OrderedCollection", "first" => %{"orderedItems" => ^replies_uris}} =
|
||||
Transmogrifier.set_replies(object.data)["replies"]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,9 +49,39 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
|
|||
replies_uris = [self_reply1.object.data["id"]]
|
||||
result = ObjectView.render("object.json", %{object: refresh_record(activity)})
|
||||
|
||||
assert %{"type" => "Collection", "items" => ^replies_uris} =
|
||||
assert %{
|
||||
"type" => "OrderedCollection",
|
||||
"id" => _,
|
||||
"first" => %{"orderedItems" => ^replies_uris}
|
||||
} =
|
||||
get_in(result, ["object", "replies"])
|
||||
end
|
||||
|
||||
test "renders a replies collection on its own" do
|
||||
user = insert(:user)
|
||||
activity = insert(:note_activity, user: user)
|
||||
activity = Pleroma.Activity.get_by_id_with_object(activity.id)
|
||||
|
||||
{:ok, r1} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: activity.id})
|
||||
|
||||
{:ok, r2} =
|
||||
CommonAPI.post(user, %{status: "reply1", in_reply_to_status_id: activity.id})
|
||||
|
||||
replies_uris = [r1.object.data["id"], r2.object.data["id"]]
|
||||
|
||||
result =
|
||||
ObjectView.render("object_replies.json", %{
|
||||
render_params: %{object_ap_id: activity.object.data["id"]}
|
||||
})
|
||||
|
||||
%{
|
||||
"type" => "OrderedCollection",
|
||||
"id" => _,
|
||||
"totalItems" => 2,
|
||||
"first" => %{"orderedItems" => ^replies_uris}
|
||||
} = result
|
||||
end
|
||||
end
|
||||
|
||||
test "renders a like activity" do
|
||||
|
|
|
|||
|
|
@ -169,6 +169,18 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
user = Map.merge(user, %{hide_followers_count: false, hide_followers: true})
|
||||
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
|
||||
end
|
||||
|
||||
test "does not hide follower items based on `hide_follows`" do
|
||||
user = insert(:user)
|
||||
follower = insert(:user)
|
||||
{:ok, user, _follower, _activity} = CommonAPI.follow(user, follower)
|
||||
|
||||
user = Map.merge(user, %{hide_followers: false, hide_follows: true})
|
||||
follower_ap_id = follower.ap_id
|
||||
|
||||
assert %{"first" => %{"orderedItems" => [^follower_ap_id]}} =
|
||||
UserView.render("followers.json", %{user: user})
|
||||
end
|
||||
end
|
||||
|
||||
describe "following" do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue