Merge branch 'phnt/mastoapi-misattribution-3381' into release/2.10-sec

This commit is contained in:
Lain Soykaf 2025-12-29 09:47:54 +04:00
commit 6c73ebe484
7 changed files with 651 additions and 44 deletions

View file

@ -261,23 +261,27 @@ defmodule Pleroma.ActivityTest do
test "add_by_params_query/3" do
user = insert(:user)
note = insert(:note_activity, user: user)
note_activity = insert(:note_activity, user: user)
insert(:add_activity, user: user, note: note)
insert(:add_activity, user: user, note: note)
insert(:add_activity, user: user, note_activity: note_activity)
insert(:add_activity, user: user, note_activity: note_activity)
insert(:add_activity, user: user)
assert Repo.aggregate(Activity, :count, :id) == 4
assert Repo.aggregate(Activity, :count, :id) == 5
add_query =
Activity.add_by_params_query(note.data["object"], user.ap_id, user.featured_address)
Activity.add_by_params_query(
note_activity.data["object"],
user.ap_id,
user.featured_address
)
assert Repo.aggregate(add_query, :count, :id) == 2
Repo.delete_all(add_query)
assert Repo.aggregate(add_query, :count, :id) == 0
assert Repo.aggregate(Activity, :count, :id) == 2
assert Repo.aggregate(Activity, :count, :id) == 3
end
describe "associated_object_id() sql function" do

View file

@ -827,9 +827,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
defp local_and_remote_activities do
remote_user = insert(:user, local: false, domain: "example.com")
announce_user = insert(:user)
local = insert(:note_activity)
remote = insert(:note_activity, local: false)
{:ok, local: local, remote: remote}
remote = insert(:note_activity, local: false, object_local: false, user: remote_user)
remote_note = insert(:note_activity, local: false, object_local: false)
local_activity_remote_object =
insert(:announce_activity, note_activity: remote_note, user: announce_user)
{:ok,
local: local, remote: remote, local_activity_remote_object: local_activity_remote_object}
end
defp local_and_remote_context_activities do
@ -872,7 +880,64 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
{:ok, remote_activity} = ObanHelpers.perform(job)
%{locals: [id1, id2], remote: remote_activity.id, context: context}
{:ok, %{id: local_to_local_react_id}} = CommonAPI.react_with_emoji(id1, local_user_2, "🦊")
{:ok, %{id: local_to_remote_react_id}} =
CommonAPI.react_with_emoji(remote_activity.id, local_user_1, "🦊")
{:ok, %{id: remote_to_local_react_id}} = CommonAPI.react_with_emoji(id1, remote_user, "🦊")
{:ok, %{id: remote_to_remote_react_id}} =
CommonAPI.react_with_emoji(remote_activity.id, remote_user, "🦊")
%{
locals: [id1, id2],
remote: remote_activity.id,
local_interactions: [local_to_local_react_id, local_to_remote_react_id],
remote_interactions: [remote_to_local_react_id, remote_to_remote_react_id],
context: context
}
end
defp extract_activity_ids_from_response(list) when is_list(list) do
list
|> Enum.map(& &1["id"])
end
defp all_ids_included?(checked, authority) when is_list(checked) and is_list(authority) do
set1 = MapSet.new(checked)
set2 = MapSet.new(authority)
MapSet.equal?(set1, set2)
end
defp local_interactions_to_remote do
interacted_user = insert(:user, local: false, domain: "example.com")
interacting_user = insert(:user)
announced_post =
insert(:note_activity, local: false, object_local: false, user: interacted_user)
emoji_reacted_post =
insert(:note_activity, local: false, object_local: false, user: interacted_user)
favorited_post =
insert(:note_activity, local: false, object_local: false, user: interacted_user)
announce = insert(:announce_activity, note_activity: announced_post, user: interacting_user)
emoji_react =
insert(:emoji_react_activity, note_activity: emoji_reacted_post, user: interacting_user)
{:ok, favorite} = CommonAPI.favorite(favorited_post.id, interacting_user)
{
:ok,
announce: announce,
emoji_react: emoji_react,
favorite: favorite,
interacted: interacted_user,
interacter: interacting_user
}
end
describe "status with restrict unauthenticated activities for local and remote" do
@ -882,7 +947,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
@ -891,18 +961,31 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
end
end
@ -911,9 +994,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
@ -922,13 +1016,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
end
end
@ -937,24 +1038,177 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Record not found"
}
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{local.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{remote.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
res_conn = get(conn, "/api/v1/statuses/#{local_activity_remote_object.id}")
assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200)
end
end
# Note: Activities of type Flag,Follow,Delete,Accept,Reject,Undo return 404
describe "status has correct attribution when fetching as" do
setup do: local_interactions_to_remote()
test "Add/Remove activity", %{conn: conn, interacter: user} do
add = insert(:add_activity, user: user)
add_id = add.id
remove = insert(:remove_activity, user: user)
remove_id = remove.id
user_id = user.id
# Schema validation fails:
# null value where integer expected at /pleroma/conversation_id
result1 =
conn
|> get("/api/v1/statuses/#{add_id}")
|> json_response(200)
assert match?(%{"id" => ^add_id, "account" => %{"id" => ^user_id}}, result1)
result2 =
conn
|> get("/api/v1/statuses/#{remove_id}")
|> json_response(200)
assert match?(%{"id" => ^remove_id, "account" => %{"id" => ^user_id}}, result2)
end
test "Announce activity", %{
conn: conn,
announce: activity,
interacter: interacter,
interacted: user
} do
announce_id = activity.id
announced_activity = Pleroma.Activity.get_create_by_object_ap_id(activity.data["object"])
announced_id = announced_activity.id
interacter_ap_id = interacter.id
user_id = user.id
result =
conn
|> get("/api/v1/statuses/#{activity.id}")
|> json_response_and_validate_schema(200)
assert match?(
%{
"id" => ^announce_id,
"account" => %{"id" => ^interacter_ap_id},
"reblog" => %{"account" => %{"id" => ^user_id}, "id" => ^announced_id}
},
result
)
end
test "Create activity", %{conn: conn, interacted: user} do
note_activity = insert(:note_activity, local: false, object_local: false, user: user)
note_activity_id = note_activity.id
user_id = user.id
result =
conn
|> get("/api/v1/statuses/#{note_activity_id}")
|> json_response_and_validate_schema(200)
assert match?(%{"id" => ^note_activity_id, "account" => %{"id" => ^user_id}}, result)
end
test "EmojiReact activity", %{conn: conn, emoji_react: activity, interacted: user} do
emoji_react_id = activity.id
user_id = user.id
result =
conn
|> get("/api/v1/statuses/#{emoji_react_id}")
|> json_response_and_validate_schema(200)
assert match?(%{"id" => ^emoji_react_id, "account" => %{"id" => ^user_id}}, result)
end
test "Like activity", %{conn: conn, favorite: activity, interacted: user} do
like_id = activity.id
user_id = user.id
result =
conn
|> get("/api/v1/statuses/#{like_id}")
|> json_response_and_validate_schema(200)
assert match?(%{"id" => ^like_id, "account" => %{"id" => ^user_id}}, result)
end
test "Update activity" do
%{conn: conn, user: user} = oauth_access(["write:statuses"])
user_id = user.id
{:ok, activity} = CommonAPI.post(user, %{status: "This will be edited"})
{:ok, updated_activity} = CommonAPI.update(activity, user, %{status: "edited"})
activity_id = activity.id
updated_activity_id = updated_activity.id
result1 =
conn
|> get("/api/v1/statuses/#{activity_id}")
|> json_response_and_validate_schema(200)
# Even though we ask for the original Create activity, updated post is served
assert match?(
%{
"id" => ^activity_id,
"account" => %{"id" => ^user_id},
"content" => "edited"
},
result1
)
# Schema validation fails:
# null value where integer expected at /pleroma/conversation_id
result2 =
conn
|> get("/api/v1/statuses/#{updated_activity_id}")
|> json_response(200)
assert match?(
%{
"id" => ^updated_activity_id,
"account" => %{"id" => ^user_id},
"content" => "edited"
},
result2
)
end
end
@ -1014,18 +1268,35 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
assert json_response_and_validate_schema(res_conn, 200) == []
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
assert length(json_response_and_validate_schema(res_conn, 200)) == 3
end
end
@ -1034,19 +1305,36 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
remote_id = remote.id
assert [%{"id" => ^remote_id}] = json_response_and_validate_schema(res_conn, 200)
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
assert length(json_response_and_validate_schema(res_conn, 200)) == 3
end
end
@ -1055,22 +1343,40 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
test "if user is unauthenticated", %{
conn: conn,
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
local_id = local.id
assert [%{"id" => ^local_id}] = json_response_and_validate_schema(res_conn, 200)
end
test "if user is authenticated", %{local: local, remote: remote} do
test "if user is authenticated", %{
local: local,
remote: remote,
local_activity_remote_object: local_activity_remote_object
} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}")
res_conn =
get(
conn,
"/api/v1/statuses?id[]=#{local.id}&id[]=#{remote.id}&id[]=#{local_activity_remote_object.id}"
)
assert length(json_response_and_validate_schema(res_conn, 200)) == 2
assert length(json_response_and_validate_schema(res_conn, 200)) == 3
end
end
# Note: Context route on EmojiReact/Announce activities puts everything into the ancestors field
describe "getting status contexts restricted unauthenticated for local and remote" do
setup do: local_and_remote_context_activities()
@ -1096,6 +1402,40 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
}
end
test "if user is unauthenticated Activity interactions", %{
conn: conn,
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
@ -1129,6 +1469,47 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated Activity interactions", %{
locals: [post_id, reply_id],
remote: remote_reply_id,
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
%{conn: conn} = oauth_access(["read"])
all_ids = [post_id, reply_id, remote_reply_id]
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
%{"ancestors" => ancestors1, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids1 = extract_activity_ids_from_response(ancestors1)
assert all_ids_included?(ancestor_ids1, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
%{"ancestors" => ancestors2, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids2 = extract_activity_ids_from_response(ancestors2)
assert all_ids_included?(ancestor_ids2, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
%{"ancestors" => ancestors3, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids3 = extract_activity_ids_from_response(ancestors3)
assert all_ids_included?(ancestor_ids3, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
%{"ancestors" => ancestors4, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids4 = extract_activity_ids_from_response(ancestors4)
assert all_ids_included?(ancestor_ids4, all_ids)
end
end
describe "getting status contexts restricted unauthenticated for local" do
@ -1178,6 +1559,45 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert remote_reply_id in descendant_ids
end
test "if user is unauthenticated Activity interactions", %{
conn: conn,
remote: remote_reply_id,
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
%{"ancestors" => ancestors1, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids1 = extract_activity_ids_from_response(ancestors1)
assert all_ids_included?(ancestor_ids1, [remote_reply_id])
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
%{"ancestors" => ancestors2, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids2 = extract_activity_ids_from_response(ancestors2)
assert all_ids_included?(ancestor_ids2, [remote_reply_id])
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
%{"ancestors" => ancestors3, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids3 = extract_activity_ids_from_response(ancestors3)
assert all_ids_included?(ancestor_ids3, [remote_reply_id])
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
%{"ancestors" => ancestors4, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids4 = extract_activity_ids_from_response(ancestors4)
assert all_ids_included?(ancestor_ids4, [remote_reply_id])
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
@ -1211,6 +1631,47 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated Activity interactions", %{
locals: [post_id, reply_id],
remote: remote_reply_id,
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
%{conn: conn} = oauth_access(["read"])
all_ids = [post_id, reply_id, remote_reply_id]
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
%{"ancestors" => ancestors1, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids1 = extract_activity_ids_from_response(ancestors1)
assert all_ids_included?(ancestor_ids1, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
%{"ancestors" => ancestors2, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids2 = extract_activity_ids_from_response(ancestors2)
assert all_ids_included?(ancestor_ids2, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
%{"ancestors" => ancestors3, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids3 = extract_activity_ids_from_response(ancestors3)
assert all_ids_included?(ancestor_ids3, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
%{"ancestors" => ancestors4, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids4 = extract_activity_ids_from_response(ancestors4)
assert all_ids_included?(ancestor_ids4, all_ids)
end
end
describe "getting status contexts restricted unauthenticated for remote" do
@ -1260,6 +1721,46 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert remote_reply_id not in descendant_ids
end
test "if user is unauthenticated Activity interactions", %{
conn: conn,
locals: [post_id, reply_id],
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
all_ids = [post_id, reply_id]
%{"ancestors" => ancestors1, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids1 = extract_activity_ids_from_response(ancestors1)
assert all_ids_included?(ancestor_ids1, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
%{"ancestors" => ancestors2, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids2 = extract_activity_ids_from_response(ancestors2)
assert all_ids_included?(ancestor_ids2, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
%{"ancestors" => ancestors3, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids3 = extract_activity_ids_from_response(ancestors3)
assert all_ids_included?(ancestor_ids3, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
%{"ancestors" => ancestors4, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids4 = extract_activity_ids_from_response(ancestors4)
assert all_ids_included?(ancestor_ids4, all_ids)
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
@ -1293,6 +1794,47 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated Activity interactions", %{
locals: [post_id, reply_id],
remote: remote_reply_id,
local_interactions: [local_to_local, local_to_remote],
remote_interactions: [remote_to_local, remote_to_remote]
} do
%{conn: conn} = oauth_access(["read"])
all_ids = [post_id, reply_id, remote_reply_id]
res_conn = get(conn, "/api/v1/statuses/#{local_to_local}/context")
%{"ancestors" => ancestors1, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids1 = extract_activity_ids_from_response(ancestors1)
assert all_ids_included?(ancestor_ids1, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{local_to_remote}/context")
%{"ancestors" => ancestors2, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids2 = extract_activity_ids_from_response(ancestors2)
assert all_ids_included?(ancestor_ids2, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_local}/context")
%{"ancestors" => ancestors3, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids3 = extract_activity_ids_from_response(ancestors3)
assert all_ids_included?(ancestor_ids3, all_ids)
res_conn = get(conn, "/api/v1/statuses/#{remote_to_remote}/context")
%{"ancestors" => ancestors4, "descendants" => []} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids4 = extract_activity_ids_from_response(ancestors4)
assert all_ids_included?(ancestor_ids4, all_ids)
end
end
describe "deleting a status" do

View file

@ -102,11 +102,19 @@ defmodule Pleroma.Factory do
user = attrs[:user] || insert(:user)
object_id =
if attrs[:object_local] == false do
# Must not match our Endpoint URL in the test env
"https://example.com/objects/#{Ecto.UUID.generate()}"
else
Pleroma.Web.ActivityPub.Utils.generate_object_id()
end
data = %{
"type" => "Note",
"content" => text,
"source" => text,
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
"id" => object_id,
"actor" => user.ap_id,
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"published" => DateTime.utc_now() |> DateTime.to_iso8601(),
@ -297,27 +305,27 @@ defmodule Pleroma.Factory do
featured_collection_activity(attrs, "Add")
end
def remove_activity_factor(attrs \\ %{}) do
def remove_activity_factory(attrs \\ %{}) do
featured_collection_activity(attrs, "Remove")
end
defp featured_collection_activity(attrs, type) do
user = attrs[:user] || insert(:user)
note = attrs[:note] || insert(:note, user: user)
note_activity = attrs[:note_activity] || insert(:note_activity, user: user)
data_attrs =
attrs
|> Map.get(:data_attrs, %{})
|> Map.put(:type, type)
attrs = Map.drop(attrs, [:user, :note, :data_attrs])
attrs = Map.drop(attrs, [:user, :note_activity, :data_attrs])
data =
%{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"target" => user.featured_address,
"object" => note.data["object"],
"actor" => note.data["actor"],
"object" => note_activity.data["object"],
"actor" => note_activity.data["actor"],
"type" => "Add",
"to" => [Pleroma.Constants.as_public()],
"cc" => [user.follower_address]
@ -361,14 +369,25 @@ defmodule Pleroma.Factory do
def note_activity_factory(attrs \\ %{}) do
user = attrs[:user] || insert(:user)
note = attrs[:note] || insert(:note, user: user)
object_local = if attrs[:object_local] == false, do: false, else: true
note = attrs[:note] || insert(:note, user: user, object_local: object_local)
activity_id =
if attrs[:local] == false do
# Same domain as in note Object factory, it doesn't make sense
# to create mismatched Create Activities with an ID coming from
# a different domain than the Object
"https://example.com/activities/#{Ecto.UUID.generate()}"
else
Pleroma.Web.ActivityPub.Utils.generate_activity_id()
end
data_attrs = attrs[:data_attrs] || %{}
attrs = Map.drop(attrs, [:user, :note, :data_attrs])
attrs = Map.drop(attrs, [:user, :note, :data_attrs, :object_local])
data =
%{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"id" => activity_id,
"type" => "Create",
"actor" => note.data["actor"],
"to" => note.data["to"],
@ -408,15 +427,17 @@ defmodule Pleroma.Factory do
def announce_activity_factory(attrs \\ %{}) do
note_activity = attrs[:note_activity] || insert(:note_activity)
object = Object.normalize(note_activity, fetch: false)
user = attrs[:user] || insert(:user)
data = %{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"type" => "Announce",
"actor" => note_activity.actor,
"object" => note_activity.data["id"],
"to" => [user.follower_address, note_activity.data["actor"]],
"actor" => user.ap_id,
"object" => object.data["id"],
"to" => [user.follower_address, object.data["actor"]],
"cc" => ["https://www.w3.org/ns/activitystreams#Public"],
"context" => note_activity.data["context"]
"context" => object.data["context"]
}
%Pleroma.Activity{
@ -426,6 +447,28 @@ defmodule Pleroma.Factory do
}
end
def emoji_react_activity_factory(attrs \\ %{}) do
note_activity = attrs[:note_activity] || insert(:note_activity)
object = Object.normalize(note_activity, fetch: false)
user = attrs[:user] || insert(:user)
data = %{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"actor" => user.ap_id,
"type" => "EmojiReact",
"object" => object.data["id"],
"to" => [user.follower_address, object.data["actor"]],
"cc" => ["https://www.w3.org/ns/activitystreams#Public"],
"published_at" => DateTime.utc_now() |> DateTime.to_iso8601(),
"context" => object.data["context"],
"content" => "😀"
}
%Pleroma.Activity{
data: data
}
end
def like_activity_factory(attrs \\ %{}) do
note_activity = attrs[:note_activity] || insert(:note_activity)
object = Object.normalize(note_activity, fetch: false)