Merge remote-tracking branch 'origin/develop' into mastodon-quote-id-api
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
commit
e0ab2c9c9c
129 changed files with 2128 additions and 362 deletions
93
test/fixtures/quote_post/mastodon_quote_post.json
vendored
Normal file
93
test/fixtures/quote_post/mastodon_quote_post.json
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"ostatus": "http://ostatus.org#",
|
||||
"atomUri": "ostatus:atomUri",
|
||||
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||
"conversation": "ostatus:conversation",
|
||||
"sensitive": "as:sensitive",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"votersCount": "toot:votersCount",
|
||||
"quote": "https://w3id.org/fep/044f#quote",
|
||||
"quoteUri": "http://fedibird.com/ns#quoteUri",
|
||||
"_misskey_quote": "https://misskey-hub.net/ns#_misskey_quote",
|
||||
"quoteAuthorization": {
|
||||
"@id": "https://w3id.org/fep/044f#quoteAuthorization",
|
||||
"@type": "@id"
|
||||
},
|
||||
"gts": "https://gotosocial.org/ns#",
|
||||
"interactionPolicy": {
|
||||
"@id": "gts:interactionPolicy",
|
||||
"@type": "@id"
|
||||
},
|
||||
"canQuote": {
|
||||
"@id": "gts:canQuote",
|
||||
"@type": "@id"
|
||||
},
|
||||
"automaticApproval": {
|
||||
"@id": "gts:automaticApproval",
|
||||
"@type": "@id"
|
||||
},
|
||||
"manualApproval": {
|
||||
"@id": "gts:manualApproval",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171",
|
||||
"type": "Note",
|
||||
"summary": null,
|
||||
"inReplyTo": null,
|
||||
"published": "2025-10-09T17:54:47Z",
|
||||
"url": "https://mastodon.social/@gwynnion/115345489087257171",
|
||||
"attributedTo": "https://mastodon.social/users/gwynnion",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://mastodon.social/users/gwynnion/followers"
|
||||
],
|
||||
"sensitive": false,
|
||||
"atomUri": "https://mastodon.social/users/gwynnion/statuses/115345489087257171",
|
||||
"inReplyToAtomUri": null,
|
||||
"conversation": "https://mastodon.social/contexts/109836797527169643-115345489087257171",
|
||||
"context": "https://mastodon.social/contexts/109836797527169643-115345489087257171",
|
||||
"content": "<p class=\"quote-inline\">RE: <a href=\"https://mastodon.social/@404mediaco/115344945575874225\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">mastodon.social/@404mediaco/11</span><span class=\"invisible\">5344945575874225</span></a></p><p>Every age verification system is just a scheme for companies and hackers to steal your identity.</p>",
|
||||
"contentMap": {
|
||||
"en": "<p class=\"quote-inline\">RE: <a href=\"https://mastodon.social/@404mediaco/115344945575874225\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">mastodon.social/@404mediaco/11</span><span class=\"invisible\">5344945575874225</span></a></p><p>Every age verification system is just a scheme for companies and hackers to steal your identity.</p>"
|
||||
},
|
||||
"quote": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
|
||||
"_misskey_quote": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
|
||||
"quoteUri": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
|
||||
"quoteAuthorization": "https://mastodon.social/users/404mediaco/quote_authorizations/115345489087269783",
|
||||
"interactionPolicy": {
|
||||
"canQuote": {
|
||||
"automaticApproval": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
}
|
||||
},
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"replies": {
|
||||
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies",
|
||||
"type": "Collection",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"next": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies?only_other_accounts=true&page=true",
|
||||
"partOf": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies",
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
"likes": {
|
||||
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/likes",
|
||||
"type": "Collection",
|
||||
"totalItems": 26
|
||||
},
|
||||
"shares": {
|
||||
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/shares",
|
||||
"type": "Collection",
|
||||
"totalItems": 28
|
||||
}
|
||||
}
|
||||
41
test/fixtures/users_mock/href_as_array.json
vendored
Normal file
41
test/fixtures/users_mock/href_as_array.json
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"alsoKnownAs": [],
|
||||
"attachment": [],
|
||||
"capabilities": {},
|
||||
"discoverable": true,
|
||||
"endpoints": {},
|
||||
"featured": "https://queef.in/cute_cat/collections/featured",
|
||||
"followers": "https://queef.in/cute_cat/followers",
|
||||
"following": "https://queef.in/cute_cat/following",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": [
|
||||
"https://queef.in/storage/profile.webp",
|
||||
"https://example.com/image"
|
||||
]
|
||||
},
|
||||
"id": "https://queef.in/cute_cat",
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"url": [
|
||||
"https://queef.in/storage/banner.gif",
|
||||
"https://example.com/image"
|
||||
]
|
||||
},
|
||||
"inbox": "https://queef.in/cute_cat/inbox",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"name": "cute_cat",
|
||||
"outbox": "https://queef.in/cute_cat/outbox",
|
||||
"preferredUsername": "cute_cat",
|
||||
"publicKey": {
|
||||
"id": "https://queef.in/cute_cat#main-key",
|
||||
"owner": "https://queef.in/cute_cat"
|
||||
},
|
||||
"published": "2025-08-18T01:16:10.000Z",
|
||||
"summary": "A cute cat",
|
||||
"tag": [],
|
||||
"type": "Person",
|
||||
"url": "https://queef.in/cute_cat",
|
||||
"vcard:bday": null,
|
||||
"webfinger": "acct:cute_cat@queef.in"
|
||||
}
|
||||
|
|
@ -5,8 +5,11 @@
|
|||
defmodule Pleroma.HTTPTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import Tesla.Mock
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Utils.URIEncoding
|
||||
|
||||
setup do
|
||||
mock(fn
|
||||
|
|
@ -28,6 +31,36 @@ defmodule Pleroma.HTTPTest do
|
|||
|
||||
%{method: :get, url: "https://example.com/emoji/Pack%201/koronebless.png?foo=bar+baz"} ->
|
||||
%Tesla.Env{status: 200, body: "emoji data"}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://example.com/media/foo/bar%20!$&'()*+,;=/:%20@a%20%5Bbaz%5D.mp4"
|
||||
} ->
|
||||
%Tesla.Env{status: 200, body: "video data"}
|
||||
|
||||
%{method: :get, url: "https://example.com/media/unicode%20%F0%9F%99%82%20.gif"} ->
|
||||
%Tesla.Env{status: 200, body: "unicode data"}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url:
|
||||
"https://i.guim.co.uk/img/media/1069ef13c447908272c4de94174cec2b6352cb2f/0_91_2000_1201/master/2000.jpg?width=1200&height=630&quality=85&auto=format&fit=crop&precrop=40:21,offset-x50,offset-y0&overlay-align=bottom%2Cleft&overlay-width=100p&overlay-base64=L2ltZy9zdGF0aWMvb3ZlcmxheXMvdGctb3BpbmlvbnMtYWdlLTIwMTkucG5n&enable=upscale&s=cba21427a73512fdc9863c486c03fdd8"
|
||||
} ->
|
||||
%Tesla.Env{status: 200, body: "Guardian image quirk"}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url:
|
||||
"https://i.guim.co.uk/emoji/Pack%201/koronebless.png?precrop=40:21,overlay-x0,overlay-y0&foo=bar+baz"
|
||||
} ->
|
||||
%Tesla.Env{status: 200, body: "Space in query with Guardian quirk"}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url:
|
||||
"https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=accessKEY%2F20130721%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130721T201207Z&X-Amz-Expires=86400&X-Amz-Signature=SIGNATURE&X-Amz-SignedHeaders=host"
|
||||
} ->
|
||||
%Tesla.Env{status: 200, body: "AWS S3 data"}
|
||||
end)
|
||||
|
||||
:ok
|
||||
|
|
@ -85,5 +118,100 @@ defmodule Pleroma.HTTPTest do
|
|||
{:ok, result} = HTTP.get(properly_encoded_url)
|
||||
|
||||
assert result.status == 200
|
||||
|
||||
url_with_reserved_chars = "https://example.com/media/foo/bar !$&'()*+,;=/: @a [baz].mp4"
|
||||
|
||||
{:ok, result} = HTTP.get(url_with_reserved_chars)
|
||||
|
||||
assert result.status == 200
|
||||
|
||||
url_with_unicode = "https://example.com/media/unicode 🙂 .gif"
|
||||
|
||||
{:ok, result} = HTTP.get(url_with_unicode)
|
||||
|
||||
assert result.status == 200
|
||||
end
|
||||
|
||||
test "decodes URL first by default" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
normal_url = "https://example.com/media/file%20with%20space.jpg?name=a+space.jpg"
|
||||
|
||||
result = URIEncoding.encode_url(normal_url)
|
||||
|
||||
assert result == "https://example.com/media/file%20with%20space.jpg?name=a+space.jpg"
|
||||
end
|
||||
|
||||
test "doesn't decode URL first when specified" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
normal_url = "https://example.com/media/file%20with%20space.jpg"
|
||||
|
||||
result = URIEncoding.encode_url(normal_url, bypass_decode: true)
|
||||
|
||||
assert result == "https://example.com/media/file%2520with%2520space.jpg"
|
||||
end
|
||||
|
||||
test "properly applies Guardian image query quirk" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
url =
|
||||
"https://i.guim.co.uk/img/media/1069ef13c447908272c4de94174cec2b6352cb2f/0_91_2000_1201/master/2000.jpg?width=1200&height=630&quality=85&auto=format&fit=crop&precrop=40:21,offset-x50,offset-y0&overlay-align=bottom%2Cleft&overlay-width=100p&overlay-base64=L2ltZy9zdGF0aWMvb3ZlcmxheXMvdGctb3BpbmlvbnMtYWdlLTIwMTkucG5n&enable=upscale&s=cba21427a73512fdc9863c486c03fdd8"
|
||||
|
||||
result = URIEncoding.encode_url(url)
|
||||
|
||||
assert result == url
|
||||
|
||||
{:ok, result_get} = HTTP.get(result)
|
||||
|
||||
assert result_get.status == 200
|
||||
end
|
||||
|
||||
test "properly encodes spaces as \"pluses\" in query when using quirks" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
url =
|
||||
"https://i.guim.co.uk/emoji/Pack 1/koronebless.png?precrop=40:21,overlay-x0,overlay-y0&foo=bar baz"
|
||||
|
||||
properly_encoded_url =
|
||||
"https://i.guim.co.uk/emoji/Pack%201/koronebless.png?precrop=40:21,overlay-x0,overlay-y0&foo=bar+baz"
|
||||
|
||||
result = URIEncoding.encode_url(url)
|
||||
|
||||
assert result == properly_encoded_url
|
||||
|
||||
{:ok, result_get} = HTTP.get(result)
|
||||
|
||||
assert result_get.status == 200
|
||||
end
|
||||
|
||||
test "properly encode AWS S3 queries" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
url =
|
||||
"https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=accessKEY%2F20130721%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130721T201207Z&X-Amz-Expires=86400&X-Amz-Signature=SIGNATURE&X-Amz-SignedHeaders=host"
|
||||
|
||||
unencoded_url =
|
||||
"https://examplebucket.s3.amazonaws.com/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=accessKEY/20130721/us-east-1/s3/aws4_request&X-Amz-Date=20130721T201207Z&X-Amz-Expires=86400&X-Amz-Signature=SIGNATURE&X-Amz-SignedHeaders=host"
|
||||
|
||||
result = URIEncoding.encode_url(url)
|
||||
result_unencoded = URIEncoding.encode_url(unencoded_url)
|
||||
|
||||
assert result == url
|
||||
assert result == result_unencoded
|
||||
|
||||
{:ok, result_get} = HTTP.get(result)
|
||||
|
||||
assert result_get.status == 200
|
||||
end
|
||||
|
||||
test "preserves query key order" do
|
||||
clear_config(:test_url_encoding, true)
|
||||
|
||||
url = "https://example.com/foo?hjkl=qwertz&xyz=abc&bar=baz"
|
||||
|
||||
result = URIEncoding.encode_url(url)
|
||||
|
||||
assert result == url
|
||||
end
|
||||
end
|
||||
|
|
|
|||
59
test/pleroma/language/translation/translate_locally_test.exs
Normal file
59
test/pleroma/language/translation/translate_locally_test.exs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Language.Translation.TranslateLocallyTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Language.Translation.TranslateLocally
|
||||
|
||||
@example_models %{
|
||||
"de" => %{
|
||||
"en" => "de-en-base"
|
||||
},
|
||||
"en" => %{
|
||||
"de" => "en-de-base",
|
||||
"pl" => "en-pl-tiny"
|
||||
},
|
||||
"cs" => %{
|
||||
"en" => "cs-en-base"
|
||||
},
|
||||
"pl" => %{
|
||||
"en" => "pl-en-tiny"
|
||||
}
|
||||
}
|
||||
|
||||
test "it returns languages list" do
|
||||
clear_config([Pleroma.Language.Translation.TranslateLocally, :models], @example_models)
|
||||
|
||||
assert {:ok, languages} = TranslateLocally.supported_languages(:source)
|
||||
assert ["cs", "de", "en", "pl"] = languages |> Enum.sort()
|
||||
end
|
||||
|
||||
describe "it returns languages matrix" do
|
||||
test "without intermediary language" do
|
||||
clear_config([Pleroma.Language.Translation.TranslateLocally, :models], @example_models)
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"cs" => ["en"],
|
||||
"de" => ["en"],
|
||||
"en" => ["de", "pl"],
|
||||
"pl" => ["en"]
|
||||
}} = TranslateLocally.languages_matrix()
|
||||
end
|
||||
|
||||
test "with intermediary language" do
|
||||
clear_config([Pleroma.Language.Translation.TranslateLocally, :models], @example_models)
|
||||
clear_config([Pleroma.Language.Translation.TranslateLocally, :intermediary_language], "en")
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"cs" => ["de", "en", "pl"],
|
||||
"de" => ["en", "pl"],
|
||||
"en" => ["de", "pl"],
|
||||
"pl" => ["de", "en"]
|
||||
}} = TranslateLocally.languages_matrix()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,6 +17,7 @@ defmodule Pleroma.NotificationTest do
|
|||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.NotificationView
|
||||
alias Pleroma.Web.Streamer
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Test.StaticConfig)
|
||||
|
|
@ -446,8 +447,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
describe "set_read_up_to()" do
|
||||
test "it sets all notifications as read up to a specified notification ID" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
[user, other_user] = insert_pair(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
|
|
@ -486,6 +486,37 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
assert m.last_read_id == to_string(n2.id)
|
||||
end
|
||||
|
||||
@tag needs_streamer: true
|
||||
test "it sends updated marker to the 'user' and the 'user:notification' stream" do
|
||||
%{user: user, token: oauth_token} = oauth_access(["read"])
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(other_user, %{
|
||||
status: "hi @#{user.nickname}!"
|
||||
})
|
||||
|
||||
[%{id: notification_id}] = Notification.for_user(user)
|
||||
|
||||
notification_id = to_string(notification_id)
|
||||
|
||||
task =
|
||||
Task.async(fn ->
|
||||
{:ok, _topic} =
|
||||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
|
||||
assert_receive {:text, event}, 4_000
|
||||
|
||||
assert %{"event" => "marker", "payload" => payload} = Jason.decode!(event)
|
||||
|
||||
assert %{"notifications" => %{"last_read_id" => ^notification_id}} =
|
||||
Jason.decode!(payload)
|
||||
end)
|
||||
|
||||
Notification.set_read_up_to(user, notification_id)
|
||||
Task.await(task)
|
||||
end
|
||||
end
|
||||
|
||||
describe "for_user_since/2" do
|
||||
|
|
|
|||
|
|
@ -396,18 +396,29 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
end
|
||||
end
|
||||
|
||||
# Hackey is used for Reverse Proxy when Hackney or Finch is the Tesla Adapter
|
||||
# Hackney is used for Reverse Proxy when Hackney or Finch is the Tesla Adapter
|
||||
# Gun is able to proxy through Tesla, so it does not need testing as the
|
||||
# test cases in the Pleroma.HTTPTest module are sufficient
|
||||
describe "Hackney URL encoding:" do
|
||||
setup do
|
||||
ClientMock
|
||||
|> expect(:request, fn :get,
|
||||
"https://example.com/emoji/Pack%201/koronebless.png?foo=bar+baz",
|
||||
_headers,
|
||||
_body,
|
||||
_opts ->
|
||||
{:ok, 200, [{"content-type", "image/png"}], "It works!"}
|
||||
|> expect(:request, fn
|
||||
:get,
|
||||
"https://example.com/emoji/Pack%201/koronebless.png?foo=bar+baz",
|
||||
_headers,
|
||||
_body,
|
||||
_opts ->
|
||||
{:ok, 200, [{"content-type", "image/png"}], "It works!"}
|
||||
|
||||
:get,
|
||||
"https://example.com/media/foo/bar%20!$&'()*+,;=/:%20@a%20%5Bbaz%5D.mp4",
|
||||
_headers,
|
||||
_body,
|
||||
_opts ->
|
||||
{:ok, 200, [{"content-type", "video/mp4"}], "Allowed reserved chars."}
|
||||
|
||||
:get, "https://example.com/media/unicode%20%F0%9F%99%82%20.gif", _headers, _body, _opts ->
|
||||
{:ok, 200, [{"content-type", "image/gif"}], "Unicode emoji in path"}
|
||||
end)
|
||||
|> stub(:stream_body, fn _ -> :done end)
|
||||
|> stub(:close, fn _ -> :ok end)
|
||||
|
|
@ -430,5 +441,21 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
|
||||
assert result.status == 200
|
||||
end
|
||||
|
||||
test "properly encodes URLs with allowed reserved characters", %{conn: conn} do
|
||||
url_with_reserved_chars = "https://example.com/media/foo/bar !$&'()*+,;=/: @a [baz].mp4"
|
||||
|
||||
result = ReverseProxy.call(conn, url_with_reserved_chars)
|
||||
|
||||
assert result.status == 200
|
||||
end
|
||||
|
||||
test "properly encodes URLs with unicode in path", %{conn: conn} do
|
||||
url_with_unicode = "https://example.com/media/unicode 🙂 .gif"
|
||||
|
||||
result = ReverseProxy.call(conn, url_with_unicode)
|
||||
|
||||
assert result.status == 200
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -227,20 +227,35 @@ defmodule Pleroma.UploadTest do
|
|||
assert Path.basename(attachment_url["href"]) == "an%E2%80%A6%20image.jpg"
|
||||
end
|
||||
|
||||
test "escapes reserved uri characters" do
|
||||
test "escapes disallowed reserved characters in uri path" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: ":?#[]@!$&\\'()*+,;=.jpg"
|
||||
filename: ":?#[]@!$&'()*+,;=.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[attachment_url | _] = data["url"]
|
||||
|
||||
assert Path.basename(attachment_url["href"]) ==
|
||||
"%3A%3F%23%5B%5D%40%21%24%26%5C%27%28%29%2A%2B%2C%3B%3D.jpg"
|
||||
":%3F%23%5B%5D@!$&'()*+,;=.jpg"
|
||||
end
|
||||
|
||||
test "double %-encodes filename" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "file with %20.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[attachment_url | _] = data["url"]
|
||||
|
||||
assert Path.basename(attachment_url["href"]) == "file%20with%20%2520.jpg"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -267,4 +282,23 @@ defmodule Pleroma.UploadTest do
|
|||
refute String.starts_with?(url, base_url <> "/media/")
|
||||
end
|
||||
end
|
||||
|
||||
describe "Setting a link_name for uploaded media" do
|
||||
setup do: clear_config([Pleroma.Upload, :link_name], true)
|
||||
|
||||
test "encodes name parameter in query" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "test file.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[attachment_url | _] = data["url"]
|
||||
|
||||
assert Path.basename(attachment_url["href"]) == "test%20file.jpg?name=test+file.jpg"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -366,5 +366,13 @@ defmodule Pleroma.UserSearchTest do
|
|||
|
||||
assert user == result |> Map.put(:search_rank, nil) |> Map.put(:search_type, nil)
|
||||
end
|
||||
|
||||
test "find users accepting chat messages only" do
|
||||
user1 = insert(:user, nickname: "user1", accepts_chat_messages: true)
|
||||
insert(:user, nickname: "user2", accepts_chat_messages: false)
|
||||
|
||||
[found_user1] = User.search("user", capabilities: ["accepts_chat_messages"])
|
||||
assert found_user1.id == user1.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1881,6 +1881,11 @@ defmodule Pleroma.UserTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "get_or_fetch_public_key_for_ap_id fetches a user that's not in the db" do
|
||||
assert {:ok, _key} =
|
||||
User.get_or_fetch_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||
end
|
||||
|
||||
test "get_public_key_for_ap_id returns correctly for user that's not in the db" do
|
||||
assert :error = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -465,6 +465,40 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "works with avatar/banner href as list" do
|
||||
user_id = "https://queef.in/cute_cat"
|
||||
|
||||
user_data =
|
||||
"test/fixtures/users_mock/href_as_array.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|> Map.delete("featured")
|
||||
|> Jason.encode!()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: ^user_id
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: user_data,
|
||||
headers: [{"content-type", "application/activity+json"}]
|
||||
}
|
||||
end)
|
||||
|
||||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||
|
||||
assert length(user.avatar["url"]) == 1
|
||||
assert length(user.banner["url"]) == 1
|
||||
|
||||
assert user.avatar["url"] |> List.first() |> Map.fetch!("href") ==
|
||||
"https://queef.in/storage/profile.webp"
|
||||
|
||||
assert user.banner["url"] |> List.first() |> Map.fetch!("href") ==
|
||||
"https://queef.in/storage/banner.gif"
|
||||
end
|
||||
|
||||
test "it fetches the appropriate tag-restricted posts" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
|||
|
|
@ -109,4 +109,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
|
|||
{:ok, filtered} = InlineQuotePolicy.filter(activity)
|
||||
assert filtered == activity
|
||||
end
|
||||
|
||||
# Mastodon uses p tags instead of span in their quote posts
|
||||
# URLs in quoteUri and post content are already mismatched
|
||||
test "skips objects which already have an .inline-quote p" do
|
||||
object = File.read!("test/fixtures/quote_post/mastodon_quote_post.json") |> Jason.decode!()
|
||||
|
||||
# Normally the ObjectValidator will fix this before it reaches MRF
|
||||
object = Map.put(object, "quoteUrl", object["quoteUri"])
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://mastodon.social/users/gwynnion",
|
||||
"object" => object
|
||||
}
|
||||
|
||||
{:ok, filtered} = InlineQuotePolicy.filter(activity)
|
||||
assert filtered == activity
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -282,6 +282,21 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
"#{Pleroma.Web.Endpoint.url()}/users/#{user.nickname}/feed.atom"
|
||||
end
|
||||
|
||||
test "redirects to rss feed when explicitly requested", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get("/users/#{user.nickname}.rss")
|
||||
|
||||
assert conn.status == 302
|
||||
|
||||
assert redirected_to(conn) ==
|
||||
"#{Pleroma.Web.Endpoint.url()}/users/#{user.nickname}/feed.rss"
|
||||
end
|
||||
|
||||
test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|
|
|
|||
|
|
@ -2104,6 +2104,50 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> json_response_and_validate_schema(404)
|
||||
end
|
||||
|
||||
test "account lookup with restrict unauthenticated profiles for local" do
|
||||
clear_config([:restrict_unauthenticated, :profiles, :local], true)
|
||||
|
||||
user = insert(:user, local: true)
|
||||
reading_user = insert(:user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> get("/api/v1/accounts/lookup?acct=#{user.nickname}")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 401)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, reading_user)
|
||||
|> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
|
||||
|> get("/api/v1/accounts/lookup?acct=#{user.nickname}")
|
||||
|
||||
assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
|
||||
assert id == user.id
|
||||
end
|
||||
|
||||
test "account lookup with restrict unauthenticated profiles for remote" do
|
||||
clear_config([:restrict_unauthenticated, :profiles, :remote], true)
|
||||
|
||||
user = insert(:user, nickname: "user@example.com", local: false)
|
||||
reading_user = insert(:user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> get("/api/v1/accounts/lookup?acct=#{user.nickname}")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 401)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, reading_user)
|
||||
|> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
|
||||
|> get("/api/v1/accounts/lookup?acct=#{user.nickname}")
|
||||
|
||||
assert %{"id" => id} = json_response_and_validate_schema(conn, 200)
|
||||
assert id == user.id
|
||||
end
|
||||
|
||||
test "create a note on a user" do
|
||||
%{conn: conn} = oauth_access(["write:accounts", "read:follows"])
|
||||
other_user = insert(:user)
|
||||
|
|
@ -2134,7 +2178,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{"id" => ^id1, "endorsed" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{id1}/pin")
|
||||
|> post("/api/v1/accounts/#{id1}/endorse")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] =
|
||||
|
|
@ -2153,7 +2197,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{"id" => ^id1, "endorsed" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{id1}/unpin")
|
||||
|> post("/api/v1/accounts/#{id1}/unendorse")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] =
|
||||
|
|
@ -2172,15 +2216,40 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{id1}/pin")
|
||||
|> post("/api/v1/accounts/#{id1}/endorse")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"error" => "You have already pinned the maximum number of users"} =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/accounts/#{id2}/pin")
|
||||
|> post("/api/v1/accounts/#{id2}/endorse")
|
||||
|> json_response_and_validate_schema(400)
|
||||
end
|
||||
|
||||
test "returns a list of pinned accounts", %{conn: conn} do
|
||||
clear_config([:instance, :max_endorsed_users], 3)
|
||||
|
||||
%{id: id1} = user1 = insert(:user)
|
||||
%{id: id2} = user2 = insert(:user)
|
||||
%{id: id3} = user3 = insert(:user)
|
||||
|
||||
CommonAPI.follow(user2, user1)
|
||||
CommonAPI.follow(user3, user1)
|
||||
|
||||
User.endorse(user1, user2)
|
||||
User.endorse(user1, user3)
|
||||
|
||||
[%{"id" => ^id2}, %{"id" => ^id3}] =
|
||||
conn
|
||||
|> get("/api/v1/accounts/#{id1}/endorsements")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "returns 404 error when specified user is not exist", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/accounts/test/endorsements")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "familiar followers" do
|
||||
|
|
|
|||
|
|
@ -194,4 +194,28 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|
|||
refute Map.has_key?(result["pleroma"]["metadata"]["base_urls"], "media_proxy")
|
||||
refute Map.has_key?(result["pleroma"]["metadata"]["base_urls"], "upload")
|
||||
end
|
||||
|
||||
test "display timeline access restrictions", %{conn: conn} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], false)
|
||||
|
||||
conn = get(conn, "/api/v2/instance")
|
||||
|
||||
assert result = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
assert result["configuration"]["timelines_access"] == %{
|
||||
"live_feeds" => %{
|
||||
"local" => "authenticated",
|
||||
"remote" => "public"
|
||||
},
|
||||
"hashtag_feeds" => %{
|
||||
"local" => "authenticated",
|
||||
"remote" => "public"
|
||||
},
|
||||
"trending_link_feeds" => %{
|
||||
"local" => "disabled",
|
||||
"remote" => "disabled"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1867,18 +1867,29 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
%{activity: activity}
|
||||
end
|
||||
|
||||
test "returns users who have favorited the status", %{conn: conn, activity: activity} do
|
||||
other_user = insert(:user)
|
||||
{:ok, _} = CommonAPI.favorite(activity.id, other_user)
|
||||
test "returns users who have favorited the status ordered from newest to oldest", %{
|
||||
conn: conn,
|
||||
activity: activity
|
||||
} do
|
||||
[other_user_1, other_user_2] = insert_pair(:user)
|
||||
[other_user_3, other_user_4] = insert_pair(:user)
|
||||
|
||||
{:ok, _} = CommonAPI.favorite(activity.id, other_user_1)
|
||||
{:ok, _} = CommonAPI.favorite(activity.id, other_user_3)
|
||||
{:ok, _} = CommonAPI.favorite(activity.id, other_user_2)
|
||||
{:ok, _} = CommonAPI.favorite(activity.id, other_user_4)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}/favourited_by")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
[%{"id" => id}] = response
|
||||
[%{"id" => id1}, %{"id" => id2}, %{"id" => id3}, %{"id" => id4}] = response
|
||||
|
||||
assert id == other_user.id
|
||||
assert id1 == other_user_4.id
|
||||
assert id2 == other_user_2.id
|
||||
assert id3 == other_user_3.id
|
||||
assert id4 == other_user_1.id
|
||||
end
|
||||
|
||||
test "returns empty array when status has not been favorited yet", %{
|
||||
|
|
@ -2541,4 +2552,47 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> json_response_and_validate_schema(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting quotes of a specified post" do
|
||||
setup do
|
||||
[current_user, user] = insert_pair(:user)
|
||||
%{user: current_user, conn: conn} = oauth_access(["read:statuses"], user: current_user)
|
||||
[current_user: current_user, user: user, conn: conn]
|
||||
end
|
||||
|
||||
test "shows quotes of a post", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
activity = insert(:note_activity)
|
||||
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "quoat", quote_id: activity.id})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}/quotes")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
[status] = response
|
||||
|
||||
assert length(response) == 1
|
||||
assert status["id"] == quote_post.id
|
||||
end
|
||||
|
||||
test "returns 404 error when a post can't be seen", %{conn: conn} do
|
||||
activity = insert(:direct_note_activity)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}/quotes")
|
||||
|
||||
assert json_response_and_validate_schema(response, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
|
||||
test "returns 404 error when a post does not exist", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/idontexist/quotes")
|
||||
|
||||
assert json_response_and_validate_schema(response, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -344,7 +344,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
quotes_count: 0,
|
||||
bookmark_folder: nil,
|
||||
list_id: nil
|
||||
}
|
||||
},
|
||||
quotes_count: 0
|
||||
}
|
||||
|
||||
assert status == expected
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
end
|
||||
|
||||
test "encodes and decodes URL and ignores query params for the path" do
|
||||
url = "https://pleroma.soykaf.com/static/logo.png?93939393939&bunny=true"
|
||||
url = "https://pleroma.soykaf.com/static/logo.png?93939393939=&bunny=true"
|
||||
encoded = MediaProxy.url(url)
|
||||
assert String.ends_with?(encoded, "/logo.png")
|
||||
assert decode_result(encoded) == url
|
||||
|
|
@ -159,18 +159,6 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
assert String.starts_with?(encoded, base_url)
|
||||
end
|
||||
|
||||
# Some sites expect ASCII encoded characters in the URL to be preserved even if
|
||||
# unnecessary.
|
||||
# Issues: https://git.pleroma.social/pleroma/pleroma/issues/580
|
||||
# https://git.pleroma.social/pleroma/pleroma/issues/1055
|
||||
test "preserve ASCII encoding" do
|
||||
url =
|
||||
"https://pleroma.com/%20/%21/%22/%23/%24/%25/%26/%27/%28/%29/%2A/%2B/%2C/%2D/%2E/%2F/%30/%31/%32/%33/%34/%35/%36/%37/%38/%39/%3A/%3B/%3C/%3D/%3E/%3F/%40/%41/%42/%43/%44/%45/%46/%47/%48/%49/%4A/%4B/%4C/%4D/%4E/%4F/%50/%51/%52/%53/%54/%55/%56/%57/%58/%59/%5A/%5B/%5C/%5D/%5E/%5F/%60/%61/%62/%63/%64/%65/%66/%67/%68/%69/%6A/%6B/%6C/%6D/%6E/%6F/%70/%71/%72/%73/%74/%75/%76/%77/%78/%79/%7A/%7B/%7C/%7D/%7E/%7F/%80/%81/%82/%83/%84/%85/%86/%87/%88/%89/%8A/%8B/%8C/%8D/%8E/%8F/%90/%91/%92/%93/%94/%95/%96/%97/%98/%99/%9A/%9B/%9C/%9D/%9E/%9F/%C2%A0/%A1/%A2/%A3/%A4/%A5/%A6/%A7/%A8/%A9/%AA/%AB/%AC/%C2%AD/%AE/%AF/%B0/%B1/%B2/%B3/%B4/%B5/%B6/%B7/%B8/%B9/%BA/%BB/%BC/%BD/%BE/%BF/%C0/%C1/%C2/%C3/%C4/%C5/%C6/%C7/%C8/%C9/%CA/%CB/%CC/%CD/%CE/%CF/%D0/%D1/%D2/%D3/%D4/%D5/%D6/%D7/%D8/%D9/%DA/%DB/%DC/%DD/%DE/%DF/%E0/%E1/%E2/%E3/%E4/%E5/%E6/%E7/%E8/%E9/%EA/%EB/%EC/%ED/%EE/%EF/%F0/%F1/%F2/%F3/%F4/%F5/%F6/%F7/%F8/%F9/%FA/%FB/%FC/%FD/%FE/%FF"
|
||||
|
||||
encoded = MediaProxy.url(url)
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
# This includes unsafe/reserved characters which are not interpreted as part of the URL
|
||||
# and would otherwise have to be ASCII encoded. It is our role to ensure the proxied URL
|
||||
# is unmodified, so we are testing these characters anyway.
|
||||
|
|
@ -182,11 +170,30 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
test "preserve unicode characters" do
|
||||
# Improperly encoded URLs should not happen even when input was wrong.
|
||||
test "does not preserve unicode characters" do
|
||||
url = "https://ko.wikipedia.org/wiki/위키백과:대문"
|
||||
|
||||
encoded_url =
|
||||
"https://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8C%80%EB%AC%B8"
|
||||
|
||||
encoded = MediaProxy.url(url)
|
||||
assert decode_result(encoded) == url
|
||||
assert decode_result(encoded) == encoded_url
|
||||
end
|
||||
|
||||
# If we preserve wrongly encoded URLs in MediaProxy, it will get fixed
|
||||
# when we GET these URLs and will result in 424 when MediaProxy previews are enabled.
|
||||
test "does not preserve incorrect URLs when making MediaProxy link" do
|
||||
incorrect_original_url = "https://example.com/media/cofe%20%28with%20milk%29.png"
|
||||
corrected_original_url = "https://example.com/media/cofe%20(with%20milk).png"
|
||||
|
||||
unpreserved_encoded_original_url =
|
||||
"http://localhost:4001/proxy/Sv6tt6xjA72_i4d8gXbuMAOXQSs/aHR0cHM6Ly9leGFtcGxlLmNvbS9tZWRpYS9jb2ZlJTIwKHdpdGglMjBtaWxrKS5wbmc/cofe%20(with%20milk).png"
|
||||
|
||||
encoded = MediaProxy.url(incorrect_original_url)
|
||||
|
||||
assert encoded == unpreserved_encoded_original_url
|
||||
assert decode_result(encoded) == corrected_original_url
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -280,35 +280,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "account endorsements" do
|
||||
test "returns a list of pinned accounts", %{conn: conn} do
|
||||
%{id: id1} = user1 = insert(:user)
|
||||
%{id: id2} = user2 = insert(:user)
|
||||
%{id: id3} = user3 = insert(:user)
|
||||
|
||||
CommonAPI.follow(user2, user1)
|
||||
CommonAPI.follow(user3, user1)
|
||||
|
||||
User.endorse(user1, user2)
|
||||
User.endorse(user1, user3)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/accounts/#{id1}/endorsements")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert length(response) == 2
|
||||
assert Enum.any?(response, fn user -> user["id"] == id2 end)
|
||||
assert Enum.any?(response, fn user -> user["id"] == id3 end)
|
||||
end
|
||||
|
||||
test "returns 404 error when specified user is not exist", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/pleroma/accounts/test/endorsements")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "birthday reminders" do
|
||||
test "returns a list of friends having birthday on specified day" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:accounts"])
|
||||
|
|
|
|||
|
|
@ -337,6 +337,41 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/pleroma/chats/:id/pin" do
|
||||
setup do: oauth_access(["write:chats"])
|
||||
|
||||
test "it pins a chat", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> post("/api/v1/pleroma/chats/#{chat.id}/pin")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"pinned" => true} = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/pleroma/chats/:id/unpin" do
|
||||
setup do: oauth_access(["write:chats"])
|
||||
|
||||
test "it unpins a chat", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
|
||||
{:ok, chat} = Chat.pin(chat)
|
||||
|
||||
result =
|
||||
conn
|
||||
|> post("/api/v1/pleroma/chats/#{chat.id}/unpin")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"pinned" => false} = result
|
||||
end
|
||||
end
|
||||
|
||||
for tested_endpoint <- ["/api/v1/pleroma/chats", "/api/v2/pleroma/chats"] do
|
||||
describe "GET #{tested_endpoint}" do
|
||||
setup do: oauth_access(["read:chats"])
|
||||
|
|
@ -407,6 +442,21 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|
|||
assert length(result) == 1
|
||||
end
|
||||
|
||||
test "it only returns pinned chats", %{conn: conn, user: user} do
|
||||
recipient1 = insert(:user)
|
||||
recipient2 = insert(:user)
|
||||
|
||||
{:ok, %{id: id} = chat} = Chat.get_or_create(user.id, recipient1.ap_id)
|
||||
{:ok, _} = Chat.get_or_create(user.id, recipient2.ap_id)
|
||||
|
||||
Chat.pin(chat)
|
||||
|
||||
[%{"id" => ^id, "pinned" => true}] =
|
||||
conn
|
||||
|> get("#{unquote(tested_endpoint)}?pinned=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
if tested_endpoint == "/api/v1/pleroma/chats" do
|
||||
test "it returns all chats", %{conn: conn, user: user} do
|
||||
Enum.each(1..30, fn _ ->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2024 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.PleromaAPI.FollowRequestControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "/api/v1/pleroma/outgoing_follow_requests works" do
|
||||
%{conn: conn, user: user} = oauth_access(["read:follows"])
|
||||
|
||||
other_user1 = insert(:user)
|
||||
other_user2 = insert(:user, is_locked: true)
|
||||
_other_user3 = insert(:user)
|
||||
|
||||
{:ok, _, _, _} = CommonAPI.follow(other_user1, user)
|
||||
{:ok, _, _, _} = CommonAPI.follow(other_user2, user)
|
||||
|
||||
conn = get(conn, "/api/v1/pleroma/outgoing_follow_requests")
|
||||
|
||||
assert [relationship] = json_response_and_validate_schema(conn, 200)
|
||||
assert to_string(other_user2.id) == relationship["id"]
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
defmodule Pleroma.Web.PleromaAPI.FrontendSettingsControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
|
||||
describe "PUT /api/v1/pleroma/preferred_frontend" do
|
||||
test "sets a cookie with selected frontend" do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/pleroma/preferred_frontend", %{"frontend_name" => "pleroma-fe/stable"})
|
||||
|
||||
json_response_and_validate_schema(response, 200)
|
||||
assert %{"preferred_frontend" => %{value: "pleroma-fe/stable"}} = response.resp_cookies
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
|
|||
|
||||
describe "POST /api/v1/pleroma/scrobble" do
|
||||
test "works correctly" do
|
||||
%{conn: conn} = oauth_access(["write"])
|
||||
%{conn: conn} = oauth_access(["write:scrobbles"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -51,7 +51,7 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
|
|||
|
||||
describe "GET /api/v1/pleroma/accounts/:id/scrobbles" do
|
||||
test "works correctly" do
|
||||
%{user: user, conn: conn} = oauth_access(["read"])
|
||||
%{user: user, conn: conn} = oauth_access(["read:scrobbles"])
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.listen(user, %{
|
||||
|
|
|
|||
|
|
@ -9,46 +9,22 @@ defmodule Pleroma.Web.PleromaAPI.StatusControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "getting quotes of a specified post" do
|
||||
setup do
|
||||
[current_user, user] = insert_pair(:user)
|
||||
%{user: current_user, conn: conn} = oauth_access(["read:statuses"], user: current_user)
|
||||
[current_user: current_user, user: user, conn: conn]
|
||||
end
|
||||
test "/quotes fallback works" do
|
||||
[current_user, user] = insert_pair(:user)
|
||||
%{conn: conn} = oauth_access(["read:statuses"], user: current_user)
|
||||
|
||||
test "shows quotes of a post", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
activity = insert(:note_activity)
|
||||
activity = insert(:note_activity)
|
||||
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "quoat", quoted_status_id: activity.id})
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "quoat", quoted_status_id: activity.id})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/quotes")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/quotes")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
[status] = response
|
||||
[status] = response
|
||||
|
||||
assert length(response) == 1
|
||||
assert status["id"] == quote_post.id
|
||||
end
|
||||
|
||||
test "returns 404 error when a post can't be seen", %{conn: conn} do
|
||||
activity = insert(:direct_note_activity)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/quotes")
|
||||
|
||||
assert json_response_and_validate_schema(response, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
|
||||
test "returns 404 error when a post does not exist", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/idontexist/quotes")
|
||||
|
||||
assert json_response_and_validate_schema(response, 404) == %{"error" => "Record not found"}
|
||||
end
|
||||
assert length(response) == 1
|
||||
assert status["id"] == quote_post.id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
|
|||
AccountView.render("show.json", user: recipient, skip_visibility_check: true),
|
||||
unread: 0,
|
||||
last_message: nil,
|
||||
updated_at: Utils.to_masto_date(chat.updated_at)
|
||||
updated_at: Utils.to_masto_date(chat.updated_at),
|
||||
pinned: false
|
||||
}
|
||||
|
||||
{:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
"users",
|
||||
"tags",
|
||||
"mailer",
|
||||
"frontend_switcher",
|
||||
"inbox",
|
||||
"relay",
|
||||
"internal",
|
||||
|
|
@ -113,4 +114,36 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
|
||||
assert expected_routes == Pleroma.Web.Router.get_api_routes()
|
||||
end
|
||||
|
||||
describe "preferred frontend cookie handling" do
|
||||
test "returns preferred frontend file", %{conn: conn} do
|
||||
name = "test-fe"
|
||||
ref = "develop"
|
||||
|
||||
clear_config([:frontends, :pickable], ["#{name}/#{ref}"])
|
||||
path = "#{@dir}/frontends/#{name}/#{ref}"
|
||||
|
||||
Pleroma.Backports.mkdir_p!(path)
|
||||
File.write!("#{path}/index.html", "from frontend plug")
|
||||
|
||||
index =
|
||||
conn
|
||||
|> put_req_cookie("preferred_frontend", "#{name}/#{ref}")
|
||||
|> get("/")
|
||||
|
||||
assert html_response(index, 200) == "from frontend plug"
|
||||
end
|
||||
|
||||
test "only returns content from pickable frontends", %{conn: conn} do
|
||||
clear_config([:instance, :static_dir], "instance/static")
|
||||
clear_config([:frontends, :pickable], ["pleroma-fe/develop", "pl-fe/develop"])
|
||||
|
||||
config_file =
|
||||
conn
|
||||
|> put_req_cookie("preferred_frontend", "../../../config")
|
||||
|> get("/config.exs")
|
||||
|
||||
refute response(config_file, 200) =~ "import Config"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -883,7 +883,7 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert Streamer.filtered_by_user?(user1, notif)
|
||||
end
|
||||
|
||||
test "it send non-reblog notification for reblog-muted actors", %{
|
||||
test "it sends non-reblog notification for reblog-muted actors", %{
|
||||
user: user1,
|
||||
token: user1_token
|
||||
} do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue