Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into fine_grained_moderation_privileges

This commit is contained in:
Sean King 2022-12-18 22:03:48 -07:00
commit 60df2d8a97
No known key found for this signature in database
GPG key ID: 510C52BACD6E7257
308 changed files with 36503 additions and 1957 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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,

View file

@ -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 =

View file

@ -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

View file

@ -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"})

View file

@ -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"},

View file

@ -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

View file

@ -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)

View file

@ -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