Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into fine_grained_moderation_privileges
This commit is contained in:
commit
60df2d8a97
308 changed files with 36503 additions and 1957 deletions
|
|
@ -247,6 +247,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert json_response(response, 200) == ObjectView.render("object.json", %{object: object})
|
||||
end
|
||||
|
||||
test "does not return local-only objects for remote users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
reader = insert(:user, local: false)
|
||||
|
||||
{:ok, post} =
|
||||
CommonAPI.post(user, %{status: "test @#{reader.nickname}", visibility: "local"})
|
||||
|
||||
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
|
||||
|
||||
object = Object.normalize(post, fetch: false)
|
||||
uuid = String.split(object.data["id"], "/") |> List.last()
|
||||
|
||||
assert response =
|
||||
conn
|
||||
|> assign(:user, reader)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}")
|
||||
|
||||
json_response(response, 404)
|
||||
end
|
||||
|
||||
test "it returns a json representation of the object with accept application/json", %{
|
||||
conn: conn
|
||||
} do
|
||||
|
|
@ -1297,6 +1318,35 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert outbox_endpoint == result["id"]
|
||||
end
|
||||
|
||||
test "it returns a local note activity when authenticated as local user", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
reader = insert(:user)
|
||||
{:ok, note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"})
|
||||
ap_id = note_activity.data["id"]
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> assign(:user, reader)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert %{"orderedItems" => [%{"id" => ^ap_id}]} = resp
|
||||
end
|
||||
|
||||
test "it does not return a local note activity when unauthenticated", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, _note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"})
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert %{"orderedItems" => []} = resp
|
||||
end
|
||||
|
||||
test "it returns a note activity in a collection", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
note_object = Object.normalize(note_activity, fetch: false)
|
||||
|
|
|
|||
|
|
@ -554,7 +554,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert activity.data["ok"] == data["ok"]
|
||||
assert activity.data["id"] == given_id
|
||||
assert activity.data["context"] == "blabla"
|
||||
assert activity.data["context_id"]
|
||||
end
|
||||
|
||||
test "adds a context when none is there" do
|
||||
|
|
@ -576,8 +575,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
assert is_binary(activity.data["context"])
|
||||
assert is_binary(object.data["context"])
|
||||
assert activity.data["context_id"]
|
||||
assert object.data["context_id"]
|
||||
end
|
||||
|
||||
test "adds an id to a given object if it lacks one and is a note and inserts it to the object database" do
|
||||
|
|
@ -1507,6 +1504,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
reporter_ap_id = reporter.ap_id
|
||||
target_ap_id = target_account.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id)
|
||||
|
||||
|
|
@ -1518,6 +1516,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
reported_activity: activity,
|
||||
content: content,
|
||||
activity_ap_id: activity_ap_id,
|
||||
object_ap_id: object_ap_id,
|
||||
activity_with_object: activity_with_object,
|
||||
reporter_ap_id: reporter_ap_id,
|
||||
target_ap_id: target_ap_id
|
||||
|
|
@ -1531,7 +1530,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
target_account: target_account,
|
||||
reported_activity: reported_activity,
|
||||
content: content,
|
||||
activity_ap_id: activity_ap_id,
|
||||
object_ap_id: object_ap_id,
|
||||
activity_with_object: activity_with_object,
|
||||
reporter_ap_id: reporter_ap_id,
|
||||
target_ap_id: target_ap_id
|
||||
|
|
@ -1547,7 +1546,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity_with_object.object.data["published"],
|
||||
"actor" =>
|
||||
|
|
@ -1571,6 +1570,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
context: context,
|
||||
target_account: target_account,
|
||||
reported_activity: reported_activity,
|
||||
object_ap_id: object_ap_id,
|
||||
content: content
|
||||
},
|
||||
Utils,
|
||||
|
|
@ -1585,8 +1585,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
content: content
|
||||
})
|
||||
|
||||
new_data =
|
||||
put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]])
|
||||
new_data = put_in(activity.data, ["object"], [target_account.ap_id, object_ap_id])
|
||||
|
||||
assert_called(Utils.maybe_federate(%{activity | data: new_data}))
|
||||
end
|
||||
|
|
@ -1612,7 +1611,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
})
|
||||
|
||||
assert Repo.aggregate(Activity, :count, :id) == 1
|
||||
assert Repo.aggregate(Object, :count, :id) == 2
|
||||
assert Repo.aggregate(Object, :count, :id) == 1
|
||||
assert Repo.aggregate(Notification, :count, :id) == 0
|
||||
end
|
||||
end
|
||||
|
|
@ -1665,7 +1664,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
end
|
||||
|
||||
describe "fetch_follow_information_for_user" do
|
||||
test "syncronizes following/followers counters" do
|
||||
test "synchronizes following/followers counters" do
|
||||
user =
|
||||
insert(:user,
|
||||
local: false,
|
||||
|
|
@ -1836,9 +1835,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
"target" => ^new_ap_id,
|
||||
"type" => "Move"
|
||||
},
|
||||
local: true
|
||||
local: true,
|
||||
recipients: recipients
|
||||
} = activity
|
||||
|
||||
assert old_user.follower_address in recipients
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => old_user.id,
|
||||
|
|
@ -1869,6 +1871,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert {:error, "Target account must have the origin in `alsoKnownAs`"} =
|
||||
ActivityPub.move(old_user, new_user)
|
||||
end
|
||||
|
||||
test "do not move remote user following relationships" do
|
||||
%{ap_id: old_ap_id} = old_user = insert(:user)
|
||||
%{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
|
||||
follower_remote = insert(:user, local: false)
|
||||
|
||||
User.follow(follower_remote, old_user)
|
||||
|
||||
assert User.following?(follower_remote, old_user)
|
||||
|
||||
assert {:ok, activity} = ActivityPub.move(old_user, new_user)
|
||||
|
||||
assert %Activity{
|
||||
actor: ^old_ap_id,
|
||||
data: %{
|
||||
"actor" => ^old_ap_id,
|
||||
"object" => ^old_ap_id,
|
||||
"target" => ^new_ap_id,
|
||||
"type" => "Move"
|
||||
},
|
||||
local: true
|
||||
} = activity
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => old_user.id,
|
||||
"target_id" => new_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
assert User.following?(follower_remote, old_user)
|
||||
refute User.following?(follower_remote, new_user)
|
||||
end
|
||||
end
|
||||
|
||||
test "doesn't retrieve replies activities with exclude_replies" do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
import Pleroma.Factory
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy
|
||||
|
||||
@linkless_message %{
|
||||
|
|
@ -49,11 +50,23 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
|
||||
assert user.note_count == 0
|
||||
|
||||
message =
|
||||
@linkful_message
|
||||
|> Map.put("actor", user.ap_id)
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"actor" => user.ap_id,
|
||||
"object" => %{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "<a href='https://example.com'>hi world!</a>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"content" => "mew"
|
||||
}
|
||||
}
|
||||
|
||||
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
||||
{:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message)
|
||||
end
|
||||
|
||||
test "it allows posts with links for local users" do
|
||||
|
|
@ -67,6 +80,18 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
|
||||
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "it disallows posts with links in history" do
|
||||
user = insert(:user, local: false)
|
||||
|
||||
assert user.note_count == 0
|
||||
|
||||
message =
|
||||
@linkful_message
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with old user" do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
|
||||
|
||||
describe "rewrites summary" do
|
||||
|
|
@ -35,10 +36,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
|||
assert {:ok, res} = EnsureRePrepended.filter(message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
end
|
||||
|
||||
test "it adds `re:` to history" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
|
||||
test "it accepts Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
end
|
||||
|
||||
describe "skip filter" do
|
||||
test "it skip if type isn't 'Create'" do
|
||||
test "it skip if type isn't 'Create' or 'Update'" do
|
||||
message = %{
|
||||
"type" => "Annotation",
|
||||
"object" => %{"summary" => "object-summary"}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
|
|||
|
||||
alias Pleroma.Constants
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
|
|
@ -161,4 +162,98 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
|
|||
assert filtered ==
|
||||
"<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> </span>I'ma tired...</p>"
|
||||
end
|
||||
|
||||
test "aware of history" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
wario = insert(:user, nickname: "wario")
|
||||
|
||||
{:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => wario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expected =
|
||||
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => ^expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
|
||||
}
|
||||
}} = MRF.filter_one(ForceMentionsInContent, activity)
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
wario = insert(:user, nickname: "wario")
|
||||
|
||||
{:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Update",
|
||||
"actor" => wario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expected =
|
||||
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => ^expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
|
||||
}
|
||||
}} = MRF.filter_one(ForceMentionsInContent, activity)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,6 +20,76 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
|
|||
assert modified["object"]["sensitive"]
|
||||
end
|
||||
|
||||
test "it is history-aware" do
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "hey",
|
||||
"tag" => []
|
||||
}
|
||||
}
|
||||
|
||||
activity_data =
|
||||
activity
|
||||
|> put_in(
|
||||
["object", "formerRepresentations"],
|
||||
%{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
Map.put(
|
||||
activity["object"],
|
||||
"tag",
|
||||
[%{"type" => "Hashtag", "name" => "#nsfw"}]
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
{:ok, modified} =
|
||||
Pleroma.Web.ActivityPub.MRF.filter_one(
|
||||
Pleroma.Web.ActivityPub.MRF.HashtagPolicy,
|
||||
activity_data
|
||||
)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"]
|
||||
end
|
||||
|
||||
test "it works with Update" do
|
||||
activity = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => "hey",
|
||||
"tag" => []
|
||||
}
|
||||
}
|
||||
|
||||
activity_data =
|
||||
activity
|
||||
|> put_in(
|
||||
["object", "formerRepresentations"],
|
||||
%{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
Map.put(
|
||||
activity["object"],
|
||||
"tag",
|
||||
[%{"type" => "Hashtag", "name" => "#nsfw"}]
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
{:ok, modified} =
|
||||
Pleroma.Web.ActivityPub.MRF.filter_one(
|
||||
Pleroma.Web.ActivityPub.MRF.HashtagPolicy,
|
||||
activity_data
|
||||
)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"]
|
||||
end
|
||||
|
||||
test "it doesn't sets the sensitive property with irrelevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,54 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
KeywordPolicy.filter(message)
|
||||
end)
|
||||
end
|
||||
|
||||
test "rejects if string matches in history" do
|
||||
clear_config([:mrf_keyword, :reject], ["pun"])
|
||||
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "rejects Updates" do
|
||||
clear_config([:mrf_keyword, :reject], ["pun"])
|
||||
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delisting from ftl based on keywords" do
|
||||
|
|
@ -157,6 +205,31 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
not (["https://www.w3.org/ns/activitystreams#Public"] == result["to"])
|
||||
end)
|
||||
end
|
||||
|
||||
test "delists if string matches in history" do
|
||||
clear_config([:mrf_keyword, :federated_timeline_removal], ["pun"])
|
||||
|
||||
message = %{
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, result} = KeywordPolicy.filter(message)
|
||||
assert ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"]
|
||||
refute ["https://www.w3.org/ns/activitystreams#Public"] == result["to"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "replacing keywords" do
|
||||
|
|
@ -221,5 +294,63 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
result == "ZFS is free software"
|
||||
end)
|
||||
end
|
||||
|
||||
test "replaces keyword if string matches in history" do
|
||||
clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}])
|
||||
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"object" => %{
|
||||
"content" => "ZFS is opensource",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"content" => "ZFS is opensource mew mew", "summary" => ""}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => "ZFS is free software",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => "ZFS is free software mew mew"}]
|
||||
}
|
||||
}
|
||||
}} = KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "replaces keyword in Updates" do
|
||||
clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}])
|
||||
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"object" => %{
|
||||
"content" => "ZFS is opensource",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"content" => "ZFS is opensource mew mew", "summary" => ""}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => "ZFS is free software",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => "ZFS is free software mew mew"}]
|
||||
}
|
||||
}
|
||||
}} = KeywordPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
|
||||
|
||||
import Mock
|
||||
|
|
@ -22,6 +23,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
@message_with_history %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "content",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "content",
|
||||
"attachment" => [
|
||||
%{"url" => [%{"href" => "http://example.com/image.jpg"}]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup do: clear_config([:media_proxy, :enabled], true)
|
||||
|
||||
test "it prefetches media proxy URIs" do
|
||||
|
|
@ -50,4 +70,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
refute called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
|
||||
test "history-aware" do
|
||||
Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
|
||||
MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history)
|
||||
|
||||
assert called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
|
||||
MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history |> Map.put("type", "Update"))
|
||||
|
||||
assert called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -151,4 +151,27 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicyTest do
|
|||
|
||||
assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"}
|
||||
end
|
||||
|
||||
test "works with Update" do
|
||||
message = %{
|
||||
"actor" => "http://localhost:4001/users/testuser",
|
||||
"cc" => ["http://localhost:4001/users/testuser/followers"],
|
||||
"object" => %{
|
||||
"actor" => "http://localhost:4001/users/testuser",
|
||||
"attachment" => [],
|
||||
"cc" => ["http://localhost:4001/users/testuser/followers"],
|
||||
"source" => "",
|
||||
"to" => [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type" => "Note"
|
||||
},
|
||||
"to" => [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type" => "Update"
|
||||
}
|
||||
|
||||
assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy
|
||||
|
||||
test "it clears content object" do
|
||||
|
|
@ -20,6 +21,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
|
|||
assert res["object"]["content"] == ""
|
||||
end
|
||||
|
||||
test "history-aware" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => ".",
|
||||
"attachment" => "image",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => ".", "attachment" => "image"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message)
|
||||
|
||||
assert %{
|
||||
"content" => "",
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => ".",
|
||||
"attachment" => "image",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => ".", "attachment" => "image"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message)
|
||||
|
||||
assert %{
|
||||
"content" => "",
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
@messages [
|
||||
%{
|
||||
"type" => "Create",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup
|
||||
|
||||
@html_sample """
|
||||
|
|
@ -16,24 +17,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
|
|||
<script>alert('hacked')</script>
|
||||
"""
|
||||
|
||||
test "it filter html tags" do
|
||||
expected = """
|
||||
<b>this is in bold</b>
|
||||
<p>this is a paragraph</p>
|
||||
this is a linebreak<br/>
|
||||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
@expected """
|
||||
<b>this is in bold</b>
|
||||
<p>this is a paragraph</p>
|
||||
this is a linebreak<br/>
|
||||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
|
||||
test "it filter html tags" do
|
||||
message = %{"type" => "Create", "object" => %{"content" => @html_sample}}
|
||||
|
||||
assert {:ok, res} = NormalizeMarkup.filter(message)
|
||||
assert res["object"]["content"] == expected
|
||||
assert res["object"]["content"] == @expected
|
||||
end
|
||||
|
||||
test "it skips filter if type isn't `Create`" do
|
||||
test "history-aware" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => @html_sample,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message)
|
||||
|
||||
assert %{
|
||||
"content" => @expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => @html_sample,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message)
|
||||
|
||||
assert %{
|
||||
"content" => @expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "it skips filter if type isn't `Create` or `Update`" do
|
||||
message = %{"type" => "Note", "object" => %{}}
|
||||
|
||||
assert {:ok, res} = NormalizeMarkup.filter(message)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
|
|
@ -31,6 +32,54 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
|||
test "a basic note validates", %{note: note} do
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a note from factory validates" do
|
||||
note = insert(:note)
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Note with history" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
|
||||
{:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
|
||||
|
||||
{:ok, %{"object" => external_rep}} =
|
||||
Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
|
||||
|
||||
%{external_rep: external_rep}
|
||||
end
|
||||
|
||||
test "edited note", %{external_rep: external_rep} do
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"tag" => [_]}]}} = external_rep
|
||||
|
||||
{:ok, validate_res, []} = ObjectValidator.validate(external_rep, [])
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} =
|
||||
validate_res
|
||||
end
|
||||
|
||||
test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do
|
||||
external_rep = Map.put(external_rep, "formerRepresentations", %{})
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
|
||||
test "edited note, badly-formed history item", %{external_rep: external_rep} do
|
||||
history_item =
|
||||
Enum.at(external_rep["formerRepresentations"]["orderedItems"], 0)
|
||||
|> Map.put("type", "Foo")
|
||||
|
||||
external_rep =
|
||||
put_in(
|
||||
external_rep,
|
||||
["formerRepresentations", "orderedItems"],
|
||||
[history_item]
|
||||
)
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
end
|
||||
|
||||
test "a Note from Roadhouse validates" do
|
||||
|
|
@ -43,4 +92,28 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
|||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a note with an attachment should work", _ do
|
||||
insert(:user, %{ap_id: "https://owncast.localhost.localdomain/federation/user/streamer"})
|
||||
|
||||
note =
|
||||
"test/fixtures/owncast-note-with-attachment.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a Note without replies/first/items validates" do
|
||||
insert(:user, ap_id: "https://mastodon.social/users/emelie")
|
||||
|
||||
note =
|
||||
"test/fixtures/tesla_mock/status.emelie.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|> pop_in(["replies", "first", "items"])
|
||||
|> elem(1)
|
||||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
|
|||
import Pleroma.Factory
|
||||
|
||||
describe "attachments" do
|
||||
test "fails without url" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
"name" => "",
|
||||
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
|
||||
"type" => "Document"
|
||||
}
|
||||
|
||||
assert {:error, _cng} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
end
|
||||
|
||||
test "works with honkerific attachments" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidatorTest do
|
|||
{:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"])
|
||||
meta = [object_data: ObjectValidator.stringify_keys(object_data)]
|
||||
|
||||
%{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
assert %{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
end
|
||||
|
||||
test "a Create/Note with mismatched context is invalid" do
|
||||
test "a Create/Note with mismatched context uses the Note's context" do
|
||||
user = insert(:user)
|
||||
|
||||
note = %{
|
||||
|
|
@ -54,6 +54,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidatorTest do
|
|||
{:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"])
|
||||
meta = [object_data: ObjectValidator.stringify_keys(object_data)]
|
||||
|
||||
%{valid?: false} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
validated = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
|
||||
assert validated.valid?
|
||||
assert {:context, note["context"]} in validated.changes
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
|
|||
test "returns an error if the object can't be updated by the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|
|
@ -40,5 +40,129 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
|
|||
|
||||
assert {:error, _cng} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
|
||||
test "validates as long as the object is same-origin with the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
assert {:ok, _update, []} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
|
||||
test "validates if the object is not of an Actor type" do
|
||||
note = insert(:note)
|
||||
updated_note = note.data |> Map.put("content", "edited content")
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, update, _} = Builder.update(other_user, updated_note)
|
||||
|
||||
assert {:ok, _update, _} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
end
|
||||
|
||||
describe "update note" do
|
||||
test "converts object into Pleroma's format" do
|
||||
mastodon_tags = [
|
||||
%{
|
||||
"icon" => %{
|
||||
"mediaType" => "image/png",
|
||||
"type" => "Image",
|
||||
"url" => "https://somewhere.org/emoji/url/1.png"
|
||||
},
|
||||
"id" => "https://somewhere.org/emoji/1",
|
||||
"name" => ":some_emoji:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "2021-04-07T11:00:00Z"
|
||||
}
|
||||
]
|
||||
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|> Map.put("tag", mastodon_tags)
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, [])
|
||||
|
||||
assert %{"emoji" => %{"some_emoji" => "https://somewhere.org/emoji/url/1.png"}} =
|
||||
meta[:object_data]
|
||||
end
|
||||
|
||||
test "returns no object_data in meta for a local Update" do
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, local: true)
|
||||
assert is_nil(meta[:object_data])
|
||||
end
|
||||
|
||||
test "returns object_data in meta for a remote Update" do
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, local: false)
|
||||
assert meta[:object_data]
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, [])
|
||||
assert meta[:object_data]
|
||||
end
|
||||
end
|
||||
|
||||
describe "update with history" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
|
||||
{:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
|
||||
{:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
|
||||
%{external_rep: external_rep}
|
||||
end
|
||||
|
||||
test "edited note", %{external_rep: external_rep} do
|
||||
{:ok, _validate_res, meta} = ObjectValidator.validate(external_rep, [])
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} =
|
||||
meta[:object_data]
|
||||
end
|
||||
|
||||
test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do
|
||||
external_rep = put_in(external_rep, ["object", "formerRepresentations"], %{})
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
|
||||
test "edited note, badly-formed history item", %{external_rep: external_rep} do
|
||||
history_item =
|
||||
Enum.at(external_rep["object"]["formerRepresentations"]["orderedItems"], 0)
|
||||
|> Map.put("type", "Foo")
|
||||
|
||||
external_rep =
|
||||
put_in(
|
||||
external_rep,
|
||||
["object", "formerRepresentations", "orderedItems"],
|
||||
[history_item]
|
||||
)
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -118,7 +118,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
describe "update users" do
|
||||
setup do
|
||||
user = insert(:user, local: false)
|
||||
{:ok, update_data, []} = Builder.update(user, %{"id" => user.ap_id, "name" => "new name!"})
|
||||
|
||||
{:ok, update_data, []} =
|
||||
Builder.update(user, %{"id" => user.ap_id, "type" => "Person", "name" => "new name!"})
|
||||
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
%{user: user, update_data: update_data, update: update}
|
||||
|
|
@ -140,6 +143,298 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "update notes" do
|
||||
setup do
|
||||
make_time = fn ->
|
||||
Pleroma.Web.ActivityPub.Utils.make_date()
|
||||
end
|
||||
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user, data: %{"published" => make_time.()})
|
||||
_note_activity = insert(:note_activity, note: note)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("summary", "edited summary")
|
||||
|> Map.put("content", "edited content")
|
||||
|> Map.put("updated", make_time.())
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_note)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
%{
|
||||
user: user,
|
||||
note: note,
|
||||
object_id: note.id,
|
||||
update_data: update_data,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
}
|
||||
end
|
||||
|
||||
test "it updates the note", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
updated_time = updated_note["updated"]
|
||||
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
assert %{
|
||||
"summary" => "edited summary",
|
||||
"content" => "edited content",
|
||||
"updated" => ^updated_time
|
||||
} = new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with no updated attribute in object", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
updated_note = Map.drop(updated_note, ["updated"])
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with updated attribute older than what we have in the original object",
|
||||
%{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, -10)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with updated attribute older than the last Update", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, +10)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, update_time, _} = DateTime.from_iso8601(old_note.data["updated"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(update_time, -5)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it updates using object_data", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
updated_note = Map.put(updated_note, "summary", "mew mew")
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "mew mew", "content" => "edited content"} = new_note.data
|
||||
end
|
||||
|
||||
test "it records the original note in formerRepresentations", %{
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
||||
|
||||
assert [Map.drop(note.data, ["id", "formerRepresentations"])] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 1
|
||||
end
|
||||
|
||||
test "it puts the original note at the front of formerRepresentations", %{
|
||||
user: user,
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
second_updated_note =
|
||||
note.data
|
||||
|> Map.put("summary", "edited summary 2")
|
||||
|> Map.put("content", "edited content 2")
|
||||
|> Map.put(
|
||||
"updated",
|
||||
first_edit["updated"]
|
||||
|> DateTime.from_iso8601()
|
||||
|> elem(1)
|
||||
|> DateTime.add(10)
|
||||
|> DateTime.to_iso8601()
|
||||
)
|
||||
|
||||
{:ok, second_update_data, []} = Builder.update(user, second_updated_note)
|
||||
{:ok, update, _meta} = ActivityPub.persist(second_update_data, local: true)
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: second_updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary 2", "content" => "edited content 2"} = new_note
|
||||
|
||||
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
||||
first_edit = Map.drop(first_edit, ["id", "formerRepresentations"])
|
||||
|
||||
assert [first_edit, original_version] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 2
|
||||
end
|
||||
|
||||
test "it does not prepend to formerRepresentations if no actual changes are made", %{
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
updated_note =
|
||||
updated_note
|
||||
|> Map.put(
|
||||
"updated",
|
||||
first_edit["updated"]
|
||||
|> DateTime.from_iso8601()
|
||||
|> elem(1)
|
||||
|> DateTime.add(10)
|
||||
|> DateTime.to_iso8601()
|
||||
)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
||||
|
||||
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
||||
|
||||
assert [original_version] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "update questions" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
question =
|
||||
insert(:question,
|
||||
user: user,
|
||||
data: %{"published" => Pleroma.Web.ActivityPub.Utils.make_date()}
|
||||
)
|
||||
|
||||
%{user: user, data: question.data, id: question.id}
|
||||
end
|
||||
|
||||
test "allows updating choice count without generating edit history", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|> Map.put("updated", Pleroma.Web.ActivityPub.Utils.make_date())
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
|
||||
test "allows updating choice count without updated field", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
|
||||
test "allows updating choice count with updated field same as the creation date", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|> Map.put("updated", data["published"])
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
end
|
||||
|
||||
describe "EmojiReact objects" do
|
||||
setup do
|
||||
poster = insert(:user)
|
||||
|
|
@ -544,9 +839,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
]) do
|
||||
{:ok, announce, _} = SideEffects.handle(announce)
|
||||
|
||||
assert called(
|
||||
Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce)
|
||||
)
|
||||
assert called(Pleroma.Web.Streamer.stream(["user", "list"], announce))
|
||||
|
||||
assert called(Pleroma.Web.Push.send(:_))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,6 +37,37 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
|
|||
assert match?([["👌", _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it works for incoming unqualified emoji reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hello"})
|
||||
|
||||
# woman detective emoji, unqualified
|
||||
unqualified_emoji = [0x1F575, 0x200D, 0x2640] |> List.to_string()
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/emoji-reaction.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|> Map.put("content", unqualified_emoji)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == other_user.ap_id
|
||||
assert data["type"] == "EmojiReact"
|
||||
assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
|
||||
assert data["object"] == activity.data["object"]
|
||||
# woman detective emoji, fully qualified
|
||||
emoji = [0x1F575, 0xFE0F, 0x200D, 0x2640, 0xFE0F] |> List.to_string()
|
||||
assert data["content"] == emoji
|
||||
|
||||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert match?([[emoji, _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it reject invalid emoji reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
|
|
|
|||
|
|
@ -707,4 +707,42 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "the standalone note uses its own ID when context is missing" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
|
||||
activity =
|
||||
"test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity)
|
||||
object = Object.normalize(modified, fetch: false)
|
||||
|
||||
assert object.data["context"] == object.data["id"]
|
||||
assert modified.data["context"] == object.data["id"]
|
||||
end
|
||||
|
||||
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
|
||||
activity =
|
||||
"test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
object =
|
||||
activity["object"]
|
||||
|> Map.put("inReplyTo", "https://404.site/object/went-to-buy-milk")
|
||||
|
||||
activity =
|
||||
activity
|
||||
|> Map.put("object", object)
|
||||
|
||||
{:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity)
|
||||
object = Object.normalize(modified, fetch: false)
|
||||
|
||||
assert object.data["context"] == object.data["inReplyTo"]
|
||||
assert modified.data["context"] == object.data["inReplyTo"]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
|
|||
assert object.data["context"] ==
|
||||
"tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation"
|
||||
|
||||
assert object.data["context_id"]
|
||||
|
||||
assert object.data["anyOf"] == []
|
||||
|
||||
assert Enum.sort(object.data["oneOf"]) ==
|
||||
|
|
@ -68,7 +66,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
|
|||
reply_object = Object.normalize(reply_activity, fetch: false)
|
||||
|
||||
assert reply_object.data["context"] == object.data["context"]
|
||||
assert reply_object.data["context_id"] == object.data["context_id"]
|
||||
end
|
||||
|
||||
test "Mastodon Question activity with HTML tags in plaintext" do
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity.data["id"],
|
||||
"id" => activity.object.data["id"],
|
||||
"content" => "test post",
|
||||
"published" => object.data["published"],
|
||||
"actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
|
|
@ -108,15 +108,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert activity.data["type"] == "Move"
|
||||
end
|
||||
|
||||
test "a reply with mismatched context is rejected" do
|
||||
insert(:user, ap_id: "https://macgirvin.com/channel/mike")
|
||||
test "it fixes both the Create and object contexts in a reply" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
insert(:user, ap_id: "https://p.helene.moe/users/helene")
|
||||
|
||||
note_activity =
|
||||
"test/fixtures/roadhouse-create-activity.json"
|
||||
create_activity =
|
||||
"test/fixtures/create-pleroma-reply-to-misskey-thread.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
assert {:error, _} = Transmogrifier.handle_incoming(note_activity)
|
||||
assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(create_activity)
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert activity.data["context"] == object.data["context"]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -227,7 +232,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert is_nil(modified["object"]["like_count"])
|
||||
assert is_nil(modified["object"]["announcements"])
|
||||
assert is_nil(modified["object"]["announcement_count"])
|
||||
assert is_nil(modified["object"]["context_id"])
|
||||
assert is_nil(modified["object"]["generator"])
|
||||
end
|
||||
|
||||
|
|
@ -242,7 +246,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert is_nil(modified["object"]["like_count"])
|
||||
assert is_nil(modified["object"]["announcements"])
|
||||
assert is_nil(modified["object"]["announcement_count"])
|
||||
assert is_nil(modified["object"]["context_id"])
|
||||
assert is_nil(modified["object"]["likes"])
|
||||
end
|
||||
|
||||
|
|
@ -312,6 +315,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
assert url == "http://localhost:4001/emoji/dino%20walking.gif"
|
||||
end
|
||||
|
||||
test "Updates of Notes are handled" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
|
||||
{:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew :blank:"})
|
||||
|
||||
{:ok, prepared} = Transmogrifier.prepare_outgoing(update.data)
|
||||
|
||||
assert %{
|
||||
"content" => "mew mew :blank:",
|
||||
"tag" => [%{"name" => ":blank:", "type" => "Emoji"}],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "everybody do the dinosaur :dinosaur:",
|
||||
"tag" => [%{"name" => ":dinosaur:", "type" => "Emoji"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
} = prepared["object"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "user upgrade" do
|
||||
|
|
@ -575,4 +600,43 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert Transmogrifier.fix_attachments(object) == expected
|
||||
end
|
||||
end
|
||||
|
||||
describe "prepare_object/1" do
|
||||
test "it processes history" do
|
||||
original = %{
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"generator" => %{},
|
||||
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
processed = Transmogrifier.prepare_object(original)
|
||||
|
||||
history_item = Enum.at(processed["formerRepresentations"]["orderedItems"], 0)
|
||||
|
||||
refute Map.has_key?(history_item, "generator")
|
||||
|
||||
assert [%{"name" => ":blobcat:"}] = history_item["tag"]
|
||||
end
|
||||
|
||||
test "it works when there is no or bad history" do
|
||||
original = %{
|
||||
"formerRepresentations" => %{
|
||||
"items" => [
|
||||
%{
|
||||
"generator" => %{},
|
||||
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
processed = Transmogrifier.prepare_object(original)
|
||||
assert processed["formerRepresentations"] == original["formerRepresentations"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -429,7 +429,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
object = Object.normalize(note_activity, fetch: false)
|
||||
res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
|
||||
assert res["context"] == object.data["id"]
|
||||
assert res["context_id"] == object.id
|
||||
assert res["id"]
|
||||
assert res["published"]
|
||||
end
|
||||
|
|
@ -437,7 +436,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
test "returns map with fake id and published data" do
|
||||
assert %{
|
||||
"context" => "pleroma:fakecontext",
|
||||
"context_id" => -1,
|
||||
"id" => "pleroma:fakeid",
|
||||
"published" => _
|
||||
} = Utils.lazy_put_activity_defaults(%{}, true)
|
||||
|
|
@ -454,13 +452,11 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
})
|
||||
|
||||
assert res["context"] == object.data["id"]
|
||||
assert res["context_id"] == object.id
|
||||
assert res["id"]
|
||||
assert res["published"]
|
||||
assert res["object"]["id"]
|
||||
assert res["object"]["published"]
|
||||
assert res["object"]["context"] == object.data["id"]
|
||||
assert res["object"]["context_id"] == object.id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -477,7 +473,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
content = "foobar"
|
||||
|
||||
target_ap_id = target_account.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
res =
|
||||
Utils.make_flag_data(
|
||||
|
|
@ -493,7 +489,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" =>
|
||||
|
|
@ -508,6 +504,49 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
"state" => "open"
|
||||
} = res
|
||||
end
|
||||
|
||||
test "returns map with Flag object with a non-Create Activity" do
|
||||
reporter = insert(:user)
|
||||
posting_account = insert(:user)
|
||||
target_account = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(posting_account, %{status: "foobar"})
|
||||
{:ok, like} = CommonAPI.favorite(target_account, activity.id)
|
||||
context = Utils.generate_context_id()
|
||||
content = "foobar"
|
||||
|
||||
target_ap_id = target_account.ap_id
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
res =
|
||||
Utils.make_flag_data(
|
||||
%{
|
||||
actor: reporter,
|
||||
context: context,
|
||||
account: target_account,
|
||||
statuses: [%{"id" => like.data["id"]}],
|
||||
content: content
|
||||
},
|
||||
%{}
|
||||
)
|
||||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" =>
|
||||
AccountView.render("show.json", %{user: posting_account, skip_visibility_check: true})
|
||||
}
|
||||
|
||||
assert %{
|
||||
"type" => "Flag",
|
||||
"content" => ^content,
|
||||
"context" => ^context,
|
||||
"object" => [^target_ap_id, ^note_obj],
|
||||
"state" => "open"
|
||||
} = res
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_announce_to_object/2" do
|
||||
|
|
|
|||
|
|
@ -81,4 +81,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
|
|||
assert result["object"] == object.data["id"]
|
||||
assert result["type"] == "Announce"
|
||||
end
|
||||
|
||||
test "renders an undo announce activity" do
|
||||
note = insert(:note_activity)
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, announce} = CommonAPI.repeat(note.id, user)
|
||||
{:ok, undo} = CommonAPI.unrepeat(note.id, user)
|
||||
|
||||
result = ObjectView.render("object.json", %{object: undo})
|
||||
|
||||
assert result["id"] == undo.data["id"]
|
||||
assert result["object"] == announce.data["id"]
|
||||
assert result["type"] == "Undo"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
|
||||
test "Renders a user, including the public key" do
|
||||
user = insert(:user)
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
|
||||
|
|
@ -55,7 +54,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
|
||||
test "Does not add an avatar image if the user hasn't set one" do
|
||||
user = insert(:user)
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
refute result["icon"]
|
||||
|
|
@ -67,8 +65,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
banner: %{"url" => [%{"href" => "https://somebanner"}]}
|
||||
)
|
||||
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
assert result["icon"]["url"] == "https://someurl"
|
||||
assert result["image"]["url"] == "https://somebanner"
|
||||
|
|
@ -89,7 +85,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
describe "endpoints" do
|
||||
test "local users have a usable endpoints structure" do
|
||||
user = insert(:user)
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
|
||||
|
|
@ -105,7 +100,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
|
||||
test "remote users have an empty endpoints structure" do
|
||||
user = insert(:user, local: false)
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
|
||||
|
|
@ -115,7 +109,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
|
||||
test "instance users do not expose oAuth endpoints" do
|
||||
user = insert(:user, nickname: nil, local: true)
|
||||
{:ok, user} = User.ensure_keys_present(user)
|
||||
|
||||
result = UserView.render("user.json", %{user: user})
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deleted chat message ##{cm_ref.id}"
|
||||
"@#{admin.nickname} deleted chat message ##{message.id}"
|
||||
|
||||
assert result["id"] == cm_ref.id
|
||||
refute MessageReference.get_by_id(cm_ref.id)
|
||||
|
|
|
|||
|
|
@ -317,14 +317,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
end
|
||||
|
||||
test "save configs setting without explicit key", %{conn: conn} do
|
||||
level = Application.get_env(:quack, :level)
|
||||
meta = Application.get_env(:quack, :meta)
|
||||
webhook_url = Application.get_env(:quack, :webhook_url)
|
||||
adapter = Application.get_env(:http, :adapter)
|
||||
send_user_agent = Application.get_env(:http, :send_user_agent)
|
||||
user_agent = Application.get_env(:http, :user_agent)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:quack, :level, level)
|
||||
Application.put_env(:quack, :meta, meta)
|
||||
Application.put_env(:quack, :webhook_url, webhook_url)
|
||||
Application.put_env(:http, :adapter, adapter)
|
||||
Application.put_env(:http, :send_user_agent, send_user_agent)
|
||||
Application.put_env(:http, :user_agent, user_agent)
|
||||
end)
|
||||
|
||||
conn =
|
||||
|
|
@ -333,19 +333,19 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":level",
|
||||
value: ":info"
|
||||
group: ":http",
|
||||
key: ":adapter",
|
||||
value: [":someval"]
|
||||
},
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":meta",
|
||||
value: [":none"]
|
||||
group: ":http",
|
||||
key: ":send_user_agent",
|
||||
value: true
|
||||
},
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":webhook_url",
|
||||
value: "https://hooks.slack.com/services/KEY"
|
||||
group: ":http",
|
||||
key: ":user_agent",
|
||||
value: [":default"]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -353,30 +353,30 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"configs" => [
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":level",
|
||||
"value" => ":info",
|
||||
"db" => [":level"]
|
||||
"group" => ":http",
|
||||
"key" => ":adapter",
|
||||
"value" => [":someval"],
|
||||
"db" => [":adapter"]
|
||||
},
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":meta",
|
||||
"value" => [":none"],
|
||||
"db" => [":meta"]
|
||||
"group" => ":http",
|
||||
"key" => ":send_user_agent",
|
||||
"value" => true,
|
||||
"db" => [":send_user_agent"]
|
||||
},
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":webhook_url",
|
||||
"value" => "https://hooks.slack.com/services/KEY",
|
||||
"db" => [":webhook_url"]
|
||||
"group" => ":http",
|
||||
"key" => ":user_agent",
|
||||
"value" => [":default"],
|
||||
"db" => [":user_agent"]
|
||||
}
|
||||
],
|
||||
"need_reboot" => false
|
||||
}
|
||||
|
||||
assert Application.get_env(:quack, :level) == :info
|
||||
assert Application.get_env(:quack, :meta) == [:none]
|
||||
assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY"
|
||||
assert Application.get_env(:http, :adapter) == [:someval]
|
||||
assert Application.get_env(:http, :send_user_agent) == true
|
||||
assert Application.get_env(:http, :user_agent) == [:default]
|
||||
end
|
||||
|
||||
test "saving config with partial update", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.InstanceDocumentControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
import Pleroma.Factory
|
||||
|
||||
@dir "test/tmp/instance_static"
|
||||
|
|
|
|||
|
|
@ -68,6 +68,32 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
assert notes["content"] == "this is an admin note"
|
||||
end
|
||||
|
||||
test "renders reported content even if the status is deleted", %{conn: conn} do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
activity = Activity.normalize(activity)
|
||||
|
||||
{:ok, %{id: report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id]
|
||||
})
|
||||
|
||||
CommonAPI.delete(activity.id, target_user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/reports/#{report_id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response["id"] == report_id
|
||||
|
||||
assert [status] = response["statuses"]
|
||||
assert activity.object.data["id"] == status["uri"]
|
||||
assert activity.object.data["content"] == status["content"]
|
||||
end
|
||||
|
||||
test "returns 404 when report id is invalid", %{conn: conn} do
|
||||
conn = get(conn, "/api/pleroma/admin/reports/test")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
||||
alias Pleroma.Builders.UserBuilder
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
|
|
@ -273,22 +272,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "context_to_conversation_id" do
|
||||
test "creates a mapping object" do
|
||||
conversation_id = Utils.context_to_conversation_id("random context")
|
||||
object = Object.get_by_ap_id("random context")
|
||||
|
||||
assert conversation_id == object.id
|
||||
end
|
||||
|
||||
test "returns an existing mapping for an existing object" do
|
||||
{:ok, object} = Object.context_mapping("random context") |> Repo.insert()
|
||||
conversation_id = Utils.context_to_conversation_id("random context")
|
||||
|
||||
assert conversation_id == object.id
|
||||
end
|
||||
end
|
||||
|
||||
describe "formats date to asctime" do
|
||||
test "when date is in ISO 8601 format" do
|
||||
date = DateTime.utc_now() |> DateTime.to_iso8601()
|
||||
|
|
@ -517,17 +500,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "conversation_id_to_context/1" do
|
||||
test "returns id" do
|
||||
object = insert(:note)
|
||||
assert Utils.conversation_id_to_context(object.id) == object.data["id"]
|
||||
end
|
||||
|
||||
test "returns error if object not found" do
|
||||
assert Utils.conversation_id_to_context("123") == {:error, "No such conversation"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "maybe_notify_mentioned_recipients/2" do
|
||||
test "returns recipients when activity is not `Create`" do
|
||||
activity = insert(:like_activity)
|
||||
|
|
|
|||
|
|
@ -61,9 +61,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
describe "blocking" do
|
||||
setup do
|
||||
blocker = insert(:user)
|
||||
blocked = insert(:user)
|
||||
User.follow(blocker, blocked)
|
||||
User.follow(blocked, blocker)
|
||||
blocked = insert(:user, local: false)
|
||||
CommonAPI.follow(blocker, blocked)
|
||||
CommonAPI.follow(blocked, blocker)
|
||||
CommonAPI.accept_follow_request(blocker, blocked)
|
||||
CommonAPI.accept_follow_request(blocked, blocked)
|
||||
%{blocker: blocker, blocked: blocked}
|
||||
end
|
||||
|
||||
|
|
@ -72,6 +74,9 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _ -> nil end do
|
||||
assert User.get_follow_state(blocker, blocked) == :follow_accept
|
||||
refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked))
|
||||
|
||||
assert {:ok, block} = CommonAPI.block(blocker, blocked)
|
||||
|
||||
assert block.local
|
||||
|
|
@ -79,6 +84,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
refute User.following?(blocker, blocked)
|
||||
refute User.following?(blocked, blocker)
|
||||
|
||||
refute User.get_follow_state(blocker, blocked)
|
||||
|
||||
assert %{data: %{"state" => "reject"}} =
|
||||
Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked)
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(block))
|
||||
end
|
||||
end
|
||||
|
|
@ -588,7 +598,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
|
||||
assert object.data["source"] == post
|
||||
assert object.data["source"]["content"] == post
|
||||
end
|
||||
|
||||
test "it filters out obviously bad tags when accepting a post as Markdown" do
|
||||
|
|
@ -605,7 +615,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>"
|
||||
assert object.data["source"] == post
|
||||
assert object.data["source"]["content"] == post
|
||||
end
|
||||
|
||||
test "it does not allow replies to direct messages that are not direct messages themselves" do
|
||||
|
|
@ -1092,10 +1102,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
target_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"})
|
||||
activity = Activity.normalize(activity)
|
||||
|
||||
reporter_ap_id = reporter.ap_id
|
||||
target_ap_id = target_user.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
reported_object_ap_id = activity.object.data["id"]
|
||||
comment = "foobar"
|
||||
|
||||
report_data = %{
|
||||
|
|
@ -1106,7 +1117,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => reported_object_ap_id,
|
||||
"content" => "foobar",
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" => AccountView.render("show.json", %{user: target_user})
|
||||
|
|
@ -1128,6 +1139,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
test "updates report state" do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
object = Object.normalize(activity)
|
||||
|
||||
{:ok, %Activity{id: report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
|
|
@ -1140,10 +1152,36 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
assert report.data["state"] == "resolved"
|
||||
|
||||
[reported_user, activity_id] = report.data["object"]
|
||||
[reported_user, object_id] = report.data["object"]
|
||||
|
||||
assert reported_user == target_user.ap_id
|
||||
assert activity_id == activity.data["id"]
|
||||
assert object_id == object.data["id"]
|
||||
end
|
||||
|
||||
test "updates report state, don't strip when report_strip_status is false" do
|
||||
clear_config([:instance, :report_strip_status], false)
|
||||
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
||||
{:ok, %Activity{id: report_id, data: report_data}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id]
|
||||
})
|
||||
|
||||
{:ok, report} = CommonAPI.update_report_state(report_id, "resolved")
|
||||
|
||||
assert report.data["state"] == "resolved"
|
||||
|
||||
[reported_user, reported_activity] = report.data["object"]
|
||||
|
||||
assert reported_user == target_user.ap_id
|
||||
assert is_map(reported_activity)
|
||||
|
||||
assert reported_activity["content"] ==
|
||||
report_data["object"] |> Enum.at(1) |> Map.get("content")
|
||||
end
|
||||
|
||||
test "does not update report state when state is unsupported" do
|
||||
|
|
@ -1543,4 +1581,128 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "update/3" do
|
||||
test "updates a post" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Map.has_key?(updated_object.data, "updated")
|
||||
end
|
||||
|
||||
test "does not change visibility" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1", visibility: "private"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Visibility.get_visibility(updated_object) == "private"
|
||||
assert Visibility.get_visibility(updated) == "private"
|
||||
end
|
||||
|
||||
test "updates a post with emoji" do
|
||||
[{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all()
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2 :#{emoji2}:"
|
||||
assert %{^emoji2 => _} = updated_object.data["emoji"]
|
||||
end
|
||||
|
||||
test "updates a post with emoji and federate properly" do
|
||||
[{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all()
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
|
||||
|
||||
clear_config([:instance, :federating], true)
|
||||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _p -> nil end do
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
|
||||
|
||||
assert updated.data["object"]["content"] == "updated 2 :#{emoji2}:"
|
||||
assert %{^emoji2 => _} = updated.data["object"]["emoji"]
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(updated))
|
||||
end
|
||||
end
|
||||
|
||||
test "editing a post that copied a remote title with remote emoji should keep that emoji" do
|
||||
remote_emoji_uri = "https://remote.org/emoji.png"
|
||||
|
||||
note =
|
||||
insert(
|
||||
:note,
|
||||
data: %{
|
||||
"summary" => ":remoteemoji:",
|
||||
"emoji" => %{
|
||||
"remoteemoji" => remote_emoji_uri
|
||||
},
|
||||
"tag" => [
|
||||
%{
|
||||
"type" => "Emoji",
|
||||
"name" => "remoteemoji",
|
||||
"icon" => %{"url" => remote_emoji_uri}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
note_activity = insert(:note_activity, note: note)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, reply} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "reply",
|
||||
spoiler_text: ":remoteemoji:",
|
||||
in_reply_to_id: note_activity.id
|
||||
})
|
||||
|
||||
assert reply.object.data["emoji"]["remoteemoji"] == remote_emoji_uri
|
||||
|
||||
{:ok, edit} =
|
||||
CommonAPI.update(user, reply, %{status: "reply mew mew", spoiler_text: ":remoteemoji:"})
|
||||
|
||||
edited_note = Pleroma.Object.normalize(edit)
|
||||
|
||||
assert edited_note.data["emoji"]["remoteemoji"] == remote_emoji_uri
|
||||
end
|
||||
|
||||
test "respects MRF" do
|
||||
user = insert(:user)
|
||||
|
||||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||
clear_config([:mrf_keyword, :replace], [{"updated", "mewmew"}])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "updated 1"})
|
||||
assert Object.normalize(activity).data["summary"] == "mewmew 1"
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "mewmew 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Map.has_key?(updated_object.data, "updated")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
}
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, :origin_containment_failed} = ObanHelpers.perform(job)
|
||||
assert {:cancel, :origin_containment_failed} = ObanHelpers.perform(job)
|
||||
end
|
||||
|
||||
test "it does not crash if MRF rejects the post" do
|
||||
|
|
@ -169,7 +169,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
|> Jason.decode!()
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, _} = ObanHelpers.perform(job)
|
||||
assert {:cancel, _} = ObanHelpers.perform(job)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -407,6 +408,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert id_two == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "gets local-only statuses for authenticated users", %{user: _user, conn: conn} do
|
||||
user_one = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user_one, %{status: "HI!!!", visibility: "local"})
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> get("/api/v1/accounts/#{user_one.id}/statuses")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => id}] = resp
|
||||
assert id == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "gets an users media, excludes reblogs", %{conn: conn} do
|
||||
note = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note.data["actor"])
|
||||
|
|
@ -881,6 +896,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"showing_reblogs" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "1"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^reblog_id}] =
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|
|
@ -910,6 +931,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"showing_reblogs" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "0"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] ==
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|
|
@ -920,21 +947,23 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
%{conn: conn} = oauth_access(["follow"])
|
||||
followed = insert(:user)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true})
|
||||
assert %{"subscribing" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"id" => _id, "subscribing" => true} =
|
||||
json_response_and_validate_schema(ret_conn, 200)
|
||||
assert %{"subscribing" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: "1"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false})
|
||||
|
||||
assert %{"id" => _id, "subscribing" => false} =
|
||||
json_response_and_validate_schema(ret_conn, 200)
|
||||
assert %{"subscribing" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "following / unfollowing errors", %{user: user, conn: conn} do
|
||||
|
|
@ -1011,6 +1040,40 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "expiring", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"duration" => "86400"})
|
||||
|
||||
assert %{"id" => _id, "muting" => true} = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user)
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
|
||||
test "falls back to expires_in", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"expires_in" => "86400"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user)
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
end
|
||||
|
||||
describe "pinned statuses" do
|
||||
|
|
@ -1829,21 +1892,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/mutes")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
|
||||
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/mutes?limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/mutes?since_id=#{id1}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1857,7 +1920,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/mutes?since_id=#{id1}&limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
end
|
||||
|
||||
test "list of mutes with with_relationships parameter" do
|
||||
|
|
@ -1876,7 +1939,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|
||||
assert [
|
||||
%{
|
||||
"id" => ^id1,
|
||||
"id" => ^id3,
|
||||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
},
|
||||
%{
|
||||
|
|
@ -1884,7 +1947,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
},
|
||||
%{
|
||||
"id" => ^id3,
|
||||
"id" => ^id1,
|
||||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
}
|
||||
] =
|
||||
|
|
@ -1909,7 +1972,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
|
||||
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1917,7 +1980,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1925,7 +1988,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?since_id=#{id1}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1941,7 +2004,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?since_id=#{id1}&limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
conn_res =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/blocks?limit=2")
|
||||
|
||||
next_url =
|
||||
~r{<.+?(?<link>/api[^>]+)>; rel=\"next\"}
|
||||
|> Regex.named_captures(get_resp_header(conn_res, "link") |> Enum.at(0))
|
||||
|> Map.get("link")
|
||||
|
||||
result =
|
||||
conn_res
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(next_url)
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
end
|
||||
|
||||
test "account lookup", %{conn: conn} do
|
||||
|
|
@ -2046,4 +2133,48 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> json_response_and_validate_schema(400)
|
||||
end
|
||||
end
|
||||
|
||||
describe "remove from followers" do
|
||||
setup do: oauth_access(["follow"])
|
||||
|
||||
test "removing user from followers", %{conn: conn, user: user} do
|
||||
%{id: other_user_id} = other_user = insert(:user)
|
||||
|
||||
CommonAPI.follow(other_user, user)
|
||||
|
||||
assert %{"id" => ^other_user_id, "followed_by" => false} =
|
||||
conn
|
||||
|> post("/api/v1/accounts/#{other_user_id}/remove_from_followers")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
refute User.following?(other_user, user)
|
||||
end
|
||||
|
||||
test "removing remote user from followers", %{conn: conn, user: user} do
|
||||
%{id: other_user_id} = other_user = insert(:user, local: false)
|
||||
|
||||
CommonAPI.follow(other_user, user)
|
||||
|
||||
assert User.following?(other_user, user)
|
||||
|
||||
assert %{"id" => ^other_user_id, "followed_by" => false} =
|
||||
conn
|
||||
|> post("/api/v1/accounts/#{other_user_id}/remove_from_followers")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
refute User.following?(other_user, user)
|
||||
end
|
||||
|
||||
test "removing user from followers errors", %{user: user, conn: conn} do
|
||||
# self remove
|
||||
conn_res = post(conn, "/api/v1/accounts/#{user.id}/remove_from_followers")
|
||||
|
||||
assert %{"error" => "Can not unfollow yourself"} =
|
||||
json_response_and_validate_schema(conn_res, 400)
|
||||
|
||||
# remove non existing user
|
||||
conn_res = post(conn, "/api/v1/accounts/doesntexist/remove_from_followers")
|
||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Filter
|
||||
|
|
@ -53,24 +54,19 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
|||
in_seconds = 600
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/filters", %{
|
||||
"phrase" => "knights",
|
||||
context: ["home"],
|
||||
expires_in: in_seconds
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/filters", %{
|
||||
"phrase" => "knights",
|
||||
context: ["home"],
|
||||
expires_in: in_seconds
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
assert response["irreversible"] == false
|
||||
|
||||
expected_expiration =
|
||||
NaiveDateTime.utc_now()
|
||||
|> NaiveDateTime.add(in_seconds)
|
||||
|
||||
{:ok, actual_expiration} = NaiveDateTime.from_iso8601(response["expires_at"])
|
||||
|
||||
assert abs(NaiveDateTime.diff(expected_expiration, actual_expiration)) <= 5
|
||||
assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
|
||||
|
||||
filter = Filter.get(response["id"], user)
|
||||
|
||||
|
|
@ -177,28 +173,25 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
|||
assert response["whole_word"] == true
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "with adding expires_at", %{conn: conn, user: user} do
|
||||
filter = insert(:filter, user: user)
|
||||
in_seconds = 600
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/filters/#{filter.filter_id}", %{
|
||||
phrase: "nii",
|
||||
context: ["public"],
|
||||
expires_in: in_seconds,
|
||||
irreversible: true
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/filters/#{filter.filter_id}", %{
|
||||
phrase: "nii",
|
||||
context: ["public"],
|
||||
expires_in: in_seconds,
|
||||
irreversible: true
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
assert response["irreversible"] == true
|
||||
|
||||
assert response["expires_at"] ==
|
||||
NaiveDateTime.utc_now()
|
||||
|> NaiveDateTime.add(in_seconds)
|
||||
|> Pleroma.Web.CommonAPI.Utils.to_masto_date()
|
||||
assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
|
||||
|
||||
filter = Filter.get(response["id"], user)
|
||||
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
end
|
||||
|
||||
test "filters notifications using include_types" do
|
||||
test "filters notifications using types" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
|
|
@ -474,21 +474,21 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
|
||||
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=follow")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=follow")
|
||||
|
||||
assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=mention")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=mention")
|
||||
|
||||
assert [%{"id" => ^mention_notification_id}] =
|
||||
json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=favourite")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=favourite")
|
||||
|
||||
assert [%{"id" => ^favorite_notification_id}] =
|
||||
json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=reblog")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=reblog")
|
||||
|
||||
assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
|
||||
assert length(result) == 4
|
||||
|
||||
query = params_to_query(%{include_types: ["follow", "mention", "favourite", "reblog"]})
|
||||
query = params_to_query(%{types: ["follow", "mention", "favourite", "reblog"]})
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -506,6 +506,23 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
assert length(result) == 4
|
||||
end
|
||||
|
||||
test "filtering falls back to include_types" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
|
||||
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, _activity} = CommonAPI.favorite(other_user, create_activity.id)
|
||||
{:ok, _activity} = CommonAPI.repeat(create_activity.id, other_user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=follow")
|
||||
|
||||
assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
end
|
||||
|
||||
test "destroy multiple" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
|
@ -27,6 +29,41 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
|||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "submit a report with a fake Create", %{
|
||||
conn: conn
|
||||
} do
|
||||
target_user = insert(:user)
|
||||
|
||||
note = insert(:note, user: target_user)
|
||||
|
||||
activity_params = %{
|
||||
"object" => note.data["id"],
|
||||
"actor" => note.data["actor"],
|
||||
"to" => note.data["to"] || [],
|
||||
"cc" => note.data["cc"] || [],
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
{:ok, fake_activity} =
|
||||
Repo.insert(%Activity{
|
||||
data: activity_params,
|
||||
recipients: activity_params["to"] ++ activity_params["cc"],
|
||||
local: true,
|
||||
actor: activity_params["actor"]
|
||||
})
|
||||
|
||||
assert %{"action_taken" => false, "id" => _} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/reports", %{
|
||||
"account_id" => target_user.id,
|
||||
"status_ids" => [fake_activity.id],
|
||||
"comment" => "bad status!",
|
||||
"forward" => "false"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "submit a report with statuses and comment", %{
|
||||
conn: conn,
|
||||
target_user: target_user,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "search", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
|
||||
|
|
@ -79,6 +80,51 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
assert status["id"] == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "search local-only status as an authenticated user" do
|
||||
user = insert(:user)
|
||||
%{conn: conn} = oauth_access(["read:search"])
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
conn
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
[status] = results["statuses"]
|
||||
assert status["id"] == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "search local-only status as an unauthenticated user" do
|
||||
user = insert(:user)
|
||||
%{conn: conn} = oauth_access([])
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
conn
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = results["statuses"]
|
||||
end
|
||||
|
||||
test "search local-only status as an anonymous user" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
build_conn()
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = results["statuses"]
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "constructs hashtags from search query", %{conn: conn} do
|
||||
results =
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.ModerationLog
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
|
|
@ -262,6 +263,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> Map.put("url", nil)
|
||||
|> Map.put("uri", nil)
|
||||
|> Map.put("created_at", nil)
|
||||
|> Kernel.put_in(["pleroma", "context"], nil)
|
||||
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
|
||||
|
||||
fake_conn =
|
||||
|
|
@ -285,6 +287,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> Map.put("url", nil)
|
||||
|> Map.put("uri", nil)
|
||||
|> Map.put("created_at", nil)
|
||||
|> Kernel.put_in(["pleroma", "context"], nil)
|
||||
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
|
||||
|
||||
assert real_status == fake_status
|
||||
|
|
@ -971,16 +974,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
test "when you're privileged to", %{conn: conn} do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
activity = insert(:note_activity)
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
res_conn =
|
||||
conn
|
||||
|> assign(:user, moderator)
|
||||
|> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"]))
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
|
||||
|> delete("/api/v1/statuses/#{activity.id}")
|
||||
|
||||
assert %{} = json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() ==
|
||||
"@#{user.nickname} deleted status ##{activity.id}"
|
||||
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
end
|
||||
|
|
@ -1891,23 +1897,50 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
|
||||
test "posting a local only status" do
|
||||
%{user: _user, conn: conn} = oauth_access(["write:statuses"])
|
||||
describe "local-only statuses" do
|
||||
test "posting a local only status" do
|
||||
%{user: _user, conn: conn} = oauth_access(["write:statuses"])
|
||||
|
||||
conn_one =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "cofe",
|
||||
"visibility" => "local"
|
||||
})
|
||||
conn_one =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "cofe",
|
||||
"visibility" => "local"
|
||||
})
|
||||
|
||||
local = Utils.as_local_public()
|
||||
local = Utils.as_local_public()
|
||||
|
||||
assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
|
||||
json_response_and_validate_schema(conn_one, 200)
|
||||
assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
|
||||
json_response_and_validate_schema(conn_one, 200)
|
||||
|
||||
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
|
||||
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
|
||||
end
|
||||
|
||||
test "other users can read local-only posts" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access(["read:statuses"])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
received =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert received["id"] == activity.id
|
||||
end
|
||||
|
||||
test "anonymous users cannot see local-only posts" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
_received =
|
||||
build_conn()
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "muted reactions" do
|
||||
|
|
@ -1980,4 +2013,178 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
} = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "get status history" do
|
||||
setup do
|
||||
%{conn: build_conn()}
|
||||
end
|
||||
|
||||
test "unedited post", %{conn: conn} do
|
||||
activity = insert(:note_activity)
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/history")
|
||||
|
||||
assert [_] = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "edited post", %{conn: conn} do
|
||||
note =
|
||||
insert(
|
||||
:note,
|
||||
data: %{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "mew mew 2",
|
||||
"summary" => "title 2"
|
||||
},
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "mew mew 1",
|
||||
"summary" => "title 1"
|
||||
}
|
||||
],
|
||||
"totalItems" => 2
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/history")
|
||||
|
||||
assert [%{"spoiler_text" => "title 1"}, %{"spoiler_text" => "title 2"}, _] =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get status source" do
|
||||
setup do
|
||||
%{conn: build_conn()}
|
||||
end
|
||||
|
||||
test "it returns the source", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/source")
|
||||
|
||||
id = activity.id
|
||||
|
||||
assert %{"id" => ^id, "text" => "mew mew #abc", "spoiler_text" => "#def"} =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "update status" do
|
||||
setup do
|
||||
oauth_access(["write:statuses"])
|
||||
end
|
||||
|
||||
test "it updates the status" do
|
||||
%{conn: conn, user: user} = oauth_access(["write:statuses", "read:statuses"])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["content"] == "edited"
|
||||
assert response["spoiler_text"] == "lol"
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["content"] == "edited"
|
||||
assert response["spoiler_text"] == "lol"
|
||||
end
|
||||
|
||||
test "it updates the attachments", %{conn: conn, user: user} do
|
||||
attachment = insert(:attachment, user: user)
|
||||
attachment_id = to_string(attachment.id)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "mew mew #abc",
|
||||
"spoiler_text" => "#def",
|
||||
"media_ids" => [attachment_id]
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^attachment_id}] = response["media_attachments"]
|
||||
end
|
||||
|
||||
test "it does not update visibility", %{conn: conn, user: user} do
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "mew mew #abc",
|
||||
spoiler_text: "#def",
|
||||
visibility: "private"
|
||||
})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["visibility"] == "private"
|
||||
end
|
||||
|
||||
test "it refuses to update when original post is not by the user", %{conn: conn} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(another_user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(:forbidden)
|
||||
end
|
||||
|
||||
test "it returns 404 if the user cannot see the post", %{conn: conn} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(another_user, %{
|
||||
status: "mew mew #abc",
|
||||
spoiler_text: "#def",
|
||||
visibility: "private"
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -367,6 +367,47 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
}
|
||||
] = result
|
||||
end
|
||||
|
||||
test "should return local-only posts for authenticated users" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access(["read:statuses"])
|
||||
|
||||
{:ok, %{id: id}} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id}] = result
|
||||
end
|
||||
|
||||
test "should not return local-only posts for users without read:statuses" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access([])
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = result
|
||||
end
|
||||
|
||||
test "should not return local-only posts for anonymous users" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
build_conn()
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = result
|
||||
end
|
||||
end
|
||||
|
||||
defp local_and_remote_activities do
|
||||
|
|
@ -903,7 +944,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
|
||||
describe "hashtag timeline handling of restrict_unauthenticated setting" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"})
|
||||
|
|
|
|||
|
|
@ -259,6 +259,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.avatar == nil
|
||||
end
|
||||
|
||||
test "updates the user's avatar, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_avatar_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
assert user.avatar == %{}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar_oversized})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user_response["avatar"] != User.avatar_url(user)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.avatar == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "updates the user's banner", %{user: user, conn: conn} do
|
||||
new_header = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
|
|
@ -278,6 +306,32 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.banner == nil
|
||||
end
|
||||
|
||||
test "updates the user's banner, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_header_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header_oversized})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user_response["header"] != User.banner_url(user)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.banner == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "updates the user's background", %{conn: conn, user: user} do
|
||||
new_header = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
|
|
@ -301,6 +355,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.background == nil
|
||||
end
|
||||
|
||||
test "updates the user's background, upload_limit, returns a HTTP 413", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_background_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"pleroma_background_image" => new_background_oversized
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user.background == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "requires 'write:accounts' permission" do
|
||||
token1 = insert(:oauth_token, scopes: ["read"])
|
||||
token2 = insert(:oauth_token, scopes: ["write", "follow"])
|
||||
|
|
@ -390,6 +472,20 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user_data["source"]["pleroma"]["show_birthday"] == true
|
||||
end
|
||||
|
||||
test "unsets birth date", %{conn: conn} do
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"birthday" => "2001-02-12"
|
||||
})
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"birthday" => ""
|
||||
})
|
||||
|
||||
assert user_data = json_response_and_validate_schema(res, 200)
|
||||
assert user_data["pleroma"]["birthday"] == nil
|
||||
end
|
||||
|
||||
test "emojis in fields labels", %{conn: conn} do
|
||||
fields = [
|
||||
%{"name" => ":firefox:", "value" => "is best 2hu"},
|
||||
|
|
|
|||
|
|
@ -779,4 +779,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
test "renders mute expiration date" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _user_relationships} =
|
||||
User.mute(user, other_user, %{notifications: true, duration: 24 * 60 * 60})
|
||||
|
||||
%{
|
||||
mute_expires_at: mute_expires_at
|
||||
} = AccountView.render("show.json", %{user: other_user, for: user, mutes: true})
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -239,6 +239,32 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
|||
test_notifications_rendering([notification], moderator_user, [expected])
|
||||
end
|
||||
|
||||
test "Edit notification" do
|
||||
user = insert(:user)
|
||||
repeat_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew"})
|
||||
{:ok, _} = CommonAPI.repeat(activity.id, repeat_user)
|
||||
{:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew"})
|
||||
|
||||
user = Pleroma.User.get_by_ap_id(user.ap_id)
|
||||
activity = Pleroma.Activity.normalize(activity)
|
||||
update = Pleroma.Activity.normalize(update)
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(update)
|
||||
|
||||
expected = %{
|
||||
id: to_string(notification.id),
|
||||
pleroma: %{is_seen: false, is_muted: false},
|
||||
type: "update",
|
||||
account: AccountView.render("show.json", %{user: user, for: repeat_user}),
|
||||
created_at: Utils.to_masto_date(notification.inserted_at),
|
||||
status: StatusView.render("show.json", %{activity: activity, for: repeat_user})
|
||||
}
|
||||
|
||||
test_notifications_rendering([notification], repeat_user, [expected])
|
||||
end
|
||||
|
||||
test "muted notification" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
require Bitwise
|
||||
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
import OpenApiSpex.TestAssertions
|
||||
|
|
@ -226,7 +227,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
object_data = Object.normalize(note, fetch: false).data
|
||||
user = User.get_cached_by_ap_id(note.data["actor"])
|
||||
|
||||
convo_id = Utils.context_to_conversation_id(object_data["context"])
|
||||
convo_id = :erlang.crc32(object_data["context"]) |> Bitwise.band(Bitwise.bnot(0x8000_0000))
|
||||
|
||||
status = StatusView.render("show.json", %{activity: note})
|
||||
|
||||
|
|
@ -246,6 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
content: HTML.filter_tags(object_data["content"]),
|
||||
text: nil,
|
||||
created_at: created_at,
|
||||
edited_at: nil,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
favourites_count: 0,
|
||||
|
|
@ -279,6 +281,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
pleroma: %{
|
||||
local: true,
|
||||
conversation_id: convo_id,
|
||||
context: object_data["context"],
|
||||
in_reply_to_account_acct: nil,
|
||||
content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
|
||||
spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
|
||||
|
|
@ -708,4 +711,55 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
status = StatusView.render("show.json", activity: visible, for: poster)
|
||||
assert status.pleroma.parent_visible
|
||||
end
|
||||
|
||||
test "it shows edited_at" do
|
||||
poster = insert(:user)
|
||||
|
||||
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
||||
|
||||
status = StatusView.render("show.json", activity: post)
|
||||
refute status.edited_at
|
||||
|
||||
{:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"})
|
||||
edited = Pleroma.Activity.normalize(post)
|
||||
|
||||
status = StatusView.render("show.json", activity: edited)
|
||||
assert status.edited_at
|
||||
end
|
||||
|
||||
test "with a source object" do
|
||||
note =
|
||||
insert(:note,
|
||||
data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, with_source: true)
|
||||
assert status.text == "object source"
|
||||
end
|
||||
|
||||
describe "source.json" do
|
||||
test "with a source object, renders both source and content type" do
|
||||
note =
|
||||
insert(:note,
|
||||
data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("source.json", activity: activity)
|
||||
assert status.text == "object source"
|
||||
assert status.content_type == "text/markdown"
|
||||
end
|
||||
|
||||
test "with a source string, renders source and put text/plain as the content type" do
|
||||
note = insert(:note, data: %{"source" => "string source"})
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("source.json", activity: activity)
|
||||
assert status.text == "string source"
|
||||
assert status.content_type == "text/plain"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,11 +10,14 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
|
|||
|
||||
test "it logs error when script is not found" do
|
||||
assert capture_log(fn ->
|
||||
assert Invalidation.Script.purge(
|
||||
["http://example.com/media/example.jpg"],
|
||||
script_path: "./example"
|
||||
) == {:error, "%ErlangError{original: :enoent}"}
|
||||
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
|
||||
assert {:error, msg} =
|
||||
Invalidation.Script.purge(
|
||||
["http://example.com/media/example.jpg"],
|
||||
script_path: "./example"
|
||||
)
|
||||
|
||||
assert msg =~ ~r/%ErlangError{original: :enoent(, reason: nil)?}/
|
||||
end) =~ ~r/Error while cache purge: %ErlangError{original: :enoent(, reason: nil)?}/
|
||||
|
||||
capture_log(fn ->
|
||||
assert Invalidation.Script.purge(
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 500, body: ""}
|
||||
end)
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: "",
|
||||
|
|
@ -218,7 +218,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
clear_config([:media_preview_proxy, :min_content_length], 100_000)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: "",
|
||||
|
|
@ -278,7 +278,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert_dependencies_installed()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
@ -300,7 +300,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert_dependencies_installed()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
@ -320,7 +320,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell"
|
||||
}
|
||||
})
|
||||
|
|
@ -54,6 +55,36 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
] == result
|
||||
end
|
||||
|
||||
test "it uses summary as description if post has one" do
|
||||
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "HI"})
|
||||
|
||||
note =
|
||||
insert(:note, %{
|
||||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "Public service announcement on caffeine consumption",
|
||||
"content" => "cofe"
|
||||
}
|
||||
})
|
||||
|
||||
result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
|
||||
|
||||
assert [
|
||||
{:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
|
||||
{:meta,
|
||||
[
|
||||
property: "twitter:description",
|
||||
content: "Public service announcement on caffeine consumption"
|
||||
], []},
|
||||
{:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
|
||||
[]},
|
||||
{:meta, [property: "twitter:card", content: "summary"], []}
|
||||
] == result
|
||||
end
|
||||
|
||||
test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do
|
||||
clear_config([Pleroma.Web.Metadata, :unfurl_nsfw], false)
|
||||
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
|
||||
|
|
@ -65,6 +96,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell",
|
||||
"sensitive" => true,
|
||||
"attachment" => [
|
||||
|
|
@ -109,6 +141,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell",
|
||||
"attachment" => [
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Metadata.UtilsTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase, async: false
|
||||
import Pleroma.Factory
|
||||
alias Pleroma.Web.Metadata.Utils
|
||||
|
||||
describe "scrub_html_and_truncate/1" do
|
||||
test "it returns text without encode HTML" do
|
||||
test "it returns content text without encode HTML if summary is nil" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
|
|
@ -16,12 +16,60 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
|
|||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => nil,
|
||||
"content" => "Pleroma's really cool!"
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
|
||||
end
|
||||
|
||||
test "it returns context text without encode HTML if summary is empty" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note, %{
|
||||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "Pleroma's really cool!"
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
|
||||
end
|
||||
|
||||
test "it returns summary text without encode HTML if summary is filled" do
|
||||
user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note, %{
|
||||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "Public service announcement on caffeine consumption",
|
||||
"content" => "cofe"
|
||||
}
|
||||
})
|
||||
|
||||
assert Utils.scrub_html_and_truncate(note) ==
|
||||
"Public service announcement on caffeine consumption"
|
||||
end
|
||||
|
||||
test "it does not return old content after editing" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew #def"})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
assert Utils.scrub_html_and_truncate(object) == "mew mew #def"
|
||||
|
||||
{:ok, update} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "mew mew #abc"})
|
||||
update = Pleroma.Activity.normalize(update)
|
||||
object = Pleroma.Object.normalize(update)
|
||||
assert Utils.scrub_html_and_truncate(object) == "mew mew #abc"
|
||||
end
|
||||
end
|
||||
|
||||
describe "scrub_html_and_truncate/2" do
|
||||
|
|
|
|||
|
|
@ -343,54 +343,4 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
|||
|> response(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "notice compatibility routes" do
|
||||
test "Soapbox FE", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/@#{user.nickname}/posts/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
|
||||
test "Mastodon", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/@#{user.nickname}/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
|
||||
test "Twitter", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/#{user.nickname}/status/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
|
|||
setup do
|
||||
clear_config([Pleroma.Upload, :uploader])
|
||||
clear_config([Backup, :limit_days])
|
||||
oauth_access(["read:accounts"])
|
||||
oauth_access(["read:backups"])
|
||||
end
|
||||
|
||||
test "GET /api/v1/pleroma/backups", %{user: user, conn: conn} do
|
||||
|
|
@ -82,4 +82,24 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
|
|||
|> post("/api/v1/pleroma/backups")
|
||||
|> json_response_and_validate_schema(400)
|
||||
end
|
||||
|
||||
test "Backup without email address" do
|
||||
user = Pleroma.Factory.insert(:user, email: nil)
|
||||
%{conn: conn} = oauth_access(["read:backups"], user: user)
|
||||
|
||||
assert is_nil(user.email)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"content_type" => "application/zip",
|
||||
"url" => _url,
|
||||
"file_size" => 0,
|
||||
"processed" => false,
|
||||
"inserted_at" => _
|
||||
}
|
||||
] =
|
||||
conn
|
||||
|> post("/api/v1/pleroma/backups")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.PleromaAPI.SettingsControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "GET /api/v1/pleroma/settings/:app" do
|
||||
setup do
|
||||
oauth_access(["read:accounts"])
|
||||
end
|
||||
|
||||
test "it gets empty settings", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/settings/pleroma-fe")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{}
|
||||
end
|
||||
|
||||
test "it gets settings", %{conn: conn, user: user} do
|
||||
response =
|
||||
conn
|
||||
|> assign(
|
||||
:user,
|
||||
struct(user,
|
||||
pleroma_settings_store: %{
|
||||
"pleroma-fe" => %{
|
||||
"foo" => "bar"
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|> get("/api/v1/pleroma/settings/pleroma-fe")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert %{"foo" => "bar"} == response
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/pleroma/settings/:app" do
|
||||
setup do
|
||||
settings = %{
|
||||
"foo" => "bar",
|
||||
"nested" => %{
|
||||
"1" => "2"
|
||||
}
|
||||
}
|
||||
|
||||
user =
|
||||
insert(
|
||||
:user,
|
||||
%{
|
||||
pleroma_settings_store: %{
|
||||
"pleroma-fe" => settings
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
%{conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
%{conn: conn, user: user, settings: settings}
|
||||
end
|
||||
|
||||
test "it adds keys", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/pleroma-fe", %{
|
||||
"foo" => "edited",
|
||||
"bar" => "new",
|
||||
"nested" => %{"3" => "4"}
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{
|
||||
"foo" => "edited",
|
||||
"bar" => "new",
|
||||
"nested" => %{
|
||||
"1" => "2",
|
||||
"3" => "4"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
test "it removes keys", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/pleroma-fe", %{
|
||||
"foo" => nil,
|
||||
"bar" => nil,
|
||||
"nested" => %{
|
||||
"1" => nil,
|
||||
"3" => nil
|
||||
}
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{
|
||||
"nested" => %{}
|
||||
}
|
||||
end
|
||||
|
||||
test "it does not override settings for other apps", %{
|
||||
conn: conn,
|
||||
user: user,
|
||||
settings: settings
|
||||
} do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/admin-fe", %{"foo" => "bar"})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
user = Pleroma.User.get_by_id(user.id)
|
||||
|
||||
assert user.pleroma_settings_store == %{
|
||||
"pleroma-fe" => settings,
|
||||
"admin-fe" => %{"foo" => "bar"}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -86,8 +86,6 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
"objects",
|
||||
"activities",
|
||||
"notice",
|
||||
"@:nickname",
|
||||
":nickname",
|
||||
"users",
|
||||
"tags",
|
||||
"mailer",
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
|
||||
assert csp =~ ~r|report-uri https://endpoint.com;report-to csp-endpoint;|
|
||||
|
||||
[reply_to] = Conn.get_resp_header(conn, "reply-to")
|
||||
[report_to] = Conn.get_resp_header(conn, "report-to")
|
||||
|
||||
assert reply_to ==
|
||||
assert report_to ==
|
||||
"{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -48,38 +48,42 @@ defmodule Pleroma.Web.Plugs.RateLimiterTest do
|
|||
refute RateLimiter.disabled?(build_conn())
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "it restricts based on config values" do
|
||||
limiter_name = :test_plug_opts
|
||||
scale = 80
|
||||
limit = 5
|
||||
|
||||
clear_config([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
|
||||
clear_config([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1})
|
||||
clear_config([:rate_limit, limiter_name], {scale, limit})
|
||||
|
||||
plug_opts = RateLimiter.init(name: limiter_name)
|
||||
conn = build_conn(:get, "/")
|
||||
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
|
||||
Process.sleep(10)
|
||||
for _ <- 1..5 do
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
refute conn_limited.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_limited.resp_body
|
||||
refute conn_limited.halted
|
||||
end
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
|
||||
assert conn_limited.halted
|
||||
|
||||
Process.sleep(50)
|
||||
expire_ttl(conn, limiter_name)
|
||||
|
||||
conn = build_conn(:get, "/")
|
||||
for _ <- 1..5 do
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
|
||||
refute conn_limited.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_limited.resp_body
|
||||
refute conn_limited.halted
|
||||
end
|
||||
|
||||
refute conn.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
|
||||
assert conn_limited.halted
|
||||
end
|
||||
|
||||
describe "options" do
|
||||
|
|
@ -263,4 +267,12 @@ defmodule Pleroma.Web.Plugs.RateLimiterTest do
|
|||
|
||||
refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
end
|
||||
|
||||
def expire_ttl(%{remote_ip: remote_ip} = _conn, bucket_name_root) do
|
||||
bucket_name = "anon:#{bucket_name_root}" |> String.to_atom()
|
||||
key_name = "ip::#{remote_ip |> Tuple.to_list() |> Enum.join(".")}"
|
||||
|
||||
{:ok, bucket_value} = Cachex.get(bucket_name, key_name)
|
||||
Cachex.put(bucket_name, key_name, bucket_value, ttl: -1)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -202,6 +202,21 @@ defmodule Pleroma.Web.Push.ImplTest do
|
|||
"New Reaction"
|
||||
end
|
||||
|
||||
test "renders title and body for update activity" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "lorem ipsum"})
|
||||
|
||||
{:ok, activity} = CommonAPI.update(user, activity, %{status: "edited status"})
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert Impl.format_body(%{activity: activity, type: "update"}, user, object) ==
|
||||
"@#{user.nickname} edited a status"
|
||||
|
||||
assert Impl.format_title(%{activity: activity, type: "update"}) ==
|
||||
"New Update"
|
||||
end
|
||||
|
||||
test "renders title for create activity with direct visibility" do
|
||||
user = insert(:user, nickname: "Bob")
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,31 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
"state" => "follow_accept"
|
||||
} = Jason.decode!(payload)
|
||||
end
|
||||
|
||||
test "it streams edits in the 'user' stream", %{user: user, token: oauth_token} do
|
||||
sender = insert(:user)
|
||||
{:ok, _, _, _} = CommonAPI.follow(user, sender)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
|
||||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
|
||||
|
||||
assert_receive {:render_with_user, _, "status_update.json", ^create}
|
||||
refute Streamer.filtered_by_user?(user, edited)
|
||||
end
|
||||
|
||||
test "it streams own edits in the 'user' stream", %{user: user, token: oauth_token} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
|
||||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
{:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"})
|
||||
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
|
||||
|
||||
assert_receive {:render_with_user, _, "status_update.json", ^create}
|
||||
refute Streamer.filtered_by_user?(user, edited)
|
||||
end
|
||||
end
|
||||
|
||||
describe "public streams" do
|
||||
|
|
@ -484,6 +509,54 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert_receive {:text, event}
|
||||
assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
|
||||
end
|
||||
|
||||
test "it streams edits in the 'public' stream" do
|
||||
sender = insert(:user)
|
||||
|
||||
Streamer.get_topic_and_add_socket("public", nil, nil)
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
assert_receive {:text, _}
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
end
|
||||
|
||||
test "it streams multiple edits in the 'public' stream correctly" do
|
||||
sender = insert(:user)
|
||||
|
||||
Streamer.get_topic_and_add_socket("public", nil, nil)
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
assert_receive {:text, _}
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew 2"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id, "content" => "mew mew 2"} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
end
|
||||
end
|
||||
|
||||
describe "thread_containment/2" do
|
||||
|
|
@ -814,4 +887,105 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert last_status["id"] == to_string(create_activity.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "stop streaming if token got revoked" do
|
||||
setup do
|
||||
child_proc = fn start, finalize ->
|
||||
fn ->
|
||||
start.()
|
||||
|
||||
receive do
|
||||
{StreamerTest, :ready} ->
|
||||
assert_receive {:render_with_user, _, "update.json", _}
|
||||
|
||||
receive do
|
||||
{StreamerTest, :revoked} -> finalize.()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
starter = fn user, token ->
|
||||
fn -> Streamer.get_topic_and_add_socket("user", user, token) end
|
||||
end
|
||||
|
||||
hit = fn -> assert_receive :close end
|
||||
miss = fn -> refute_receive :close end
|
||||
|
||||
send_all = fn tasks, thing -> Enum.each(tasks, &send(&1.pid, thing)) end
|
||||
|
||||
%{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
miss: miss,
|
||||
send_all: send_all
|
||||
}
|
||||
end
|
||||
|
||||
test "do not revoke other tokens", %{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
miss: miss,
|
||||
send_all: send_all
|
||||
} do
|
||||
%{user: user, token: token} = oauth_access(["read"])
|
||||
%{token: token2} = oauth_access(["read"], user: user)
|
||||
%{user: user2, token: user2_token} = oauth_access(["read"])
|
||||
|
||||
post_user = insert(:user)
|
||||
CommonAPI.follow(user, post_user)
|
||||
CommonAPI.follow(user2, post_user)
|
||||
|
||||
tasks = [
|
||||
Task.async(child_proc.(starter.(user, token), hit)),
|
||||
Task.async(child_proc.(starter.(user, token2), miss)),
|
||||
Task.async(child_proc.(starter.(user2, user2_token), miss))
|
||||
]
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(post_user, %{
|
||||
status: "hi"
|
||||
})
|
||||
|
||||
send_all.(tasks, {StreamerTest, :ready})
|
||||
|
||||
Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token)
|
||||
|
||||
send_all.(tasks, {StreamerTest, :revoked})
|
||||
|
||||
Enum.each(tasks, &Task.await/1)
|
||||
end
|
||||
|
||||
test "revoke all streams for this token", %{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
send_all: send_all
|
||||
} do
|
||||
%{user: user, token: token} = oauth_access(["read"])
|
||||
|
||||
post_user = insert(:user)
|
||||
CommonAPI.follow(user, post_user)
|
||||
|
||||
tasks = [
|
||||
Task.async(child_proc.(starter.(user, token), hit)),
|
||||
Task.async(child_proc.(starter.(user, token), hit))
|
||||
]
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(post_user, %{
|
||||
status: "hi"
|
||||
})
|
||||
|
||||
send_all.(tasks, {StreamerTest, :ready})
|
||||
|
||||
Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token)
|
||||
|
||||
send_all.(tasks, {StreamerTest, :revoked})
|
||||
|
||||
Enum.each(tasks, &Task.await/1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.MFA
|
||||
alias Pleroma.MFA.TOTP
|
||||
|
|
|
|||
|
|
@ -233,6 +233,102 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "POST /main/ostatus - remote_subscribe/2 - with statuses" do
|
||||
setup do: clear_config([:instance, :federating], true)
|
||||
|
||||
test "renders subscribe form", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
|
||||
assert is_binary(status_id)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{"status_id" => status_id, "profile" => ""})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find status"
|
||||
assert response =~ "Interacting with"
|
||||
end
|
||||
|
||||
test "renders subscribe form with error when status not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{"status_id" => "somerandomid", "profile" => ""})
|
||||
|> response(:ok)
|
||||
|
||||
assert response =~ "Could not find status"
|
||||
refute response =~ "Interacting with"
|
||||
end
|
||||
|
||||
test "it redirect to webfinger url", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
status_ap_id = status.data["object"]
|
||||
|
||||
assert is_binary(status_id)
|
||||
assert is_binary(status_ap_id)
|
||||
|
||||
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> post("/main/ostatus", %{
|
||||
"status" => %{"status_id" => status_id, "profile" => user2.ap_id}
|
||||
})
|
||||
|
||||
assert redirected_to(conn) ==
|
||||
"https://social.heldscal.la/main/ostatussub?profile=#{status_ap_id}"
|
||||
end
|
||||
|
||||
test "it renders form with error when status not found", %{conn: conn} do
|
||||
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
|
||||
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{
|
||||
"status" => %{"status_id" => "somerandomid", "profile" => user2.ap_id}
|
||||
})
|
||||
|> response(:ok)
|
||||
|
||||
assert response =~ "Something went wrong."
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /main/ostatus - show_subscribe_form/2" do
|
||||
setup do: clear_config([:instance, :federating], true)
|
||||
|
||||
test "it works with users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/main/ostatus", %{"nickname" => user.nickname})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find user"
|
||||
assert response =~ "Remotely follow #{user.nickname}"
|
||||
end
|
||||
|
||||
test "it works with statuses", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
|
||||
assert is_binary(status_id)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/main/ostatus", %{"status_id" => status_id})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find status"
|
||||
assert response =~ "Interacting with"
|
||||
end
|
||||
end
|
||||
|
||||
test "it returns new captcha", %{conn: conn} do
|
||||
with_mock Pleroma.Captcha,
|
||||
new: fn -> "test_captcha" end do
|
||||
|
|
@ -516,4 +612,371 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
assert user.password_hash == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/pleroma/move_account" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "hi",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions and invalid password", %{conn: conn} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "hi",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account does not alias it",
|
||||
%{
|
||||
conn: conn
|
||||
} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"error" => "Target account must have the origin in `alsoKnownAs`"
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account does not exist",
|
||||
%{
|
||||
conn: conn
|
||||
} do
|
||||
target_nick = "not_found@mastodon.social"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 404) == %{
|
||||
"error" => "Target account not found."
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account aliases it and local cache does not exist",
|
||||
%{} do
|
||||
user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser")
|
||||
%{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
target_nick = "mewmew@lm.kazv.moe"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account aliases it and local cache does not aliases it",
|
||||
%{} do
|
||||
user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser")
|
||||
%{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
target_user =
|
||||
insert(
|
||||
:user,
|
||||
ap_id: "https://lm.kazv.moe/users/mewmew",
|
||||
nickname: "mewmew@lm.kazv.moe",
|
||||
local: false
|
||||
)
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account does not aliases it and local cache aliases it",
|
||||
%{
|
||||
user: user,
|
||||
conn: conn
|
||||
} do
|
||||
target_user =
|
||||
insert(
|
||||
:user,
|
||||
ap_id: "https://lm.kazv.moe/users/mewmew",
|
||||
nickname: "mewmew@lm.kazv.moe",
|
||||
local: false,
|
||||
also_known_as: [user.ap_id]
|
||||
)
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"error" => "Target account must have the origin in `alsoKnownAs`"
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account aliases it", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
follower = insert(:user)
|
||||
|
||||
User.follow(follower, user)
|
||||
|
||||
assert User.following?(follower, user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api/pleroma/move_account",
|
||||
%{
|
||||
password: "test",
|
||||
target_account: target_nick
|
||||
}
|
||||
)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => user.id,
|
||||
"target_id" => target_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
refute User.following?(follower, user)
|
||||
assert User.following?(follower, target_user)
|
||||
end
|
||||
|
||||
test "prefix nickname by @ should work", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
follower = insert(:user)
|
||||
|
||||
User.follow(follower, user)
|
||||
|
||||
assert User.following?(follower, user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api/pleroma/move_account",
|
||||
%{
|
||||
password: "test",
|
||||
target_account: "@" <> target_nick
|
||||
}
|
||||
)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => user.id,
|
||||
"target_id" => target_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
refute User.following?(follower, user)
|
||||
assert User.following?(follower, target_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/aliases" do
|
||||
setup do: oauth_access(["read:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> get("/api/pleroma/aliases")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: read:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions", %{
|
||||
conn: conn
|
||||
} do
|
||||
assert %{"aliases" => []} =
|
||||
conn
|
||||
|> get("/api/pleroma/aliases")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "with permissions and aliases", %{} do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
assert {:ok, user} = user |> User.add_alias(user2)
|
||||
|
||||
%{user: _user, conn: conn} = oauth_access(["read:accounts"], user: user)
|
||||
|
||||
assert %{"aliases" => aliases} =
|
||||
conn
|
||||
|> get("/api/pleroma/aliases")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert aliases == [user2 |> User.full_nickname()]
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/pleroma/aliases" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{alias: "none"})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions, no alias param", %{
|
||||
conn: conn
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{})
|
||||
|
||||
assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400)
|
||||
end
|
||||
|
||||
test "with permissions, with alias param", %{
|
||||
conn: conn
|
||||
} do
|
||||
user2 = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{alias: user2 |> User.full_nickname()})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"status" => "success"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/aliases" do
|
||||
setup do
|
||||
alias_user = insert(:user)
|
||||
non_alias_user = insert(:user)
|
||||
user = insert(:user, also_known_as: [alias_user.ap_id])
|
||||
|
||||
oauth_access(["write:accounts"], user: user)
|
||||
|> Map.put(:alias_user, alias_user)
|
||||
|> Map.put(:non_alias_user, non_alias_user)
|
||||
end
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: "none"})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions, no alias param", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{})
|
||||
|
||||
assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400)
|
||||
end
|
||||
|
||||
test "with permissions, account does not have such alias", %{
|
||||
conn: conn,
|
||||
non_alias_user: non_alias_user
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: non_alias_user |> User.full_nickname()})
|
||||
|
||||
assert %{"error" => "Account has no such alias."} =
|
||||
json_response_and_validate_schema(conn, 404)
|
||||
end
|
||||
|
||||
test "with permissions, account does have such alias", %{
|
||||
conn: conn,
|
||||
alias_user: alias_user
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: alias_user |> User.full_nickname()})
|
||||
|
||||
assert %{"status" => "success"} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,6 +48,35 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
|
|||
]
|
||||
end
|
||||
|
||||
test "reach user on tld, while pleroma is runned on subdomain" do
|
||||
Pleroma.Web.Endpoint.config_change(
|
||||
[{Pleroma.Web.Endpoint, url: [host: "sub.example.com"]}],
|
||||
[]
|
||||
)
|
||||
|
||||
clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com")
|
||||
|
||||
clear_config([Pleroma.Web.WebFinger, :domain], "example.com")
|
||||
|
||||
user = insert(:user, ap_id: "https://sub.example.com/users/bobby", nickname: "bobby")
|
||||
|
||||
response =
|
||||
build_conn()
|
||||
|> put_req_header("accept", "application/jrd+json")
|
||||
|> get("/.well-known/webfinger?resource=acct:#{user.nickname}@example.com")
|
||||
|> json_response(200)
|
||||
|
||||
assert response["subject"] == "acct:#{user.nickname}@example.com"
|
||||
assert response["aliases"] == ["https://sub.example.com/users/#{user.nickname}"]
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Web.Endpoint.config_change(
|
||||
[{Pleroma.Web.Endpoint, url: [host: "localhost"]}],
|
||||
[]
|
||||
)
|
||||
end)
|
||||
end
|
||||
|
||||
test "it returns 404 when user isn't found (JSON)" do
|
||||
result =
|
||||
build_conn()
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
|
||||
test "returns error when there is no content-type header" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "http://social.heldscal.la/.well-known/host-meta"} ->
|
||||
%{url: "https://social.heldscal.la/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -120,7 +120,7 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
test "it gets the xrd endpoint for statusnet" do
|
||||
{:ok, template} = WebFinger.find_lrdd_template("status.alpicola.com")
|
||||
|
||||
assert template == "http://status.alpicola.com/main/xrd?uri={uri}"
|
||||
assert template == "https://status.alpicola.com/main/xrd?uri={uri}"
|
||||
end
|
||||
|
||||
test "it works with idna domains as nickname" do
|
||||
|
|
@ -147,7 +147,7 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
headers: [{"content-type", "application/jrd+json"}]
|
||||
}}
|
||||
|
||||
%{url: "http://mastodon.social/.well-known/host-meta"} ->
|
||||
%{url: "https://mastodon.social/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -170,7 +170,7 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||
headers: [{"content-type", "application/xrd+xml"}]
|
||||
}}
|
||||
|
||||
%{url: "http://pawoo.net/.well-known/host-meta"} ->
|
||||
%{url: "https://pawoo.net/.well-known/host-meta"} ->
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue