Merge remote-tracking branch 'remotes/origin/develop' into 2168-media-preview-proxy
# Conflicts: # config/config.exs # lib/pleroma/web/media_proxy/media_proxy.ex # mix.lock # test/web/media_proxy/media_proxy_test.exs
This commit is contained in:
commit
bdf57b8ef4
360 changed files with 5783 additions and 4648 deletions
|
|
@ -44,7 +44,7 @@ defmodule Pleroma.ActivityExpirationTest do
|
|||
%{activity_id: activity.id, scheduled_at: naive_datetime}
|
||||
)
|
||||
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(:ops, :pid)
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(%Oban.Job{})
|
||||
|
||||
refute Pleroma.Repo.get(Pleroma.Activity, activity.id)
|
||||
refute Pleroma.Repo.get(Pleroma.ActivityExpiration, expiration.id)
|
||||
|
|
|
|||
|
|
@ -54,4 +54,12 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
|
|||
assert Pleroma.Config.get(new_group2) == 2
|
||||
assert Pleroma.Config.get(new_group3) == 3
|
||||
end
|
||||
|
||||
test "check_media_proxy_whitelist_config/0" do
|
||||
clear_config([:media_proxy, :whitelist], ["https://example.com", "example2.com"])
|
||||
|
||||
assert capture_log(fn ->
|
||||
Pleroma.Config.DeprecationWarnings.check_media_proxy_whitelist_config()
|
||||
end) =~ "Your config is using old format (only domain) for MediaProxy whitelist option"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ defmodule Pleroma.Config.HolderTest do
|
|||
test "default_config/0" do
|
||||
config = Holder.default_config()
|
||||
assert config[:pleroma][Pleroma.Uploaders.Local][:uploads] == "test/uploads"
|
||||
assert config[:tesla][:adapter] == Tesla.Mock
|
||||
|
||||
refute config[:pleroma][Pleroma.Repo]
|
||||
refute config[:pleroma][Pleroma.Web.Endpoint]
|
||||
|
|
@ -18,17 +17,15 @@ defmodule Pleroma.Config.HolderTest do
|
|||
refute config[:pleroma][:configurable_from_database]
|
||||
refute config[:pleroma][:database]
|
||||
refute config[:phoenix][:serve_endpoints]
|
||||
refute config[:tesla][:adapter]
|
||||
end
|
||||
|
||||
test "default_config/1" do
|
||||
pleroma_config = Holder.default_config(:pleroma)
|
||||
assert pleroma_config[Pleroma.Uploaders.Local][:uploads] == "test/uploads"
|
||||
tesla_config = Holder.default_config(:tesla)
|
||||
assert tesla_config[:adapter] == Tesla.Mock
|
||||
end
|
||||
|
||||
test "default_config/2" do
|
||||
assert Holder.default_config(:pleroma, Pleroma.Uploaders.Local) == [uploads: "test/uploads"]
|
||||
assert Holder.default_config(:tesla, :adapter) == Tesla.Mock
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,21 +13,13 @@ defmodule Pleroma.Docs.GeneratorTest do
|
|||
key: :uploader,
|
||||
type: :module,
|
||||
description: "",
|
||||
suggestions:
|
||||
Generator.list_modules_in_dir(
|
||||
"lib/pleroma/upload/filter",
|
||||
"Elixir.Pleroma.Upload.Filter."
|
||||
)
|
||||
suggestions: {:list_behaviour_implementations, Pleroma.Upload.Filter}
|
||||
},
|
||||
%{
|
||||
key: :filters,
|
||||
type: {:list, :module},
|
||||
description: "",
|
||||
suggestions:
|
||||
Generator.list_modules_in_dir(
|
||||
"lib/pleroma/web/activity_pub/mrf",
|
||||
"Elixir.Pleroma.Web.ActivityPub.MRF."
|
||||
)
|
||||
suggestions: {:list_behaviour_implementations, Pleroma.Web.ActivityPub.MRF}
|
||||
},
|
||||
%{
|
||||
key: Pleroma.Upload,
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ defmodule Pleroma.Emails.AdminEmailTest do
|
|||
account_url
|
||||
}\">#{account.nickname}</a></p>\n<p>Comment: Test comment\n<p> Statuses:\n <ul>\n <li><a href=\"#{
|
||||
status_url
|
||||
}\">#{status_url}</li>\n </ul>\n</p>\n\n"
|
||||
}\">#{status_url}</li>\n </ul>\n</p>\n\n<p>\n<a href=\"http://localhost:4001/pleroma/admin/#/reports/index\">View Reports in AdminFE</a>\n"
|
||||
end
|
||||
|
||||
test "it works when the reporter is a remote user without email" do
|
||||
|
|
|
|||
|
|
@ -3,37 +3,39 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.FilterTest do
|
||||
alias Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Filter
|
||||
alias Pleroma.Repo
|
||||
|
||||
describe "creating filters" do
|
||||
test "creating one filter" do
|
||||
user = insert(:user)
|
||||
|
||||
query = %Pleroma.Filter{
|
||||
query = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 42,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query)
|
||||
result = Pleroma.Filter.get(filter.filter_id, user)
|
||||
{:ok, %Filter{} = filter} = Filter.create(query)
|
||||
result = Filter.get(filter.filter_id, user)
|
||||
assert query.phrase == result.phrase
|
||||
end
|
||||
|
||||
test "creating one filter without a pre-defined filter_id" do
|
||||
user = insert(:user)
|
||||
|
||||
query = %Pleroma.Filter{
|
||||
query = %Filter{
|
||||
user_id: user.id,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter} = Pleroma.Filter.create(query)
|
||||
{:ok, %Filter{} = filter} = Filter.create(query)
|
||||
# Should start at 1
|
||||
assert filter.filter_id == 1
|
||||
end
|
||||
|
|
@ -41,23 +43,23 @@ defmodule Pleroma.FilterTest do
|
|||
test "creating additional filters uses previous highest filter_id + 1" do
|
||||
user = insert(:user)
|
||||
|
||||
query_one = %Pleroma.Filter{
|
||||
query_one = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 42,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one)
|
||||
{:ok, %Filter{} = filter_one} = Filter.create(query_one)
|
||||
|
||||
query_two = %Pleroma.Filter{
|
||||
query_two = %Filter{
|
||||
user_id: user.id,
|
||||
# No filter_id
|
||||
phrase: "who",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two)
|
||||
{:ok, %Filter{} = filter_two} = Filter.create(query_two)
|
||||
assert filter_two.filter_id == filter_one.filter_id + 1
|
||||
end
|
||||
|
||||
|
|
@ -65,29 +67,29 @@ defmodule Pleroma.FilterTest do
|
|||
user_one = insert(:user)
|
||||
user_two = insert(:user)
|
||||
|
||||
query_one = %Pleroma.Filter{
|
||||
query_one = %Filter{
|
||||
user_id: user_one.id,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter_one} = Pleroma.Filter.create(query_one)
|
||||
{:ok, %Filter{} = filter_one} = Filter.create(query_one)
|
||||
|
||||
query_two = %Pleroma.Filter{
|
||||
query_two = %Filter{
|
||||
user_id: user_two.id,
|
||||
phrase: "who",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, %Pleroma.Filter{} = filter_two} = Pleroma.Filter.create(query_two)
|
||||
{:ok, %Filter{} = filter_two} = Filter.create(query_two)
|
||||
|
||||
assert filter_one.filter_id == 1
|
||||
assert filter_two.filter_id == 1
|
||||
|
||||
result_one = Pleroma.Filter.get(filter_one.filter_id, user_one)
|
||||
result_one = Filter.get(filter_one.filter_id, user_one)
|
||||
assert result_one.phrase == filter_one.phrase
|
||||
|
||||
result_two = Pleroma.Filter.get(filter_two.filter_id, user_two)
|
||||
result_two = Filter.get(filter_two.filter_id, user_two)
|
||||
assert result_two.phrase == filter_two.phrase
|
||||
end
|
||||
end
|
||||
|
|
@ -95,38 +97,38 @@ defmodule Pleroma.FilterTest do
|
|||
test "deleting a filter" do
|
||||
user = insert(:user)
|
||||
|
||||
query = %Pleroma.Filter{
|
||||
query = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 0,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, _filter} = Pleroma.Filter.create(query)
|
||||
{:ok, filter} = Pleroma.Filter.delete(query)
|
||||
assert is_nil(Repo.get(Pleroma.Filter, filter.filter_id))
|
||||
{:ok, _filter} = Filter.create(query)
|
||||
{:ok, filter} = Filter.delete(query)
|
||||
assert is_nil(Repo.get(Filter, filter.filter_id))
|
||||
end
|
||||
|
||||
test "getting all filters by an user" do
|
||||
user = insert(:user)
|
||||
|
||||
query_one = %Pleroma.Filter{
|
||||
query_one = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 1,
|
||||
phrase: "knights",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
query_two = %Pleroma.Filter{
|
||||
query_two = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 2,
|
||||
phrase: "who",
|
||||
context: ["home"]
|
||||
}
|
||||
|
||||
{:ok, filter_one} = Pleroma.Filter.create(query_one)
|
||||
{:ok, filter_two} = Pleroma.Filter.create(query_two)
|
||||
filters = Pleroma.Filter.get_filters(user)
|
||||
{:ok, filter_one} = Filter.create(query_one)
|
||||
{:ok, filter_two} = Filter.create(query_two)
|
||||
filters = Filter.get_filters(user)
|
||||
assert filter_one in filters
|
||||
assert filter_two in filters
|
||||
end
|
||||
|
|
@ -134,7 +136,7 @@ defmodule Pleroma.FilterTest do
|
|||
test "updating a filter" do
|
||||
user = insert(:user)
|
||||
|
||||
query_one = %Pleroma.Filter{
|
||||
query_one = %Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 1,
|
||||
phrase: "knights",
|
||||
|
|
@ -146,8 +148,9 @@ defmodule Pleroma.FilterTest do
|
|||
context: ["home", "timeline"]
|
||||
}
|
||||
|
||||
{:ok, filter_one} = Pleroma.Filter.create(query_one)
|
||||
{:ok, filter_two} = Pleroma.Filter.update(filter_one, changes)
|
||||
{:ok, filter_one} = Filter.create(query_one)
|
||||
{:ok, filter_two} = Filter.update(filter_one, changes)
|
||||
|
||||
assert filter_one != filter_two
|
||||
assert filter_two.phrase == changes.phrase
|
||||
assert filter_two.context == changes.context
|
||||
|
|
|
|||
BIN
test/fixtures/DSCN0010.jpg
vendored
Normal file
BIN
test/fixtures/DSCN0010.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
|
|
@ -26,6 +26,9 @@
|
|||
"summary": "\u003cp\u003e\u003c/p\u003e",
|
||||
"url": "http://mastodon.example.org/@admin",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"capabilities": {
|
||||
"acceptsChatMessages": true
|
||||
},
|
||||
"publicKey": {
|
||||
"id": "http://mastodon.example.org/users/admin#main-key",
|
||||
"owner": "http://mastodon.example.org/users/admin",
|
||||
|
|
|
|||
1
test/fixtures/tesla_mock/framatube.org-video.json
vendored
Normal file
1
test/fixtures/tesla_mock/framatube.org-video.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1
test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json
vendored
Normal file
1
test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"type":"Person","id":"https://framatube.org/accounts/framasoft","following":"https://framatube.org/accounts/framasoft/following","followers":"https://framatube.org/accounts/framasoft/followers","playlists":"https://framatube.org/accounts/framasoft/playlists","inbox":"https://framatube.org/accounts/framasoft/inbox","outbox":"https://framatube.org/accounts/framasoft/outbox","preferredUsername":"framasoft","url":"https://framatube.org/accounts/framasoft","name":"Framasoft","endpoints":{"sharedInbox":"https://framatube.org/inbox"},"publicKey":{"id":"https://framatube.org/accounts/framasoft#main-key","owner":"https://framatube.org/accounts/framasoft","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuRh3frgIg866D0y0FThp\nSUkJImMcHGkUvpYQYv2iUgarZZtEbwT8PfQf0bJazy+cP8KqQmMDf5PBhT7dfdny\nf/GKGMw9Olc+QISeKDj3sqZ3Csrm4KV4avMGCfth6eSU7LozojeSGCXdUFz/8UgE\nfhV4mJjEX/FbwRYoKlagv5rY9mkX5XomzZU+z9j6ZVXyofwOwJvmI1hq0SYDv2bc\neB/RgIh/H0nyMtF8o+0CT42FNEET9j9m1BKOBtPzwZHmitKRkEmui5cK256s1laB\nT61KHpcD9gQKkQ+I3sFEzCBUJYfVo6fUe+GehBZuAfq4qDhd15SfE4K9veDscDFI\nTwIDAQAB\n-----END PUBLIC KEY-----"},"icon":{"type":"Image","mediaType":"image/png","url":"https://framatube.org/lazy-static/avatars/f73876f5-1d45-4f8a-942a-d3d5d5ac5dc1.png"},"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"RsaSignature2017":"https://w3id.org/security#RsaSignature2017","pt":"https://joinpeertube.org/ns#","sc":"http://schema.org#","Hashtag":"as:Hashtag","uuid":"sc:identifier","category":"sc:category","licence":"sc:license","subtitleLanguage":"sc:subtitleLanguage","sensitive":"as:sensitive","language":"sc:inLanguage","expires":"sc:expires","CacheFile":"pt:CacheFile","Infohash":"pt:Infohash","originallyPublishedAt":"sc:datePublished","views":{"@type":"sc:Number","@id":"pt:views"},"state":{"@type":"sc:Number","@id":"pt:state"},"size":{"@type":"sc:Number","@id":"pt:size"},"fps":{"@type":"sc:Number","@id":"pt:fps"},"startTimestamp":{"@type":"sc:Number","@id":"pt:startTimestamp"},"stopTimestamp":{"@type":"sc:Number","@id":"pt:stopTimestamp"},"position":{"@type":"sc:Number","@id":"pt:position"},"commentsEnabled":{"@type":"sc:Boolean","@id":"pt:commentsEnabled"},"downloadEnabled":{"@type":"sc:Boolean","@id":"pt:downloadEnabled"},"waitTranscoding":{"@type":"sc:Boolean","@id":"pt:waitTranscoding"},"support":{"@type":"sc:Text","@id":"pt:support"}},{"likes":{"@id":"as:likes","@type":"@id"},"dislikes":{"@id":"as:dislikes","@type":"@id"},"playlists":{"@id":"pt:playlists","@type":"@id"},"shares":{"@id":"as:shares","@type":"@id"},"comments":{"@id":"as:comments","@type":"@id"}}],"summary":null}
|
||||
301
test/fixtures/tesla_mock/https___osada.macgirvin.com.html
vendored
Normal file
301
test/fixtures/tesla_mock/https___osada.macgirvin.com.html
vendored
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
<!DOCTYPE html >
|
||||
<html prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
<title>Osada</title>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=0"/>
|
||||
<meta property="generator" content="osada"/>
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/fork-awesome/css/fork-awesome.min.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/vendor/twbs/bootstrap/dist/css/bootstrap.min.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/bootstrap-tagsinput/bootstrap-tagsinput.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/bootstrap-red.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/datetimepicker/jquery.datetimepicker.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/tiptip/tipTip.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/jgrowl/jquery.jgrowl.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/jRange/jquery.range.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/conversation.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/widgets.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/colorbox.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/library/justifiedGallery/justifiedGallery.min.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/default.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/mod_home.css?v=2.3" type="text/css" media="screen">
|
||||
<link rel="stylesheet" href="http://osada.macgirvin.com/view/theme/redbasic/php/style.pcss?v=2.3" type="text/css" media="screen">
|
||||
|
||||
<script>
|
||||
|
||||
var aStr = {
|
||||
|
||||
'delitem' : "Delete this item?",
|
||||
'comment' : "Comment",
|
||||
'showmore' : "<i class='fa fa-chevron-down'></i> show all",
|
||||
'showfewer' : "<i class='fa fa-chevron-up'></i> show less",
|
||||
'divgrowmore' : "<i class='fa fa-chevron-down'></i> expand",
|
||||
'divgrowless' : "<i class='fa fa-chevron-up'></i> collapse",
|
||||
'pwshort' : "Password too short",
|
||||
'pwnomatch' : "Passwords do not match",
|
||||
'everybody' : "everybody",
|
||||
'passphrase' : "Secret Passphrase",
|
||||
'passhint' : "Passphrase hint",
|
||||
'permschange' : "Notice: Permissions have changed but have not yet been submitted.",
|
||||
'closeAll' : "close all",
|
||||
'nothingnew' : "Nothing new here",
|
||||
'rating_desc' : "Rate This Channel (this is public)",
|
||||
'rating_val' : "Rating",
|
||||
'rating_text' : "Describe (optional)",
|
||||
'submit' : "Submit",
|
||||
'linkurl' : "Please enter a link URL",
|
||||
'leavethispage' : "Unsaved changes. Are you sure you wish to leave this page?",
|
||||
'location' : "Location",
|
||||
'lovely' : "lovely",
|
||||
'wonderful' : "wonderful",
|
||||
'fantastic' : "fantastic",
|
||||
'great' : "great",
|
||||
'nick_invld1' : "Your chosen nickname was either already taken or not valid. Please use our suggestion (",
|
||||
'nick_invld2' : ") or enter a new one.",
|
||||
'nick_valid' : "Thank you, this nickname is valid.",
|
||||
'name_empty' : "A channel name is required.",
|
||||
'name_ok1' : "This is a ",
|
||||
'name_ok2' : " channel name",
|
||||
|
||||
|
||||
|
||||
't01' : "",
|
||||
't02' : "",
|
||||
't03' : "ago",
|
||||
't04' : "from now",
|
||||
't05' : "less than a minute",
|
||||
't06' : "about a minute",
|
||||
't07' : "%d minutes",
|
||||
't08' : "about an hour",
|
||||
't09' : "about %d hours",
|
||||
't10' : "a day",
|
||||
't11' : "%d days",
|
||||
't12' : "about a month",
|
||||
't13' : "%d months",
|
||||
't14' : "about a year",
|
||||
't15' : "%d years",
|
||||
't16' : " ",
|
||||
't17' : "[]",
|
||||
|
||||
'monthNames' : [ "January","February","March","April","May","June","July","August","September","October","November","December" ],
|
||||
'monthNamesShort' : [ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" ],
|
||||
'dayNames' : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
|
||||
'dayNamesShort' : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
|
||||
'today' : "today",
|
||||
'month' : "month",
|
||||
'week' : "week",
|
||||
'day' : "day",
|
||||
'allday' : "All day"
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<script src="http://osada.macgirvin.com/view/js/jquery.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/justifiedGallery/jquery.justifiedGallery.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/sprintf.js/dist/sprintf.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/textcomplete/textcomplete.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/view/js/autocomplete.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/jquery.timeago.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/readmore.js/readmore.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/sticky-kit/sticky-kit.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/jgrowl/jquery.jgrowl_minimized.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/view/js/acl.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/view/js/webtoolkit.base64.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/jRange/jquery.range.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/colorbox/jquery.colorbox-min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/jquery.AreYouSure/jquery.are-you-sure.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/tableofcontents/jquery.toc.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/imagesloaded/imagesloaded.pkgd.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/bootbox/bootbox.min.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/bootstrap-tagsinput/bootstrap-tagsinput.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/datetimepicker/jquery.datetimepicker.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/library/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js?v=2.3"></script>
|
||||
<script src="http://osada.macgirvin.com/view/theme/redbasic/js/redbasic.js?v=2.3"></script>
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
var updateInterval = 80000;
|
||||
var localUser = false;
|
||||
var zid = null;
|
||||
var justifiedGalleryActive = false;
|
||||
var preloadImages = 0;
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<script>$(document).ready(function() { $("#nav-search-text").search_autocomplete('https://osada.macgirvin.com/acl');});</script><script src="http://osada.macgirvin.com/view/js/main.js?v=2.3"></script>
|
||||
</head>
|
||||
<body>
|
||||
<header></header>
|
||||
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"><div class="project-banner" title="Powered by Osada"><a href="https://osada.macgirvin.com/">☸</a></div>
|
||||
<div class="d-lg-none pt-1 pb-1">
|
||||
<a class="btn btn-primary btn-sm text-white" href="#" title="Sign in" id="login_nav_btn_collapse" data-toggle="modal" data-target="#nav-login">
|
||||
Login
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-toggler-right">
|
||||
<button id="expand-aside" type="button" class="d-lg-none navbar-toggler border-0" data-toggle="offcanvas" data-target="#region_1">
|
||||
<i class="fa fa-arrow-circle-right" id="expand-aside-icon"></i>
|
||||
</button>
|
||||
<button id="menu-btn" class="navbar-toggler border-0" type="button" data-toggle="collapse" data-target="#navbar-collapse-2">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse-1">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item d-lg-flex">
|
||||
<a class="nav-link" href="#" title="Sign in" id="login_nav_btn" data-toggle="modal" data-target="#nav-login">
|
||||
Login
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div id="banner" class="navbar-text"></div>
|
||||
|
||||
<ul id="nav-right" class="navbar-nav ml-auto">
|
||||
<li class="nav-item collapse clearfix" id="nav-search">
|
||||
<form class="form-inline" method="get" action="search" role="search">
|
||||
<input class="form-control form-control-sm mt-1 mr-2" id="nav-search-text" type="text" value="" placeholder="@name, !forum, #tag, content" name="search" title="Search site @name, !forum, #tag, ?docs, content" onclick="this.submit();" onblur="closeMenu('nav-search'); openMenu('nav-search-btn');"/>
|
||||
</form>
|
||||
<div id="nav-search-spinner" class="spinner-wrapper">
|
||||
<div class="spinner s"></div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item" id="nav-search-btn">
|
||||
<a class="nav-link" href="#nav-search" title="Search site @name, !forum, #tag, ?docs, content" onclick="openMenu('nav-search'); closeMenu('nav-search-btn'); $('#nav-search-text').focus(); return false;"><i class="fa fa-fw fa-search"></i></a>
|
||||
</li>
|
||||
<li class="nav-item dropdown" id="app-menu">
|
||||
<a class="nav-link" href="#" data-toggle="dropdown"><i class="fa fa-fw fa-bars"></i></a>
|
||||
<div id="dropdown-menu" class="dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item" href="https://osada.macgirvin.com/directory"><i class="generic-icons-nav fa fa-fw fa-sitemap"></i>Directory</a>
|
||||
|
||||
|
||||
<a class="dropdown-item" href="https://osada.macgirvin.com/lang"><i class="generic-icons-nav fa fa-fw fa-language"></i>Language</a>
|
||||
|
||||
|
||||
<a class="dropdown-item" href="https://osada.macgirvin.com/search"><i class="generic-icons-nav fa fa-fw fa-search"></i>Search</a>
|
||||
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="collapse d-lg-none" id="navbar-collapse-2">
|
||||
<div class="navbar-nav mr-auto">
|
||||
<a class="nav-link" href="https://osada.macgirvin.com/directory"><i class="generic-icons-nav fa fa-fw fa-sitemap"></i>Directory</a>
|
||||
|
||||
|
||||
<a class="nav-link" href="https://osada.macgirvin.com/lang"><i class="generic-icons-nav fa fa-fw fa-language"></i>Language</a>
|
||||
|
||||
|
||||
<a class="nav-link" href="https://osada.macgirvin.com/search"><i class="generic-icons-nav fa fa-fw fa-search"></i>Search</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<main>
|
||||
<aside id="region_1"><div class="aside_spacer"><div id="left_aside_wrapper"></div></div></aside>
|
||||
<section id="region_2"><h1 class="home-welcome">Welcome to Osada</h1><form action="https://osada.macgirvin.com/" id="main-login" method="post">
|
||||
<input type="hidden" name="auth-params" value="login"/>
|
||||
<div id="login-main">
|
||||
<div id="login-input" class="form-group">
|
||||
<div id="id_username_wrapper" class="form-group">
|
||||
<label for="id_username" id="label_username">Login/Email</label>
|
||||
<input class="form-control" name="username" id="id_username" type="text" value="">
|
||||
<small id="help_username" class="form-text text-muted"></small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="id_password">Password</label>
|
||||
<input class="form-control" type="password" name="password" id="id_password" value=""> <small id="help_password" class="form-text text-muted"></small>
|
||||
</div>
|
||||
<div id="remember_container" class="clearfix form-group checkbox">
|
||||
<label for="id_remember">Remember me</label>
|
||||
<div class="float-right"><input type="checkbox" name="remember" id="id_remember" value="1"/><label class="switchlabel" for="id_remember"> <span class="onoffswitch-inner" data-on="Yes" data-off="No"></span><span class="onoffswitch-switch"></span></label></div>
|
||||
<small class="form-text text-muted"></small>
|
||||
</div>
|
||||
<button type="submit" name="submit" class="btn btn-block btn-primary">Login</button>
|
||||
</div>
|
||||
<div id="login-extra-links">
|
||||
<a href="https://osada.macgirvin.com/pubsites" title="Create an account to access services and applications" id="register-link" class="pull-right">Register</a> <a href="lostpass" title="Forgot your password?" id="lost-password-link">Password Reset</a>
|
||||
</div>
|
||||
<hr>
|
||||
<a href="rmagic" class="btn btn-block btn-outline-success rmagic-button">Remote Authentication</a>
|
||||
</div>
|
||||
<input type="hidden" name="0" value=""/>
|
||||
</form>
|
||||
<script type="text/javascript"> $(document).ready(function() { $("#id_username").focus();} );</script>
|
||||
<div id="nav-login" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Login</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<form action="https://osada.macgirvin.com/" id="main-login" method="post">
|
||||
<input type="hidden" name="auth-params" value="login"/>
|
||||
<div id="login-main">
|
||||
<div id="login-input" class="form-group">
|
||||
<div id="id_username_wrapper" class="form-group">
|
||||
<label for="id_username" id="label_username">Login/Email</label>
|
||||
<input class="form-control" name="username" id="id_username" type="text" value="">
|
||||
<small id="help_username" class="form-text text-muted"></small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="id_password">Password</label>
|
||||
<input class="form-control" type="password" name="password" id="id_password" value=""> <small id="help_password" class="form-text text-muted"></small>
|
||||
</div>
|
||||
<div id="remember_me_container" class="clearfix form-group checkbox">
|
||||
<label for="id_remember_me">Remember me</label>
|
||||
<div class="float-right"><input type="checkbox" name="remember_me" id="id_remember_me" value="1"/><label class="switchlabel" for="id_remember_me"> <span class="onoffswitch-inner" data-on="Yes" data-off="No"></span><span class="onoffswitch-switch"></span></label></div>
|
||||
<small class="form-text text-muted"></small>
|
||||
</div>
|
||||
<button type="submit" name="submit" class="btn btn-block btn-primary">Login</button>
|
||||
</div>
|
||||
<div id="login-extra-links">
|
||||
<a href="https://osada.macgirvin.com/pubsites" title="Create an account to access services and applications" id="register-link" class="pull-right">Register</a> <a href="lostpass" title="Forgot your password?" id="lost-password-link">Password Reset</a>
|
||||
</div>
|
||||
<hr>
|
||||
<a href="rmagic" class="btn btn-block btn-outline-success rmagic-button">Remote Authentication</a>
|
||||
</div>
|
||||
<input type="hidden" name="0" value=""/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page-footer"></div>
|
||||
<div id="pause"></div>
|
||||
</section>
|
||||
<aside id="region_3" class="d-none d-xl-table-cell"><div class="aside_spacer"><div id="right_aside_wrapper"></div></div></aside>
|
||||
</main>
|
||||
<footer></footer>
|
||||
</body>
|
||||
</html>
|
||||
<!--
|
||||
FILE ARCHIVED ON 11:49:38 Jan 26, 2019 AND RETRIEVED FROM THE
|
||||
INTERNET ARCHIVE ON 04:27:56 Mar 02, 2020.
|
||||
|
||||
CONTENT MAY BE PROTECTED BY COPYRIGHT (17 U.S.C. SECTION 108(a)(3)).
|
||||
-->
|
||||
<!--
|
||||
playback timings (ms):
|
||||
exclusion.robots: 0.217
|
||||
CDXLines.iter: 14.7 (3)
|
||||
LoadShardBlock: 165.298 (3)
|
||||
esindex: 0.01
|
||||
PetaboxLoader3.datanode: 72.599 (4)
|
||||
exclusion.robots.policy: 0.208
|
||||
RedisCDXSource: 16.804
|
||||
PetaboxLoader3.resolve: 146.316 (4)
|
||||
captures_list: 199.59
|
||||
load_resource: 56.473
|
||||
-->
|
||||
101
test/gun/conneciton_pool_test.exs
Normal file
101
test/gun/conneciton_pool_test.exs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Gun.ConnectionPoolTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Mox
|
||||
import ExUnit.CaptureLog
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Gun.ConnectionPool
|
||||
|
||||
defp gun_mock(_) do
|
||||
Pleroma.GunMock
|
||||
|> stub(:open, fn _, _, _ -> Task.start_link(fn -> Process.sleep(100) end) end)
|
||||
|> stub(:await_up, fn _, _ -> {:ok, :http} end)
|
||||
|> stub(:set_owner, fn _, _ -> :ok end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
setup :set_mox_from_context
|
||||
setup :gun_mock
|
||||
|
||||
test "gives the same connection to 2 concurrent requests" do
|
||||
Enum.map(
|
||||
[
|
||||
"http://www.korean-books.com.kp/KBMbooks/en/periodic/pictorial/20200530163914.pdf",
|
||||
"http://www.korean-books.com.kp/KBMbooks/en/periodic/pictorial/20200528183427.pdf"
|
||||
],
|
||||
fn uri ->
|
||||
uri = URI.parse(uri)
|
||||
task_parent = self()
|
||||
|
||||
Task.start_link(fn ->
|
||||
{:ok, conn} = ConnectionPool.get_conn(uri, [])
|
||||
ConnectionPool.release_conn(conn)
|
||||
send(task_parent, conn)
|
||||
end)
|
||||
end
|
||||
)
|
||||
|
||||
[pid, pid] =
|
||||
for _ <- 1..2 do
|
||||
receive do
|
||||
pid -> pid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "connection limit is respected with concurrent requests" do
|
||||
clear_config([:connections_pool, :max_connections]) do
|
||||
Config.put([:connections_pool, :max_connections], 1)
|
||||
# The supervisor needs a reboot to apply the new config setting
|
||||
Process.exit(Process.whereis(Pleroma.Gun.ConnectionPool.WorkerSupervisor), :kill)
|
||||
|
||||
on_exit(fn ->
|
||||
Process.exit(Process.whereis(Pleroma.Gun.ConnectionPool.WorkerSupervisor), :kill)
|
||||
end)
|
||||
end
|
||||
|
||||
capture_log(fn ->
|
||||
Enum.map(
|
||||
[
|
||||
"https://ninenines.eu/",
|
||||
"https://youtu.be/PFGwMiDJKNY"
|
||||
],
|
||||
fn uri ->
|
||||
uri = URI.parse(uri)
|
||||
task_parent = self()
|
||||
|
||||
Task.start_link(fn ->
|
||||
result = ConnectionPool.get_conn(uri, [])
|
||||
# Sleep so that we don't end up with a situation,
|
||||
# where request from the second process gets processed
|
||||
# only after the first process already released the connection
|
||||
Process.sleep(50)
|
||||
|
||||
case result do
|
||||
{:ok, pid} ->
|
||||
ConnectionPool.release_conn(pid)
|
||||
|
||||
_ ->
|
||||
nil
|
||||
end
|
||||
|
||||
send(task_parent, result)
|
||||
end)
|
||||
end
|
||||
)
|
||||
|
||||
[{:error, :pool_full}, {:ok, _pid}] =
|
||||
for _ <- 1..2 do
|
||||
receive do
|
||||
result -> result
|
||||
end
|
||||
end
|
||||
|> Enum.sort()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
@ -9,24 +9,10 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
import Mox
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Gun.Conn
|
||||
alias Pleroma.HTTP.AdapterHelper.Gun
|
||||
alias Pleroma.Pool.Connections
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
defp gun_mock(_) do
|
||||
gun_mock()
|
||||
:ok
|
||||
end
|
||||
|
||||
defp gun_mock do
|
||||
Pleroma.GunMock
|
||||
|> stub(:open, fn _, _, _ -> Task.start_link(fn -> Process.sleep(1000) end) end)
|
||||
|> stub(:await_up, fn _, _ -> {:ok, :http} end)
|
||||
|> stub(:set_owner, fn _, _ -> :ok end)
|
||||
end
|
||||
|
||||
describe "options/1" do
|
||||
setup do: clear_config([:http, :adapter], a: 1, b: 2)
|
||||
|
||||
|
|
@ -35,7 +21,6 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https ipv4 with default port" do
|
||||
|
|
@ -43,7 +28,6 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https ipv6 with default port" do
|
||||
|
|
@ -51,7 +35,6 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https url with non standart port" do
|
||||
|
|
@ -62,46 +45,12 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
assert opts[:certificates_verification]
|
||||
end
|
||||
|
||||
test "get conn on next request" do
|
||||
gun_mock()
|
||||
level = Application.get_env(:logger, :level)
|
||||
Logger.configure(level: :debug)
|
||||
on_exit(fn -> Logger.configure(level: level) end)
|
||||
uri = URI.parse("http://some-domain2.com")
|
||||
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert opts[:conn] == nil
|
||||
assert opts[:close_conn] == nil
|
||||
|
||||
Process.sleep(50)
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert is_pid(opts[:conn])
|
||||
assert opts[:close_conn] == false
|
||||
end
|
||||
|
||||
test "merges with defaul http adapter config" do
|
||||
defaults = Gun.options([receive_conn: false], URI.parse("https://example.com"))
|
||||
assert Keyword.has_key?(defaults, :a)
|
||||
assert Keyword.has_key?(defaults, :b)
|
||||
end
|
||||
|
||||
test "default ssl adapter opts with connection" do
|
||||
gun_mock()
|
||||
uri = URI.parse("https://some-domain.com")
|
||||
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert opts[:certificates_verification]
|
||||
refute opts[:tls_opts] == []
|
||||
|
||||
assert opts[:close_conn] == false
|
||||
assert is_pid(opts[:conn])
|
||||
end
|
||||
|
||||
test "parses string proxy host & port" do
|
||||
proxy = Config.get([:http, :proxy_url])
|
||||
Config.put([:http, :proxy_url], "localhost:8123")
|
||||
|
|
@ -132,127 +81,4 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
|||
assert opts[:proxy] == {'example.com', 4321}
|
||||
end
|
||||
end
|
||||
|
||||
describe "options/1 with receive_conn parameter" do
|
||||
setup :gun_mock
|
||||
|
||||
test "receive conn by default" do
|
||||
uri = URI.parse("http://another-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
received_opts = Gun.options(uri)
|
||||
assert received_opts[:close_conn] == false
|
||||
assert is_pid(received_opts[:conn])
|
||||
end
|
||||
|
||||
test "don't receive conn if receive_conn is false" do
|
||||
uri = URI.parse("http://another-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = [receive_conn: false]
|
||||
received_opts = Gun.options(opts, uri)
|
||||
assert received_opts[:close_conn] == nil
|
||||
assert received_opts[:conn] == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "after_request/1" do
|
||||
setup :gun_mock
|
||||
|
||||
test "body_as not chunks" do
|
||||
uri = URI.parse("http://some-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "body_as chunks" do
|
||||
uri = URI.parse("http://some-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options([body_as: :chunks], uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
self = self()
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with no connection" do
|
||||
uri = URI.parse("http://uniq-domain.com")
|
||||
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = Gun.options([body_as: :chunks], uri)
|
||||
conn = opts[:conn]
|
||||
opts = Keyword.delete(opts, :conn)
|
||||
self = self()
|
||||
|
||||
:ok = Gun.after_request(opts)
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:uniq-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with ipv4" do
|
||||
uri = URI.parse("http://127.0.0.1")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with ipv6" do
|
||||
uri = URI.parse("http://[2a03:2880:f10c:83:face:b00c:0:25de]")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,135 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.ConnectionTest do
|
||||
use ExUnit.Case
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTTP.Connection
|
||||
|
||||
describe "parse_host/1" do
|
||||
test "as atom to charlist" do
|
||||
assert Connection.parse_host(:localhost) == 'localhost'
|
||||
end
|
||||
|
||||
test "as string to charlist" do
|
||||
assert Connection.parse_host("localhost.com") == 'localhost.com'
|
||||
end
|
||||
|
||||
test "as string ip to tuple" do
|
||||
assert Connection.parse_host("127.0.0.1") == {127, 0, 0, 1}
|
||||
end
|
||||
end
|
||||
|
||||
describe "parse_proxy/1" do
|
||||
test "ip with port" do
|
||||
assert Connection.parse_proxy("127.0.0.1:8123") == {:ok, {127, 0, 0, 1}, 8123}
|
||||
end
|
||||
|
||||
test "host with port" do
|
||||
assert Connection.parse_proxy("localhost:8123") == {:ok, 'localhost', 8123}
|
||||
end
|
||||
|
||||
test "as tuple" do
|
||||
assert Connection.parse_proxy({:socks4, :localhost, 9050}) ==
|
||||
{:ok, :socks4, 'localhost', 9050}
|
||||
end
|
||||
|
||||
test "as tuple with string host" do
|
||||
assert Connection.parse_proxy({:socks5, "localhost", 9050}) ==
|
||||
{:ok, :socks5, 'localhost', 9050}
|
||||
end
|
||||
end
|
||||
|
||||
describe "parse_proxy/1 errors" do
|
||||
test "ip without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("127.0.0.1") == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail \"127.0.0.1\""
|
||||
end
|
||||
|
||||
test "host without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("localhost") == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail \"localhost\""
|
||||
end
|
||||
|
||||
test "host with bad port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("localhost:port") == {:error, :invalid_proxy_port}
|
||||
end) =~ "parsing port in proxy fail \"localhost:port\""
|
||||
end
|
||||
|
||||
test "ip with bad port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("127.0.0.1:15.9") == {:error, :invalid_proxy_port}
|
||||
end) =~ "parsing port in proxy fail \"127.0.0.1:15.9\""
|
||||
end
|
||||
|
||||
test "as tuple without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy({:socks5, :localhost}) == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail {:socks5, :localhost}"
|
||||
end
|
||||
|
||||
test "with nil" do
|
||||
assert Connection.parse_proxy(nil) == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "options/3" do
|
||||
setup do: clear_config([:http, :proxy_url])
|
||||
|
||||
test "without proxy_url in config" do
|
||||
Config.delete([:http, :proxy_url])
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
refute Keyword.has_key?(opts, :proxy)
|
||||
end
|
||||
|
||||
test "parses string proxy host & port" do
|
||||
Config.put([:http, :proxy_url], "localhost:8123")
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
assert opts[:proxy] == {'localhost', 8123}
|
||||
end
|
||||
|
||||
test "parses tuple proxy scheme host and port" do
|
||||
Config.put([:http, :proxy_url], {:socks, 'localhost', 1234})
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
assert opts[:proxy] == {:socks, 'localhost', 1234}
|
||||
end
|
||||
|
||||
test "passed opts have more weight than defaults" do
|
||||
Config.put([:http, :proxy_url], {:socks5, 'localhost', 1234})
|
||||
|
||||
opts = Connection.options(%URI{}, proxy: {'example.com', 4321})
|
||||
|
||||
assert opts[:proxy] == {'example.com', 4321}
|
||||
end
|
||||
end
|
||||
|
||||
describe "format_host/1" do
|
||||
test "with domain" do
|
||||
assert Connection.format_host("example.com") == 'example.com'
|
||||
end
|
||||
|
||||
test "with idna domain" do
|
||||
assert Connection.format_host("ですexample.com") == 'xn--example-183fne.com'
|
||||
end
|
||||
|
||||
test "with ipv4" do
|
||||
assert Connection.format_host("127.0.0.1") == '127.0.0.1'
|
||||
end
|
||||
|
||||
test "with ipv6" do
|
||||
assert Connection.format_host("2a03:2880:f10c:83:face:b00c:0:25de") ==
|
||||
'2a03:2880:f10c:83:face:b00c:0:25de'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -246,49 +246,18 @@ defmodule Pleroma.NotificationTest do
|
|||
assert Notification.create_notification(activity, muter)
|
||||
end
|
||||
|
||||
test "it disables notifications from followers" do
|
||||
follower = insert(:user)
|
||||
|
||||
followed =
|
||||
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
|
||||
|
||||
User.follow(follower, followed)
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from non-followers" do
|
||||
test "it disables notifications from strangers" do
|
||||
follower = insert(:user)
|
||||
|
||||
followed =
|
||||
insert(:user,
|
||||
notification_settings: %Pleroma.User.NotificationSetting{non_followers: false}
|
||||
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
|
||||
)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from people the user follows" do
|
||||
follower =
|
||||
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{follows: false})
|
||||
|
||||
followed = insert(:user)
|
||||
User.follow(follower, followed)
|
||||
follower = Repo.get(User, follower.id)
|
||||
{:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
|
||||
refute Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
test "it disables notifications from people the user does not follow" do
|
||||
follower =
|
||||
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{non_follows: false})
|
||||
|
||||
followed = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
|
||||
refute Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for user if he is the activity author" do
|
||||
activity = insert(:note_activity)
|
||||
author = User.get_cached_by_ap_id(activity.data["actor"])
|
||||
|
|
@ -324,6 +293,44 @@ defmodule Pleroma.NotificationTest do
|
|||
{:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
|
||||
refute Notification.create_notification(status, user)
|
||||
end
|
||||
|
||||
test "it doesn't create notifications if content matches with an irreversible filter" do
|
||||
user = insert(:user)
|
||||
subscriber = insert(:user)
|
||||
|
||||
User.subscribe(subscriber, user)
|
||||
insert(:filter, user: subscriber, phrase: "cofe", hide: true)
|
||||
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "got cofe?"})
|
||||
|
||||
assert {:ok, []} == Notification.create_notifications(status)
|
||||
end
|
||||
|
||||
test "it creates notifications if content matches with a not irreversible filter" do
|
||||
user = insert(:user)
|
||||
subscriber = insert(:user)
|
||||
|
||||
User.subscribe(subscriber, user)
|
||||
insert(:filter, user: subscriber, phrase: "cofe", hide: false)
|
||||
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "got cofe?"})
|
||||
{:ok, [notification]} = Notification.create_notifications(status)
|
||||
|
||||
assert notification
|
||||
end
|
||||
|
||||
test "it creates notifications when someone likes user's status with a filtered word" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
insert(:filter, user: user, phrase: "tesla", hide: true)
|
||||
|
||||
{:ok, activity_one} = CommonAPI.post(user, %{status: "wow tesla"})
|
||||
{:ok, activity_two} = CommonAPI.favorite(other_user, activity_one.id)
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity_two)
|
||||
|
||||
assert notification
|
||||
end
|
||||
end
|
||||
|
||||
describe "follow / follow_request notifications" do
|
||||
|
|
@ -990,8 +997,13 @@ defmodule Pleroma.NotificationTest do
|
|||
end
|
||||
|
||||
describe "for_user" do
|
||||
test "it returns notifications for muted user without notifications" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, %{user: user}}
|
||||
end
|
||||
|
||||
test "it returns notifications for muted user without notifications", %{user: user} do
|
||||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted, false)
|
||||
|
||||
|
|
@ -1002,8 +1014,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert notification.activity.object
|
||||
end
|
||||
|
||||
test "it doesn't return notifications for muted user with notifications" do
|
||||
user = insert(:user)
|
||||
test "it doesn't return notifications for muted user with notifications", %{user: user} do
|
||||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted)
|
||||
|
||||
|
|
@ -1012,8 +1023,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
||||
test "it doesn't return notifications for blocked user" do
|
||||
user = insert(:user)
|
||||
test "it doesn't return notifications for blocked user", %{user: user} do
|
||||
blocked = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(user, blocked)
|
||||
|
||||
|
|
@ -1022,8 +1032,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
||||
test "it doesn't return notifications for domain-blocked non-followed user" do
|
||||
user = insert(:user)
|
||||
test "it doesn't return notifications for domain-blocked non-followed user", %{user: user} do
|
||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
||||
|
||||
|
|
@ -1044,8 +1053,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
||||
test "it doesn't return notifications for muted thread" do
|
||||
user = insert(:user)
|
||||
test "it doesn't return notifications for muted thread", %{user: user} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
|
||||
|
|
@ -1054,8 +1062,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
||||
test "it returns notifications from a muted user when with_muted is set" do
|
||||
user = insert(:user)
|
||||
test "it returns notifications from a muted user when with_muted is set", %{user: user} do
|
||||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted)
|
||||
|
||||
|
|
@ -1064,8 +1071,9 @@ defmodule Pleroma.NotificationTest do
|
|||
assert length(Notification.for_user(user, %{with_muted: true})) == 1
|
||||
end
|
||||
|
||||
test "it doesn't return notifications from a blocked user when with_muted is set" do
|
||||
user = insert(:user)
|
||||
test "it doesn't return notifications from a blocked user when with_muted is set", %{
|
||||
user: user
|
||||
} do
|
||||
blocked = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(user, blocked)
|
||||
|
||||
|
|
@ -1075,8 +1083,8 @@ defmodule Pleroma.NotificationTest do
|
|||
end
|
||||
|
||||
test "when with_muted is set, " <>
|
||||
"it doesn't return notifications from a domain-blocked non-followed user" do
|
||||
user = insert(:user)
|
||||
"it doesn't return notifications from a domain-blocked non-followed user",
|
||||
%{user: user} do
|
||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
||||
|
||||
|
|
@ -1085,8 +1093,7 @@ defmodule Pleroma.NotificationTest do
|
|||
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
|
||||
end
|
||||
|
||||
test "it returns notifications from muted threads when with_muted is set" do
|
||||
user = insert(:user)
|
||||
test "it returns notifications from muted threads when with_muted is set", %{user: user} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
|
||||
|
|
@ -1094,5 +1101,33 @@ defmodule Pleroma.NotificationTest do
|
|||
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
|
||||
assert length(Notification.for_user(user, %{with_muted: true})) == 1
|
||||
end
|
||||
|
||||
test "it doesn't return notifications about mentions with filtered word", %{user: user} do
|
||||
insert(:filter, user: user, phrase: "cofe", hide: true)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(another_user, %{status: "@#{user.nickname} got cofe?"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
end
|
||||
|
||||
test "it returns notifications about mentions with not hidden filtered word", %{user: user} do
|
||||
insert(:filter, user: user, phrase: "test", hide: false)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "@#{user.nickname} test"})
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
||||
test "it returns notifications about favorites with filtered word", %{user: user} do
|
||||
insert(:filter, user: user, phrase: "cofe", hide: true)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "Give me my cofe!"})
|
||||
{:ok, _} = CommonAPI.favorite(another_user, activity.id)
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -54,6 +54,20 @@ defmodule Pleroma.PaginationTest do
|
|||
|
||||
assert length(paginated) == 1
|
||||
end
|
||||
|
||||
test "handles id gracefully", %{notes: notes} do
|
||||
id = Enum.at(notes, 1).id |> Integer.to_string()
|
||||
|
||||
paginated =
|
||||
Pagination.fetch_paginated(Object, %{
|
||||
id: "9s99Hq44Cnv8PKBwWG",
|
||||
max_id: id,
|
||||
limit: 20,
|
||||
offset: 0
|
||||
})
|
||||
|
||||
assert length(paginated) == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "offset" do
|
||||
|
|
|
|||
|
|
@ -4,9 +4,14 @@
|
|||
|
||||
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Plugs.AdminSecretAuthenticationPlug
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Plugs.PlugHelper
|
||||
alias Pleroma.Plugs.RateLimiter
|
||||
|
||||
test "does nothing if a user is assigned", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
|
@ -25,6 +30,10 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
|||
describe "when secret set it assigns an admin user" do
|
||||
setup do: clear_config([:admin_token])
|
||||
|
||||
setup_with_mocks([{RateLimiter, [:passthrough], []}]) do
|
||||
:ok
|
||||
end
|
||||
|
||||
test "with `admin_token` query parameter", %{conn: conn} do
|
||||
Pleroma.Config.put(:admin_token, "password123")
|
||||
|
||||
|
|
@ -33,12 +42,14 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
|||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
refute conn.assigns[:user]
|
||||
assert called(RateLimiter.call(conn, name: :authentication))
|
||||
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "password123"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:user].is_admin
|
||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
|
||||
end
|
||||
|
||||
test "with `x-admin-token` HTTP header", %{conn: conn} do
|
||||
|
|
@ -50,6 +61,7 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
|||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
refute conn.assigns[:user]
|
||||
assert called(RateLimiter.call(conn, name: :authentication))
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -57,6 +69,7 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
|||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:user].is_admin
|
||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,17 +4,12 @@
|
|||
|
||||
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Plug.Conn
|
||||
|
||||
setup do: clear_config([:http_securiy, :enabled])
|
||||
setup do: clear_config([:http_security, :sts])
|
||||
setup do: clear_config([:http_security, :referrer_policy])
|
||||
|
||||
describe "http security enabled" do
|
||||
setup do
|
||||
Config.put([:http_security, :enabled], true)
|
||||
end
|
||||
setup do: clear_config([:http_security, :enabled], true)
|
||||
|
||||
test "it sends CSP headers when enabled", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
|
@ -29,7 +24,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
end
|
||||
|
||||
test "it sends STS headers when enabled", %{conn: conn} do
|
||||
Config.put([:http_security, :sts], true)
|
||||
clear_config([:http_security, :sts], true)
|
||||
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
||||
|
|
@ -38,7 +33,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
end
|
||||
|
||||
test "it does not send STS headers when disabled", %{conn: conn} do
|
||||
Config.put([:http_security, :sts], false)
|
||||
clear_config([:http_security, :sts], false)
|
||||
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
||||
|
|
@ -47,23 +42,19 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
end
|
||||
|
||||
test "referrer-policy header reflects configured value", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
resp = get(conn, "/api/v1/instance")
|
||||
|
||||
assert Conn.get_resp_header(conn, "referrer-policy") == ["same-origin"]
|
||||
assert Conn.get_resp_header(resp, "referrer-policy") == ["same-origin"]
|
||||
|
||||
Config.put([:http_security, :referrer_policy], "no-referrer")
|
||||
clear_config([:http_security, :referrer_policy], "no-referrer")
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> get("/api/v1/instance")
|
||||
resp = get(conn, "/api/v1/instance")
|
||||
|
||||
assert Conn.get_resp_header(conn, "referrer-policy") == ["no-referrer"]
|
||||
assert Conn.get_resp_header(resp, "referrer-policy") == ["no-referrer"]
|
||||
end
|
||||
|
||||
test "it sends `report-to` & `report-uri` CSP response headers" do
|
||||
conn =
|
||||
build_conn()
|
||||
|> get("/api/v1/instance")
|
||||
test "it sends `report-to` & `report-uri` CSP response headers", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
||||
[csp] = Conn.get_resp_header(conn, "content-security-policy")
|
||||
|
||||
|
|
@ -74,10 +65,67 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
assert reply_to ==
|
||||
"{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}"
|
||||
end
|
||||
|
||||
test "default values for img-src and media-src with disabled media proxy", %{conn: conn} do
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
||||
[csp] = Conn.get_resp_header(conn, "content-security-policy")
|
||||
assert csp =~ "media-src 'self' https:;"
|
||||
assert csp =~ "img-src 'self' data: blob: https:;"
|
||||
end
|
||||
end
|
||||
|
||||
describe "img-src and media-src" do
|
||||
setup do
|
||||
clear_config([:http_security, :enabled], true)
|
||||
clear_config([:media_proxy, :enabled], true)
|
||||
clear_config([:media_proxy, :proxy_opts, :redirect_on_failure], false)
|
||||
end
|
||||
|
||||
test "media_proxy with base_url", %{conn: conn} do
|
||||
url = "https://example.com"
|
||||
clear_config([:media_proxy, :base_url], url)
|
||||
assert_media_img_src(conn, url)
|
||||
end
|
||||
|
||||
test "upload with base url", %{conn: conn} do
|
||||
url = "https://example2.com"
|
||||
clear_config([Pleroma.Upload, :base_url], url)
|
||||
assert_media_img_src(conn, url)
|
||||
end
|
||||
|
||||
test "with S3 public endpoint", %{conn: conn} do
|
||||
url = "https://example3.com"
|
||||
clear_config([Pleroma.Uploaders.S3, :public_endpoint], url)
|
||||
assert_media_img_src(conn, url)
|
||||
end
|
||||
|
||||
test "with captcha endpoint", %{conn: conn} do
|
||||
clear_config([Pleroma.Captcha.Mock, :endpoint], "https://captcha.com")
|
||||
assert_media_img_src(conn, "https://captcha.com")
|
||||
end
|
||||
|
||||
test "with media_proxy whitelist", %{conn: conn} do
|
||||
clear_config([:media_proxy, :whitelist], ["https://example6.com", "https://example7.com"])
|
||||
assert_media_img_src(conn, "https://example7.com https://example6.com")
|
||||
end
|
||||
|
||||
# TODO: delete after removing support bare domains for media proxy whitelist
|
||||
test "with media_proxy bare domains whitelist (deprecated)", %{conn: conn} do
|
||||
clear_config([:media_proxy, :whitelist], ["example4.com", "example5.com"])
|
||||
assert_media_img_src(conn, "example5.com example4.com")
|
||||
end
|
||||
end
|
||||
|
||||
defp assert_media_img_src(conn, url) do
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
[csp] = Conn.get_resp_header(conn, "content-security-policy")
|
||||
assert csp =~ "media-src 'self' #{url};"
|
||||
assert csp =~ "img-src 'self' data: blob: #{url};"
|
||||
end
|
||||
|
||||
test "it does not send CSP headers when disabled", %{conn: conn} do
|
||||
Config.put([:http_security, :enabled], false)
|
||||
clear_config([:http_security, :enabled], false)
|
||||
|
||||
conn = get(conn, "/api/v1/instance")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,112 +8,30 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
|
|||
alias Pleroma.Plugs.UserIsAdminPlug
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false)
|
||||
test "accepts a user that is an admin" do
|
||||
user = insert(:user, is_admin: true)
|
||||
|
||||
test "accepts a user that is an admin" do
|
||||
user = insert(:user, is_admin: true)
|
||||
conn = assign(build_conn(), :user, user)
|
||||
|
||||
conn = assign(build_conn(), :user, user)
|
||||
ret_conn = UserIsAdminPlug.call(conn, %{})
|
||||
|
||||
ret_conn = UserIsAdminPlug.call(conn, %{})
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "denies a user that isn't an admin" do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "denies when a user isn't set" do
|
||||
conn = UserIsAdminPlug.call(build_conn(), %{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
||||
test "denies a user that isn't an admin" do
|
||||
user = insert(:user)
|
||||
|
||||
setup do
|
||||
admin_user = insert(:user, is_admin: true)
|
||||
non_admin_user = insert(:user, is_admin: false)
|
||||
blank_user = nil
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
{:ok, %{users: [admin_user, non_admin_user, blank_user]}}
|
||||
end
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "if token has any of admin scopes, accepts a user that is an admin", %{conn: conn} do
|
||||
user = insert(:user, is_admin: true)
|
||||
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
|
||||
test "denies when a user isn't set" do
|
||||
conn = UserIsAdminPlug.call(build_conn(), %{})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|
||||
ret_conn = UserIsAdminPlug.call(conn, %{})
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "if token has any of admin scopes, denies a user that isn't an admin", %{conn: conn} do
|
||||
user = insert(:user, is_admin: false)
|
||||
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "if token has any of admin scopes, denies when a user isn't set", %{conn: conn} do
|
||||
token = insert(:oauth_token, scopes: ["admin:something"])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, nil)
|
||||
|> assign(:token, token)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
|
||||
test "if token lacks admin scopes, denies users regardless of is_admin flag",
|
||||
%{users: users} do
|
||||
for user <- users do
|
||||
token = insert(:oauth_token, user: user)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
end
|
||||
|
||||
test "if token is missing, denies users regardless of is_admin flag", %{users: users} do
|
||||
for user <- users do
|
||||
conn =
|
||||
build_conn()
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, nil)
|
||||
|> UserIsAdminPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
end
|
||||
end
|
||||
assert conn.status == 403
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,760 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Pool.ConnectionsTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Gun.Conn
|
||||
alias Pleroma.GunMock
|
||||
alias Pleroma.Pool.Connections
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
setup_all do
|
||||
name = :test_connections
|
||||
{:ok, pid} = Connections.start_link({name, [checkin_timeout: 150]})
|
||||
{:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.GunMock)
|
||||
|
||||
on_exit(fn ->
|
||||
if Process.alive?(pid), do: GenServer.stop(name)
|
||||
end)
|
||||
|
||||
{:ok, name: name}
|
||||
end
|
||||
|
||||
defp open_mock(num \\ 1) do
|
||||
GunMock
|
||||
|> expect(:open, num, &start_and_register(&1, &2, &3))
|
||||
|> expect(:await_up, num, fn _, _ -> {:ok, :http} end)
|
||||
|> expect(:set_owner, num, fn _, _ -> :ok end)
|
||||
end
|
||||
|
||||
defp connect_mock(mock) do
|
||||
mock
|
||||
|> expect(:connect, &connect(&1, &2))
|
||||
|> expect(:await, &await(&1, &2))
|
||||
end
|
||||
|
||||
defp info_mock(mock), do: expect(mock, :info, &info(&1))
|
||||
|
||||
defp start_and_register('gun-not-up.com', _, _), do: {:error, :timeout}
|
||||
|
||||
defp start_and_register(host, port, _) do
|
||||
{:ok, pid} = Task.start_link(fn -> Process.sleep(1000) end)
|
||||
|
||||
scheme =
|
||||
case port do
|
||||
443 -> "https"
|
||||
_ -> "http"
|
||||
end
|
||||
|
||||
Registry.register(GunMock, pid, %{
|
||||
origin_scheme: scheme,
|
||||
origin_host: host,
|
||||
origin_port: port
|
||||
})
|
||||
|
||||
{:ok, pid}
|
||||
end
|
||||
|
||||
defp info(pid) do
|
||||
[{_, info}] = Registry.lookup(GunMock, pid)
|
||||
info
|
||||
end
|
||||
|
||||
defp connect(pid, _) do
|
||||
ref = make_ref()
|
||||
Registry.register(GunMock, ref, pid)
|
||||
ref
|
||||
end
|
||||
|
||||
defp await(pid, ref) do
|
||||
[{_, ^pid}] = Registry.lookup(GunMock, ref)
|
||||
{:response, :fin, 200, []}
|
||||
end
|
||||
|
||||
defp now, do: :os.system_time(:second)
|
||||
|
||||
describe "alive?/2" do
|
||||
test "is alive", %{name: name} do
|
||||
assert Connections.alive?(name)
|
||||
end
|
||||
|
||||
test "returns false if not started" do
|
||||
refute Connections.alive?(:some_random_name)
|
||||
end
|
||||
end
|
||||
|
||||
test "opens connection and reuse it on next request", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://some-domain.com"
|
||||
key = "http:some-domain.com:80"
|
||||
refute Connections.checkin(url, name)
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}, {^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [],
|
||||
conn_state: :idle
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuse connection for idna domains", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://ですsome-domain.com"
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:ですsome-domain.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
end
|
||||
|
||||
test "reuse for ipv4", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://127.0.0.1"
|
||||
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
:ok = Connections.checkout(reused_conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [],
|
||||
conn_state: :idle
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuse for ipv6", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://[2a03:2880:f10c:83:face:b00c:0:25de]"
|
||||
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
end
|
||||
|
||||
test "up and down ipv4", %{name: name} do
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self(), name)
|
||||
|
||||
self = self()
|
||||
url = "http://127.0.0.1"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
send(name, {:gun_down, conn, nil, nil, nil})
|
||||
send(name, {:gun_up, conn, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "up and down ipv6", %{name: name} do
|
||||
self = self()
|
||||
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self, name)
|
||||
|
||||
url = "http://[2a03:2880:f10c:83:face:b00c:0:25de]"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
send(name, {:gun_down, conn, nil, nil, nil})
|
||||
send(name, {:gun_up, conn, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuses connection based on protocol", %{name: name} do
|
||||
open_mock(2)
|
||||
http_url = "http://some-domain.com"
|
||||
http_key = "http:some-domain.com:80"
|
||||
https_url = "https://some-domain.com"
|
||||
https_key = "https:some-domain.com:443"
|
||||
|
||||
refute Connections.checkin(http_url, name)
|
||||
:ok = Conn.open(http_url, name)
|
||||
conn = Connections.checkin(http_url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
refute Connections.checkin(https_url, name)
|
||||
:ok = Conn.open(https_url, name)
|
||||
https_conn = Connections.checkin(https_url, name)
|
||||
|
||||
refute conn == https_conn
|
||||
|
||||
reused_https = Connections.checkin(https_url, name)
|
||||
|
||||
refute conn == reused_https
|
||||
|
||||
assert reused_https == https_conn
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^http_key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
},
|
||||
^https_key => %Conn{
|
||||
conn: ^https_conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "connection can't get up", %{name: name} do
|
||||
expect(GunMock, :open, &start_and_register(&1, &2, &3))
|
||||
url = "http://gun-not-up.com"
|
||||
|
||||
assert capture_log(fn ->
|
||||
refute Conn.open(url, name)
|
||||
refute Connections.checkin(url, name)
|
||||
end) =~
|
||||
"Opening connection to http://gun-not-up.com failed with error {:error, :timeout}"
|
||||
end
|
||||
|
||||
test "process gun_down message and then gun_up", %{name: name} do
|
||||
self = self()
|
||||
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self, name)
|
||||
|
||||
url = "http://gun-down-and-up.com"
|
||||
key = "http:gun-down-and-up.com:80"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
send(name, {:gun_down, conn, :http, nil, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :down,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
send(name, {:gun_up, conn, :http})
|
||||
|
||||
conn2 = Connections.checkin(url, name)
|
||||
assert conn == conn2
|
||||
|
||||
assert is_pid(conn2)
|
||||
assert Process.alive?(conn2)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: _,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}, {^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "async processes get same conn for same domain", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://some-domain.com"
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
tasks =
|
||||
for _ <- 1..5 do
|
||||
Task.async(fn ->
|
||||
Connections.checkin(url, name)
|
||||
end)
|
||||
end
|
||||
|
||||
tasks_with_results = Task.yield_many(tasks)
|
||||
|
||||
results =
|
||||
Enum.map(tasks_with_results, fn {task, res} ->
|
||||
res || Task.shutdown(task, :brutal_kill)
|
||||
end)
|
||||
|
||||
conns = for {:ok, value} <- results, do: value
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Conn{
|
||||
conn: conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
assert Enum.all?(conns, fn res -> res == conn end)
|
||||
end
|
||||
|
||||
test "remove frequently used and idle", %{name: name} do
|
||||
open_mock(3)
|
||||
self = self()
|
||||
http_url = "http://some-domain.com"
|
||||
https_url = "https://some-domain.com"
|
||||
:ok = Conn.open(https_url, name)
|
||||
:ok = Conn.open(http_url, name)
|
||||
|
||||
conn1 = Connections.checkin(https_url, name)
|
||||
|
||||
[conn2 | _conns] =
|
||||
for _ <- 1..4 do
|
||||
Connections.checkin(http_url, name)
|
||||
end
|
||||
|
||||
http_key = "http:some-domain.com:80"
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^http_key => %Conn{
|
||||
conn: ^conn2,
|
||||
gun_state: :up,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}, {^self, _}, {^self, _}, {^self, _}]
|
||||
},
|
||||
"https:some-domain.com:443" => %Conn{
|
||||
conn: ^conn1,
|
||||
gun_state: :up,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn1, self, name)
|
||||
|
||||
another_url = "http://another-domain.com"
|
||||
:ok = Conn.open(another_url, name)
|
||||
conn = Connections.checkin(another_url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:another-domain.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
},
|
||||
^http_key => %Conn{
|
||||
conn: _,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
describe "with proxy" do
|
||||
test "as ip", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "http://proxy-string.com"
|
||||
key = "http:proxy-string.com:80"
|
||||
:ok = Conn.open(url, name, proxy: {{127, 0, 0, 1}, 8123})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as host", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "http://proxy-tuple-atom.com"
|
||||
:ok = Conn.open(url, name, proxy: {'localhost', 9050})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:proxy-tuple-atom.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as ip and ssl", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "https://proxy-string.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {{127, 0, 0, 1}, 8123})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-string.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as host and ssl", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "https://proxy-tuple-atom.com"
|
||||
:ok = Conn.open(url, name, proxy: {'localhost', 9050})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-tuple-atom.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "with socks type", %{name: name} do
|
||||
open_mock()
|
||||
|
||||
url = "http://proxy-socks.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {:socks5, 'localhost', 1234})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:proxy-socks.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "with socks4 type and ssl", %{name: name} do
|
||||
open_mock()
|
||||
url = "https://proxy-socks.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {:socks4, 'localhost', 1234})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-socks.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
end
|
||||
|
||||
describe "crf/3" do
|
||||
setup do
|
||||
crf = Connections.crf(1, 10, 1)
|
||||
{:ok, crf: crf}
|
||||
end
|
||||
|
||||
test "more used will have crf higher", %{crf: crf} do
|
||||
# used 3 times
|
||||
crf1 = Connections.crf(1, 10, crf)
|
||||
crf1 = Connections.crf(1, 10, crf1)
|
||||
|
||||
# used 2 times
|
||||
crf2 = Connections.crf(1, 10, crf)
|
||||
|
||||
assert crf1 > crf2
|
||||
end
|
||||
|
||||
test "recently used will have crf higher on equal references", %{crf: crf} do
|
||||
# used 3 sec ago
|
||||
crf1 = Connections.crf(3, 10, crf)
|
||||
|
||||
# used 4 sec ago
|
||||
crf2 = Connections.crf(4, 10, crf)
|
||||
|
||||
assert crf1 > crf2
|
||||
end
|
||||
|
||||
test "equal crf on equal reference and time", %{crf: crf} do
|
||||
# used 2 times
|
||||
crf1 = Connections.crf(1, 10, crf)
|
||||
|
||||
# used 2 times
|
||||
crf2 = Connections.crf(1, 10, crf)
|
||||
|
||||
assert crf1 == crf2
|
||||
end
|
||||
|
||||
test "recently used will have higher crf", %{crf: crf} do
|
||||
crf1 = Connections.crf(2, 10, crf)
|
||||
crf1 = Connections.crf(1, 10, crf1)
|
||||
|
||||
crf2 = Connections.crf(3, 10, crf)
|
||||
crf2 = Connections.crf(4, 10, crf2)
|
||||
assert crf1 > crf2
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_unused_conns/1" do
|
||||
test "crf is equalent, sorting by reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "reference is equalent, sorting by crf", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 1.999
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "higher crf and lower reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 3,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"2", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "lower crf and lower reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 1.99,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
end
|
||||
|
||||
test "count/1" do
|
||||
name = :test_count
|
||||
{:ok, _} = Connections.start_link({name, [checkin_timeout: 150]})
|
||||
assert Connections.count(name) == 0
|
||||
Connections.add_conn(name, "1", %Conn{conn: self()})
|
||||
assert Connections.count(name) == 1
|
||||
Connections.remove_conn(name, "1")
|
||||
assert Connections.count(name) == 0
|
||||
end
|
||||
end
|
||||
|
|
@ -314,7 +314,7 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
test "not atachment", %{conn: conn} do
|
||||
disposition_headers_mock([
|
||||
{"content-type", "image/gif"},
|
||||
{"content-length", 0}
|
||||
{"content-length", "0"}
|
||||
])
|
||||
|
||||
conn = ReverseProxy.call(conn, "/disposition")
|
||||
|
|
@ -325,7 +325,7 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
test "with content-disposition header", %{conn: conn} do
|
||||
disposition_headers_mock([
|
||||
{"content-disposition", "attachment; filename=\"filename.jpg\""},
|
||||
{"content-length", 0}
|
||||
{"content-length", "0"}
|
||||
])
|
||||
|
||||
conn = ReverseProxy.call(conn, "/disposition")
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ defmodule Pleroma.Cluster do
|
|||
silence_logger_warnings(fn ->
|
||||
node_configs
|
||||
|> Enum.map(&Task.async(fn -> start_slave(&1) end))
|
||||
|> Enum.map(&Task.await(&1, 60_000))
|
||||
|> Enum.map(&Task.await(&1, 90_000))
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ defmodule Pleroma.Factory do
|
|||
data = %{
|
||||
"type" => "Note",
|
||||
"content" => text,
|
||||
"source" => text,
|
||||
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
|
||||
"actor" => user.ap_id,
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
|
|
@ -427,4 +428,12 @@ defmodule Pleroma.Factory do
|
|||
user: build(:user)
|
||||
}
|
||||
end
|
||||
|
||||
def filter_factory do
|
||||
%Pleroma.Filter{
|
||||
user: build(:user),
|
||||
filter_id: sequence(:filter_id, & &1),
|
||||
phrase: "cofe"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -308,6 +308,22 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://framatube.org/accounts/framasoft", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/https___framatube.org_accounts_framasoft.json")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/framatube.org-video.json")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://peertube.social/accounts/craigmaloney", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -1326,6 +1342,18 @@ defmodule HttpRequestMock do
|
|||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}}
|
||||
end
|
||||
|
||||
def get("http://localhost:4001/", _, "", Accept: "text/html") do
|
||||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}}
|
||||
end
|
||||
|
||||
def get("https://osada.macgirvin.com/", _, "", Accept: "text/html") do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com.html")
|
||||
}}
|
||||
end
|
||||
|
||||
def get(url, query, body, headers) do
|
||||
{:error,
|
||||
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ defmodule Pleroma.Tests.ObanHelpers do
|
|||
end
|
||||
|
||||
def perform(%Oban.Job{} = job) do
|
||||
res = apply(String.to_existing_atom("Elixir." <> job.worker), :perform, [job.args, job])
|
||||
res = apply(String.to_existing_atom("Elixir." <> job.worker), :perform, [job])
|
||||
Repo.delete(job)
|
||||
res
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
|
|||
alias Pleroma.Web.ActivityPub.Utils
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
||||
|
|
@ -46,7 +48,8 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
|
|||
|
||||
describe "running unfollow" do
|
||||
test "relay is unfollowed" do
|
||||
target_instance = "http://mastodon.example.org/users/admin"
|
||||
user = insert(:user)
|
||||
target_instance = user.ap_id
|
||||
|
||||
Mix.Tasks.Pleroma.Relay.run(["follow", target_instance])
|
||||
|
||||
|
|
@ -71,7 +74,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
|
|||
|
||||
assert undo_activity.data["type"] == "Undo"
|
||||
assert undo_activity.data["actor"] == local_user.ap_id
|
||||
assert undo_activity.data["object"] == cancelled_activity.data
|
||||
assert undo_activity.data["object"]["id"] == cancelled_activity.data["id"]
|
||||
refute "#{target_instance}/followers" in User.following(local_user)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -110,7 +110,23 @@ defmodule Mix.Tasks.Pleroma.UserTest do
|
|||
|
||||
test "a remote user's create activity is deleted when the object has been pruned" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "uguu"})
|
||||
{:ok, post2} = CommonAPI.post(user2, %{status: "test"})
|
||||
obj = Object.normalize(post2)
|
||||
|
||||
{:ok, like_object, meta} = Pleroma.Web.ActivityPub.Builder.like(user, obj)
|
||||
|
||||
{:ok, like_activity, _meta} =
|
||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(
|
||||
like_object,
|
||||
Keyword.put(meta, :local, true)
|
||||
)
|
||||
|
||||
like_activity.data["object"]
|
||||
|> Pleroma.Object.get_by_ap_id()
|
||||
|> Repo.delete()
|
||||
|
||||
clear_config([:instance, :federating], true)
|
||||
|
||||
|
|
@ -127,6 +143,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do
|
|||
assert %{deactivated: true} = User.get_by_nickname(user.nickname)
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(:_))
|
||||
refute Pleroma.Repo.get(Pleroma.Activity, like_activity.id)
|
||||
end
|
||||
|
||||
refute Activity.get_by_id(post.id)
|
||||
|
|
@ -464,17 +481,17 @@ defmodule Mix.Tasks.Pleroma.UserTest do
|
|||
moot = insert(:user, nickname: "moot")
|
||||
kawen = insert(:user, nickname: "kawen", name: "fediverse expert moon")
|
||||
|
||||
{:ok, user} = User.follow(user, kawen)
|
||||
{:ok, user} = User.follow(user, moon)
|
||||
|
||||
assert [moon.id, kawen.id] == User.Search.search("moon") |> Enum.map(& &1.id)
|
||||
res = User.search("moo") |> Enum.map(& &1.id)
|
||||
assert moon.id in res
|
||||
assert moot.id in res
|
||||
assert kawen.id in res
|
||||
assert [moon.id, kawen.id] == User.Search.search("moon fediverse") |> Enum.map(& &1.id)
|
||||
|
||||
assert [kawen.id, moon.id] ==
|
||||
User.Search.search("moon fediverse", for_user: user) |> Enum.map(& &1.id)
|
||||
res = User.search("moo") |> Enum.map(& &1.id)
|
||||
assert Enum.sort([moon.id, moot.id, kawen.id]) == Enum.sort(res)
|
||||
|
||||
assert [kawen.id, moon.id] == User.Search.search("expert fediverse") |> Enum.map(& &1.id)
|
||||
|
||||
assert [moon.id, kawen.id] ==
|
||||
User.Search.search("expert fediverse", for_user: user) |> Enum.map(& &1.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
31
test/upload/filter/exiftool_test.exs
Normal file
31
test/upload/filter/exiftool_test.exs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Upload.Filter.ExiftoolTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Upload.Filter
|
||||
|
||||
test "apply exiftool filter" do
|
||||
File.cp!(
|
||||
"test/fixtures/DSCN0010.jpg",
|
||||
"test/fixtures/DSCN0010_tmp.jpg"
|
||||
)
|
||||
|
||||
upload = %Pleroma.Upload{
|
||||
name: "image_with_GPS_data.jpg",
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/DSCN0010.jpg"),
|
||||
tempfile: Path.absname("test/fixtures/DSCN0010_tmp.jpg")
|
||||
}
|
||||
|
||||
assert Filter.Exiftool.filter(upload) == :ok
|
||||
|
||||
{exif_original, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010.jpg"])
|
||||
{exif_filtered, 0} = System.cmd("exiftool", ["test/fixtures/DSCN0010_tmp.jpg"])
|
||||
|
||||
refute exif_original == exif_filtered
|
||||
assert String.match?(exif_original, ~r/GPS/)
|
||||
refute String.match?(exif_filtered, ~r/GPS/)
|
||||
end
|
||||
end
|
||||
|
|
@ -107,6 +107,19 @@ defmodule Pleroma.UploadTest do
|
|||
describe "Storing a file with the Local uploader" do
|
||||
setup [:ensure_local_uploader]
|
||||
|
||||
test "does not allow descriptions longer than the post limit" do
|
||||
clear_config([:instance, :description_limit], 2)
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "image.jpg"
|
||||
}
|
||||
|
||||
{:error, :description_too_long} = Upload.store(file, description: "123")
|
||||
end
|
||||
|
||||
test "returns a media url" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ defmodule Pleroma.User.NotificationSettingTest do
|
|||
alias Pleroma.User.NotificationSetting
|
||||
|
||||
describe "changeset/2" do
|
||||
test "sets valid privacy option" do
|
||||
test "sets option to hide notification contents" do
|
||||
changeset =
|
||||
NotificationSetting.changeset(
|
||||
%NotificationSetting{},
|
||||
%{"privacy_option" => true}
|
||||
%{"hide_notification_contents" => true}
|
||||
)
|
||||
|
||||
assert %Ecto.Changeset{valid?: true} = changeset
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ defmodule Pleroma.UserSearchTest do
|
|||
describe "User.search" do
|
||||
setup do: clear_config([:instance, :limit_to_local_content])
|
||||
|
||||
test "excluded invisible users from results" do
|
||||
test "excludes invisible users from results" do
|
||||
user = insert(:user, %{nickname: "john t1000"})
|
||||
insert(:user, %{invisible: true, nickname: "john t800"})
|
||||
|
||||
|
|
@ -25,6 +25,15 @@ defmodule Pleroma.UserSearchTest do
|
|||
assert found_user.id == user.id
|
||||
end
|
||||
|
||||
test "excludes service actors from results" do
|
||||
insert(:user, actor_type: "Application", nickname: "user1")
|
||||
service = insert(:user, actor_type: "Service", nickname: "user2")
|
||||
person = insert(:user, actor_type: "Person", nickname: "user3")
|
||||
|
||||
assert [found_user1, found_user2] = User.search("user")
|
||||
assert [found_user1.id, found_user2.id] -- [service.id, person.id] == []
|
||||
end
|
||||
|
||||
test "accepts limit parameter" do
|
||||
Enum.each(0..4, &insert(:user, %{nickname: "john#{&1}"}))
|
||||
assert length(User.search("john", limit: 3)) == 3
|
||||
|
|
@ -37,30 +46,49 @@ defmodule Pleroma.UserSearchTest do
|
|||
assert length(User.search("john", limit: 3, offset: 3)) == 2
|
||||
end
|
||||
|
||||
test "finds a user by full or partial nickname" do
|
||||
defp clear_virtual_fields(user) do
|
||||
Map.merge(user, %{search_rank: nil, search_type: nil})
|
||||
end
|
||||
|
||||
test "finds a user by full nickname or its leading fragment" do
|
||||
user = insert(:user, %{nickname: "john"})
|
||||
|
||||
Enum.each(["john", "jo", "j"], fn query ->
|
||||
assert user ==
|
||||
User.search(query)
|
||||
|> List.first()
|
||||
|> Map.put(:search_rank, nil)
|
||||
|> Map.put(:search_type, nil)
|
||||
|> clear_virtual_fields()
|
||||
end)
|
||||
end
|
||||
|
||||
test "finds a user by full or partial name" do
|
||||
test "finds a user by full name or leading fragment(s) of its words" do
|
||||
user = insert(:user, %{name: "John Doe"})
|
||||
|
||||
Enum.each(["John Doe", "JOHN", "doe", "j d", "j", "d"], fn query ->
|
||||
assert user ==
|
||||
User.search(query)
|
||||
|> List.first()
|
||||
|> Map.put(:search_rank, nil)
|
||||
|> Map.put(:search_type, nil)
|
||||
|> clear_virtual_fields()
|
||||
end)
|
||||
end
|
||||
|
||||
test "matches by leading fragment of user domain" do
|
||||
user = insert(:user, %{nickname: "arandom@dude.com"})
|
||||
insert(:user, %{nickname: "iamthedude"})
|
||||
|
||||
assert [user.id] == User.search("dud") |> Enum.map(& &1.id)
|
||||
end
|
||||
|
||||
test "ranks full nickname match higher than full name match" do
|
||||
nicknamed_user = insert(:user, %{nickname: "hj@shigusegubu.club"})
|
||||
named_user = insert(:user, %{nickname: "xyz@sample.com", name: "HJ"})
|
||||
|
||||
results = User.search("hj")
|
||||
|
||||
assert [nicknamed_user.id, named_user.id] == Enum.map(results, & &1.id)
|
||||
assert Enum.at(results, 0).search_rank > Enum.at(results, 1).search_rank
|
||||
end
|
||||
|
||||
test "finds users, considering density of matched tokens" do
|
||||
u1 = insert(:user, %{name: "Bar Bar plus Word Word"})
|
||||
u2 = insert(:user, %{name: "Word Word Bar Bar Bar"})
|
||||
|
|
|
|||
|
|
@ -486,6 +486,15 @@ defmodule Pleroma.UserTest do
|
|||
}
|
||||
setup do: clear_config([:instance, :account_activation_required], true)
|
||||
|
||||
test "it sets the 'accepts_chat_messages' set to true" do
|
||||
changeset = User.register_changeset(%User{}, @full_user_data)
|
||||
assert changeset.valid?
|
||||
|
||||
{:ok, user} = Repo.insert(changeset)
|
||||
|
||||
assert user.accepts_chat_messages
|
||||
end
|
||||
|
||||
test "it creates unconfirmed user" do
|
||||
changeset = User.register_changeset(%User{}, @full_user_data)
|
||||
assert changeset.valid?
|
||||
|
|
|
|||
|
|
@ -1082,6 +1082,45 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert object = Object.get_by_ap_id(note_object.data["id"])
|
||||
assert object.data["like_count"] == 1
|
||||
end
|
||||
|
||||
test "it doesn't spreads faulty attributedTo or actor fields", %{
|
||||
conn: conn,
|
||||
activity: activity
|
||||
} do
|
||||
reimu = insert(:user, nickname: "reimu")
|
||||
cirno = insert(:user, nickname: "cirno")
|
||||
|
||||
assert reimu.ap_id
|
||||
assert cirno.ap_id
|
||||
|
||||
activity =
|
||||
activity
|
||||
|> put_in(["object", "actor"], reimu.ap_id)
|
||||
|> put_in(["object", "attributedTo"], reimu.ap_id)
|
||||
|> put_in(["actor"], reimu.ap_id)
|
||||
|> put_in(["attributedTo"], reimu.ap_id)
|
||||
|
||||
_reimu_outbox =
|
||||
conn
|
||||
|> assign(:user, cirno)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{reimu.nickname}/outbox", activity)
|
||||
|> json_response(403)
|
||||
|
||||
cirno_outbox =
|
||||
conn
|
||||
|> assign(:user, cirno)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{cirno.nickname}/outbox", activity)
|
||||
|> json_response(201)
|
||||
|
||||
assert cirno_outbox["attributedTo"] == nil
|
||||
assert cirno_outbox["actor"] == cirno.ap_id
|
||||
|
||||
assert cirno_object = Object.normalize(cirno_outbox["object"])
|
||||
assert cirno_object.data["actor"] == cirno.ap_id
|
||||
assert cirno_object.data["attributedTo"] == cirno.ap_id
|
||||
end
|
||||
end
|
||||
|
||||
describe "/relay/followers" do
|
||||
|
|
|
|||
|
|
@ -184,38 +184,45 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert User.invisible?(user)
|
||||
end
|
||||
|
||||
test "it fetches the appropriate tag-restricted posts" do
|
||||
user = insert(:user)
|
||||
test "it returns a user that accepts chat messages" do
|
||||
user_id = "http://mastodon.example.org/users/admin"
|
||||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||
|
||||
{:ok, status_one} = CommonAPI.post(user, %{status: ". #test"})
|
||||
{:ok, status_two} = CommonAPI.post(user, %{status: ". #essais"})
|
||||
{:ok, status_three} = CommonAPI.post(user, %{status: ". #test #reject"})
|
||||
|
||||
fetch_one = ActivityPub.fetch_activities([], %{type: "Create", tag: "test"})
|
||||
|
||||
fetch_two = ActivityPub.fetch_activities([], %{type: "Create", tag: ["test", "essais"]})
|
||||
|
||||
fetch_three =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
type: "Create",
|
||||
tag: ["test", "essais"],
|
||||
tag_reject: ["reject"]
|
||||
})
|
||||
|
||||
fetch_four =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
type: "Create",
|
||||
tag: ["test"],
|
||||
tag_all: ["test", "reject"]
|
||||
})
|
||||
|
||||
assert fetch_one == [status_one, status_three]
|
||||
assert fetch_two == [status_one, status_two, status_three]
|
||||
assert fetch_three == [status_one, status_two]
|
||||
assert fetch_four == [status_three]
|
||||
assert user.accepts_chat_messages
|
||||
end
|
||||
end
|
||||
|
||||
test "it fetches the appropriate tag-restricted posts" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, status_one} = CommonAPI.post(user, %{status: ". #test"})
|
||||
{:ok, status_two} = CommonAPI.post(user, %{status: ". #essais"})
|
||||
{:ok, status_three} = CommonAPI.post(user, %{status: ". #test #reject"})
|
||||
|
||||
fetch_one = ActivityPub.fetch_activities([], %{type: "Create", tag: "test"})
|
||||
|
||||
fetch_two = ActivityPub.fetch_activities([], %{type: "Create", tag: ["test", "essais"]})
|
||||
|
||||
fetch_three =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
type: "Create",
|
||||
tag: ["test", "essais"],
|
||||
tag_reject: ["reject"]
|
||||
})
|
||||
|
||||
fetch_four =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
type: "Create",
|
||||
tag: ["test"],
|
||||
tag_all: ["test", "reject"]
|
||||
})
|
||||
|
||||
assert fetch_one == [status_one, status_three]
|
||||
assert fetch_two == [status_one, status_two, status_three]
|
||||
assert fetch_three == [status_one, status_two]
|
||||
assert fetch_four == [status_three]
|
||||
end
|
||||
|
||||
describe "insertion" do
|
||||
test "drops activities beyond a certain limit" do
|
||||
limit = Config.get([:instance, :remote_limit])
|
||||
|
|
@ -507,6 +514,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
activities = ActivityPub.fetch_activities_for_context("2hu", %{blocking_user: user})
|
||||
assert activities == [activity_two, activity]
|
||||
end
|
||||
|
||||
test "doesn't return activities with filtered words" do
|
||||
user = insert(:user)
|
||||
user_two = insert(:user)
|
||||
insert(:filter, user: user, phrase: "test", hide: true)
|
||||
|
||||
{:ok, %{id: id1, data: %{"context" => context}}} = CommonAPI.post(user, %{status: "1"})
|
||||
|
||||
{:ok, %{id: id2}} = CommonAPI.post(user_two, %{status: "2", in_reply_to_status_id: id1})
|
||||
|
||||
{:ok, %{id: id3} = user_activity} =
|
||||
CommonAPI.post(user, %{status: "3 test?", in_reply_to_status_id: id2})
|
||||
|
||||
{:ok, %{id: id4} = filtered_activity} =
|
||||
CommonAPI.post(user_two, %{status: "4 test!", in_reply_to_status_id: id3})
|
||||
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "5", in_reply_to_status_id: id4})
|
||||
|
||||
activities =
|
||||
context
|
||||
|> ActivityPub.fetch_activities_for_context(%{user: user})
|
||||
|> Enum.map(& &1.id)
|
||||
|
||||
assert length(activities) == 4
|
||||
assert user_activity.id in activities
|
||||
refute filtered_activity.id in activities
|
||||
end
|
||||
end
|
||||
|
||||
test "doesn't return blocked activities" do
|
||||
|
|
@ -642,7 +676,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
refute activity in activities
|
||||
|
||||
followed_user = insert(:user)
|
||||
ActivityPub.follow(user, followed_user)
|
||||
CommonAPI.follow(user, followed_user)
|
||||
{:ok, repeat_activity} = CommonAPI.repeat(activity.id, followed_user)
|
||||
|
||||
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
|
||||
|
|
@ -785,6 +819,75 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert activity == expected_activity
|
||||
end
|
||||
|
||||
describe "irreversible filters" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
user_two = insert(:user)
|
||||
|
||||
insert(:filter, user: user_two, phrase: "cofe", hide: true)
|
||||
insert(:filter, user: user_two, phrase: "ok boomer", hide: true)
|
||||
insert(:filter, user: user_two, phrase: "test", hide: false)
|
||||
|
||||
params = %{
|
||||
type: ["Create", "Announce"],
|
||||
user: user_two
|
||||
}
|
||||
|
||||
{:ok, %{user: user, user_two: user_two, params: params}}
|
||||
end
|
||||
|
||||
test "it returns statuses if they don't contain exact filter words", %{
|
||||
user: user,
|
||||
params: params
|
||||
} do
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "got cofefe?"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "I am not a boomer"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "ok boomers"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "ccofee is not a word"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "this is a test"})
|
||||
|
||||
activities = ActivityPub.fetch_activities([], params)
|
||||
|
||||
assert Enum.count(activities) == 6
|
||||
end
|
||||
|
||||
test "it does not filter user's own statuses", %{user_two: user_two, params: params} do
|
||||
{:ok, _} = CommonAPI.post(user_two, %{status: "Give me some cofe!"})
|
||||
{:ok, _} = CommonAPI.post(user_two, %{status: "ok boomer"})
|
||||
|
||||
activities = ActivityPub.fetch_activities([], params)
|
||||
|
||||
assert Enum.count(activities) == 2
|
||||
end
|
||||
|
||||
test "it excludes statuses with filter words", %{user: user, params: params} do
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "Give me some cofe!"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "ok boomer"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "is it a cOfE?"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "cofe is all I need"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "— ok BOOMER\n"})
|
||||
|
||||
activities = ActivityPub.fetch_activities([], params)
|
||||
|
||||
assert Enum.empty?(activities)
|
||||
end
|
||||
|
||||
test "it returns all statuses if user does not have any filters" do
|
||||
another_user = insert(:user)
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "got cofe?"})
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "test!"})
|
||||
|
||||
activities =
|
||||
ActivityPub.fetch_activities([], %{
|
||||
type: ["Create", "Announce"],
|
||||
user: another_user
|
||||
})
|
||||
|
||||
assert Enum.count(activities) == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "public fetch activities" do
|
||||
test "doesn't retrieve unlisted activities" do
|
||||
user = insert(:user)
|
||||
|
|
@ -917,24 +1020,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "following / unfollowing" do
|
||||
test "it reverts follow activity" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
|
||||
assert {:error, :reverted} = ActivityPub.follow(follower, followed)
|
||||
end
|
||||
|
||||
assert Repo.aggregate(Activity, :count, :id) == 0
|
||||
assert Repo.aggregate(Object, :count, :id) == 0
|
||||
end
|
||||
|
||||
describe "unfollowing" do
|
||||
test "it reverts unfollow activity" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
|
||||
assert {:error, :reverted} = ActivityPub.unfollow(follower, followed)
|
||||
|
|
@ -947,21 +1038,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert activity.data["object"] == followed.ap_id
|
||||
end
|
||||
|
||||
test "creates a follow activity" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
{:ok, activity} = ActivityPub.follow(follower, followed)
|
||||
assert activity.data["type"] == "Follow"
|
||||
assert activity.data["actor"] == follower.ap_id
|
||||
assert activity.data["object"] == followed.ap_id
|
||||
end
|
||||
|
||||
test "creates an undo activity for the last follow" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
{:ok, activity} = ActivityPub.unfollow(follower, followed)
|
||||
|
||||
assert activity.data["type"] == "Undo"
|
||||
|
|
@ -978,7 +1059,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
follower = insert(:user)
|
||||
followed = insert(:user, %{locked: true})
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
{:ok, activity} = ActivityPub.unfollow(follower, followed)
|
||||
|
||||
assert activity.data["type"] == "Undo"
|
||||
|
|
@ -1363,7 +1444,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(params, nil)
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
refute User.following?(follower, old_user)
|
||||
assert User.following?(follower, new_user)
|
||||
|
|
@ -1975,4 +2056,46 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert [%{activity_id: ^id_create}] = Pleroma.ActivityExpiration |> Repo.all()
|
||||
end
|
||||
end
|
||||
|
||||
describe "handling of clashing nicknames" do
|
||||
test "renames an existing user with a clashing nickname and a different ap id" do
|
||||
orig_user =
|
||||
insert(
|
||||
:user,
|
||||
local: false,
|
||||
nickname: "admin@mastodon.example.org",
|
||||
ap_id: "http://mastodon.example.org/users/harinezumigari"
|
||||
)
|
||||
|
||||
%{
|
||||
nickname: orig_user.nickname,
|
||||
ap_id: orig_user.ap_id <> "part_2"
|
||||
}
|
||||
|> ActivityPub.maybe_handle_clashing_nickname()
|
||||
|
||||
user = User.get_by_id(orig_user.id)
|
||||
|
||||
assert user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
|
||||
end
|
||||
|
||||
test "does nothing with a clashing nickname and the same ap id" do
|
||||
orig_user =
|
||||
insert(
|
||||
:user,
|
||||
local: false,
|
||||
nickname: "admin@mastodon.example.org",
|
||||
ap_id: "http://mastodon.example.org/users/harinezumigari"
|
||||
)
|
||||
|
||||
%{
|
||||
nickname: orig_user.nickname,
|
||||
ap_id: orig_user.ap_id
|
||||
}
|
||||
|> ActivityPub.maybe_handle_clashing_nickname()
|
||||
|
||||
user = User.get_by_id(orig_user.id)
|
||||
|
||||
assert user.nickname == orig_user.nickname
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
|
|||
"id" => "https://example.com/activities/1234"
|
||||
}
|
||||
|
||||
{:reject, nil} = AntiFollowbotPolicy.filter(message)
|
||||
assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "matches followbots by display name" do
|
||||
|
|
@ -36,7 +36,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
|
|||
"id" => "https://example.com/activities/1234"
|
||||
}
|
||||
|
||||
{:reject, nil} = AntiFollowbotPolicy.filter(message)
|
||||
assert {:reject, "[AntiFollowbotPolicy]" <> _} = AntiFollowbotPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
|
|||
} do
|
||||
Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 0, reject_threshold: 2})
|
||||
|
||||
{:reject, nil} = filter(message)
|
||||
assert {:reject, "[HellthreadPolicy] 3 recipients is over the limit of 2"} ==
|
||||
filter(message)
|
||||
end
|
||||
|
||||
test "does not reject the message if the recipient count is below reject_threshold", %{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
assert {:reject, nil} == KeywordPolicy.filter(message)
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "rejects if string matches in summary" do
|
||||
|
|
@ -39,7 +40,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
assert {:reject, nil} == KeywordPolicy.filter(message)
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "rejects if regex matches in content" do
|
||||
|
|
@ -55,7 +57,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
{:reject, nil} == KeywordPolicy.filter(message)
|
||||
{:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
|
||||
KeywordPolicy.filter(message)
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
@ -72,7 +75,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
{:reject, nil} == KeywordPolicy.filter(message)
|
||||
{:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
|
||||
KeywordPolicy.filter(message)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do
|
|||
"to" => ["https://example.com/blocked"]
|
||||
}
|
||||
|
||||
assert MentionPolicy.filter(message) == {:reject, nil}
|
||||
assert MentionPolicy.filter(message) ==
|
||||
{:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"}
|
||||
end
|
||||
|
||||
test "cc" do
|
||||
|
|
@ -88,7 +89,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do
|
|||
"cc" => ["https://example.com/blocked"]
|
||||
}
|
||||
|
||||
assert MentionPolicy.filter(message) == {:reject, nil}
|
||||
assert MentionPolicy.filter(message) ==
|
||||
{:reject, "[MentionPolicy] Rejected for mention of https://example.com/blocked"}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do
|
|||
}
|
||||
|
||||
Pleroma.Config.put([:mrf_rejectnonpublic, :allow_followersonly], false)
|
||||
assert {:reject, nil} = RejectNonPublic.filter(message)
|
||||
assert {:reject, _} = RejectNonPublic.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do
|
|||
}
|
||||
|
||||
Pleroma.Config.put([:mrf_rejectnonpublic, :allow_direct], false)
|
||||
assert {:reject, nil} = RejectNonPublic.filter(message)
|
||||
assert {:reject, _} = RejectNonPublic.filter(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
report_message = build_report_message()
|
||||
local_message = build_local_message()
|
||||
|
||||
assert SimplePolicy.filter(report_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(report_message)
|
||||
assert SimplePolicy.filter(local_message) == {:ok, local_message}
|
||||
end
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
report_message = build_report_message()
|
||||
local_message = build_local_message()
|
||||
|
||||
assert SimplePolicy.filter(report_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(report_message)
|
||||
assert SimplePolicy.filter(local_message) == {:ok, local_message}
|
||||
end
|
||||
end
|
||||
|
|
@ -241,7 +241,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
|
||||
remote_message = build_remote_message()
|
||||
|
||||
assert SimplePolicy.filter(remote_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(remote_message)
|
||||
end
|
||||
|
||||
test "activity matches with wildcard domain" do
|
||||
|
|
@ -249,7 +249,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
|
||||
remote_message = build_remote_message()
|
||||
|
||||
assert SimplePolicy.filter(remote_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(remote_message)
|
||||
end
|
||||
|
||||
test "actor has a matching host" do
|
||||
|
|
@ -257,7 +257,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
|
||||
remote_user = build_remote_user()
|
||||
|
||||
assert SimplePolicy.filter(remote_user) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(remote_user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
remote_message = build_remote_message()
|
||||
|
||||
assert SimplePolicy.filter(local_message) == {:ok, local_message}
|
||||
assert SimplePolicy.filter(remote_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(remote_message)
|
||||
end
|
||||
|
||||
test "activity has a matching host" do
|
||||
|
|
@ -429,7 +429,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
test "it rejects the deletion" do
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(deletion_message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -439,7 +439,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
test "it rejects the deletion" do
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
|
||||
assert {:reject, _} = SimplePolicy.filter(deletion_message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do
|
|||
describe "mrf_tag:disable-any-subscription" do
|
||||
test "rejects message" do
|
||||
actor = insert(:user, tags: ["mrf_tag:disable-any-subscription"])
|
||||
message = %{"object" => actor.ap_id, "type" => "Follow"}
|
||||
assert {:reject, nil} = TagPolicy.filter(message)
|
||||
message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => actor.ap_id}
|
||||
assert {:reject, _} = TagPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicyTest do
|
|||
actor = insert(:user, tags: ["mrf_tag:disable-remote-subscription"])
|
||||
follower = insert(:user, tags: ["mrf_tag:disable-remote-subscription"], local: false)
|
||||
message = %{"object" => actor.ap_id, "type" => "Follow", "actor" => follower.ap_id}
|
||||
assert {:reject, nil} = TagPolicy.filter(message)
|
||||
assert {:reject, _} = TagPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "allows non-local follow requests" do
|
||||
|
|
|
|||
|
|
@ -26,6 +26,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
|
|||
actor = insert(:user)
|
||||
Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => ["test-ap-id"]})
|
||||
message = %{"actor" => actor.ap_id}
|
||||
assert UserAllowListPolicy.filter(message) == {:reject, nil}
|
||||
assert {:reject, _} = UserAllowListPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
{:reject, nil} = VocabularyPolicy.filter(message)
|
||||
{:reject, _} = VocabularyPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "it does not accept disallowed parent types" do
|
||||
|
|
@ -60,7 +60,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
{:reject, nil} = VocabularyPolicy.filter(message)
|
||||
{:reject, _} = VocabularyPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
|
|||
"object" => "whatever"
|
||||
}
|
||||
|
||||
{:reject, nil} = VocabularyPolicy.filter(message)
|
||||
{:reject, _} = VocabularyPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "it rejects based on child object type" do
|
||||
|
|
@ -89,7 +89,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.VocabularyPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
{:reject, nil} = VocabularyPolicy.filter(message)
|
||||
{:reject, _} = VocabularyPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "it passes through objects that aren't disallowed" do
|
||||
|
|
|
|||
|
|
@ -1,684 +0,0 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "attachments" do
|
||||
test "works with honkerific attachments" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
"name" => "",
|
||||
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
|
||||
"type" => "Document",
|
||||
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
|
||||
}
|
||||
|
||||
assert {:ok, attachment} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert attachment.mediaType == "application/octet-stream"
|
||||
end
|
||||
|
||||
test "it turns mastodon attachments into our attachments" do
|
||||
attachment = %{
|
||||
"url" =>
|
||||
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
|
||||
"type" => "Document",
|
||||
"name" => nil,
|
||||
"mediaType" => "image/jpeg"
|
||||
}
|
||||
|
||||
{:ok, attachment} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert [
|
||||
%{
|
||||
href:
|
||||
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
|
||||
type: "Link",
|
||||
mediaType: "image/jpeg"
|
||||
}
|
||||
] = attachment.url
|
||||
|
||||
assert attachment.mediaType == "image/jpeg"
|
||||
end
|
||||
|
||||
test "it handles our own uploads" do
|
||||
user = insert(:user)
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
{:ok, attachment} =
|
||||
attachment.data
|
||||
|> AttachmentValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert attachment.mediaType == "image/jpeg"
|
||||
end
|
||||
end
|
||||
|
||||
describe "chat message create activities" do
|
||||
test "it is invalid if the object already exists" do
|
||||
user = insert(:user)
|
||||
recipient = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
|
||||
object = Object.normalize(activity, false)
|
||||
|
||||
{:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(create_data, [])
|
||||
|
||||
assert {:object, {"The object to create already exists", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is invalid if the object data has a different `to` or `actor` field" do
|
||||
user = insert(:user)
|
||||
recipient = insert(:user)
|
||||
{:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
|
||||
|
||||
{:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(create_data, [])
|
||||
|
||||
assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
|
||||
assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
|
||||
describe "chat messages" do
|
||||
setup do
|
||||
clear_config([:instance, :remote_limit])
|
||||
user = insert(:user)
|
||||
recipient = insert(:user, local: false)
|
||||
|
||||
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
|
||||
|
||||
%{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
|
||||
end
|
||||
|
||||
test "let's through some basic html", %{user: user, recipient: recipient} do
|
||||
{:ok, valid_chat_message, _} =
|
||||
Builder.chat_message(
|
||||
user,
|
||||
recipient.ap_id,
|
||||
"hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
|
||||
)
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["content"] ==
|
||||
"hey <a href=\"https://example.org\">example</a> alert('uguu')"
|
||||
end
|
||||
|
||||
test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert Map.put(valid_chat_message, "attachment", nil) == object
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", attachment.data)
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment in an array", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", [attachment.data])
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment but without content", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", attachment.data)
|
||||
|> Map.delete("content")
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "does not validate if the message has no content", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
contentless =
|
||||
valid_chat_message
|
||||
|> Map.delete("content")
|
||||
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
|
||||
end
|
||||
|
||||
test "does not validate if the message is longer than the remote_limit", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
Pleroma.Config.put([:instance, :remote_limit], 2)
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
|
||||
end
|
||||
|
||||
test "does not validate if the recipient is blocking the actor", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user,
|
||||
recipient: recipient
|
||||
} do
|
||||
Pleroma.User.block(recipient, user)
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
|
||||
end
|
||||
|
||||
test "does not validate if the actor or the recipient is not in our system", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("actor", "https://raymoo.com/raymoo")
|
||||
|
||||
{:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("to", ["https://raymoo.com/raymoo"])
|
||||
|
||||
{:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
end
|
||||
|
||||
test "does not validate for a message with multiple recipients", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user,
|
||||
recipient: recipient
|
||||
} do
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("to", [user.ap_id, recipient.ap_id])
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
end
|
||||
|
||||
test "does not validate if it doesn't concern local users" do
|
||||
user = insert(:user, local: false)
|
||||
recipient = insert(:user, local: false)
|
||||
|
||||
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
|
||||
assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
|
||||
end
|
||||
end
|
||||
|
||||
describe "EmojiReacts" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
object = Pleroma.Object.get_by_ap_id(post_activity.data["object"])
|
||||
|
||||
{:ok, valid_emoji_react, []} = Builder.emoji_react(user, object, "👌")
|
||||
|
||||
%{user: user, post_activity: post_activity, valid_emoji_react: valid_emoji_react}
|
||||
end
|
||||
|
||||
test "it validates a valid EmojiReact", %{valid_emoji_react: valid_emoji_react} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_emoji_react, [])
|
||||
end
|
||||
|
||||
test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_content =
|
||||
valid_emoji_react
|
||||
|> Map.delete("content")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", "x")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:content, {"must be a single character emoji", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
|
||||
describe "Undos" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
{:ok, like} = CommonAPI.favorite(user, post_activity.id)
|
||||
{:ok, valid_like_undo, []} = Builder.undo(user, like)
|
||||
|
||||
%{user: user, like: like, valid_like_undo: valid_like_undo}
|
||||
end
|
||||
|
||||
test "it validates a basic like undo", %{valid_like_undo: valid_like_undo} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_like_undo, [])
|
||||
end
|
||||
|
||||
test "it does not validate if the actor of the undo is not the actor of the object", %{
|
||||
valid_like_undo: valid_like_undo
|
||||
} do
|
||||
other_user = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
bad_actor =
|
||||
valid_like_undo
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(bad_actor, [])
|
||||
|
||||
assert {:actor, {"not the same as object actor", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it does not validate if the object is missing", %{valid_like_undo: valid_like_undo} do
|
||||
missing_object =
|
||||
valid_like_undo
|
||||
|> Map.put("object", "https://gensokyo.2hu/objects/1")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
assert length(cng.errors) == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "deletes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "cancel me daddy"})
|
||||
|
||||
{:ok, valid_post_delete, _} = Builder.delete(user, post_activity.data["object"])
|
||||
{:ok, valid_user_delete, _} = Builder.delete(user, user.ap_id)
|
||||
|
||||
%{user: user, valid_post_delete: valid_post_delete, valid_user_delete: valid_user_delete}
|
||||
end
|
||||
|
||||
test "it is valid for a post deletion", %{valid_post_delete: valid_post_delete} do
|
||||
{:ok, valid_post_delete, _} = ObjectValidator.validate(valid_post_delete, [])
|
||||
|
||||
assert valid_post_delete["deleted_activity_id"]
|
||||
end
|
||||
|
||||
test "it is invalid if the object isn't in a list of certain types", %{
|
||||
valid_post_delete: valid_post_delete
|
||||
} do
|
||||
object = Object.get_by_ap_id(valid_post_delete["object"])
|
||||
|
||||
data =
|
||||
object.data
|
||||
|> Map.put("type", "Like")
|
||||
|
||||
{:ok, _object} =
|
||||
object
|
||||
|> Ecto.Changeset.change(%{data: data})
|
||||
|> Object.update_and_set_cache()
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(valid_post_delete, [])
|
||||
assert {:object, {"object not in allowed types", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is valid for a user deletion", %{valid_user_delete: valid_user_delete} do
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_user_delete, []))
|
||||
end
|
||||
|
||||
test "it's invalid if the id is missing", %{valid_post_delete: valid_post_delete} do
|
||||
no_id =
|
||||
valid_post_delete
|
||||
|> Map.delete("id")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(no_id, [])
|
||||
|
||||
assert {:id, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the object doesn't exist", %{valid_post_delete: valid_post_delete} do
|
||||
missing_object =
|
||||
valid_post_delete
|
||||
|> Map.put("object", "http://does.not/exist")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the actor of the object and the actor of delete are from different domains",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
valid_user = insert(:user)
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", valid_user.ap_id)
|
||||
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_other_actor, []))
|
||||
|
||||
invalid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(invalid_other_actor, [])
|
||||
|
||||
assert {:actor, {"is not allowed to delete object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's valid if the actor of the object is a local superuser",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
user =
|
||||
insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
|
||||
assert meta[:do_not_federate]
|
||||
end
|
||||
end
|
||||
|
||||
describe "likes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
valid_like = %{
|
||||
"to" => [user.ap_id],
|
||||
"cc" => [],
|
||||
"type" => "Like",
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"object" => post_activity.data["object"],
|
||||
"actor" => user.ap_id,
|
||||
"context" => "a context"
|
||||
}
|
||||
|
||||
%{valid_like: valid_like, user: user, post_activity: post_activity}
|
||||
end
|
||||
|
||||
test "returns ok when called in the ObjectValidator", %{valid_like: valid_like} do
|
||||
{:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
|
||||
|
||||
assert "id" in Map.keys(object)
|
||||
end
|
||||
|
||||
test "is valid for a valid object", %{valid_like: valid_like} do
|
||||
assert LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "sets the 'to' field to the object actor if no recipients are given", %{
|
||||
valid_like: valid_like,
|
||||
user: user
|
||||
} do
|
||||
without_recipients =
|
||||
valid_like
|
||||
|> Map.delete("to")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_recipients, [])
|
||||
|
||||
assert object["to"] == [user.ap_id]
|
||||
end
|
||||
|
||||
test "sets the context field to the context of the object if no context is given", %{
|
||||
valid_like: valid_like,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
without_context =
|
||||
valid_like
|
||||
|> Map.delete("context")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_context, [])
|
||||
|
||||
assert object["context"] == post_activity.data["context"]
|
||||
end
|
||||
|
||||
test "it errors when the actor is missing or not known", %{valid_like: valid_like} do
|
||||
without_actor = Map.delete(valid_like, "actor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_actor).valid?
|
||||
|
||||
with_invalid_actor = Map.put(valid_like, "actor", "invalidactor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_actor).valid?
|
||||
end
|
||||
|
||||
test "it errors when the object is missing or not known", %{valid_like: valid_like} do
|
||||
without_object = Map.delete(valid_like, "object")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_object).valid?
|
||||
|
||||
with_invalid_object = Map.put(valid_like, "object", "invalidobject")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_object).valid?
|
||||
end
|
||||
|
||||
test "it errors when the actor has already like the object", %{
|
||||
valid_like: valid_like,
|
||||
user: user,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
_like = CommonAPI.favorite(user, post_activity.id)
|
||||
|
||||
refute LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "it works when actor or object are wrapped in maps", %{valid_like: valid_like} do
|
||||
wrapped_like =
|
||||
valid_like
|
||||
|> Map.put("actor", %{"id" => valid_like["actor"]})
|
||||
|> Map.put("object", %{"id" => valid_like["object"]})
|
||||
|
||||
validated = LikeValidator.cast_and_validate(wrapped_like)
|
||||
|
||||
assert validated.valid?
|
||||
|
||||
assert {:actor, valid_like["actor"]} in validated.changes
|
||||
assert {:object, valid_like["object"]} in validated.changes
|
||||
end
|
||||
end
|
||||
|
||||
describe "announces" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
announcer = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
object = Object.normalize(post_activity, false)
|
||||
{:ok, valid_announce, []} = Builder.announce(announcer, object)
|
||||
|
||||
%{
|
||||
valid_announce: valid_announce,
|
||||
user: user,
|
||||
post_activity: post_activity,
|
||||
announcer: announcer
|
||||
}
|
||||
end
|
||||
|
||||
test "returns ok for a valid announce", %{valid_announce: valid_announce} do
|
||||
assert {:ok, _object, _meta} = ObjectValidator.validate(valid_announce, [])
|
||||
end
|
||||
|
||||
test "returns an error if the object can't be found", %{valid_announce: valid_announce} do
|
||||
without_object =
|
||||
valid_announce
|
||||
|> Map.delete("object")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_object, [])
|
||||
|
||||
assert {:object, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
|
||||
nonexisting_object =
|
||||
valid_announce
|
||||
|> Map.put("object", "https://gensokyo.2hu/objects/99999999")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(nonexisting_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if we don't have the actor", %{valid_announce: valid_announce} do
|
||||
nonexisting_actor =
|
||||
valid_announce
|
||||
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(nonexisting_actor, [])
|
||||
|
||||
assert {:actor, {"can't find user", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if the actor already announced the object", %{
|
||||
valid_announce: valid_announce,
|
||||
announcer: announcer,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
_announce = CommonAPI.repeat(post_activity.id, announcer)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(valid_announce, [])
|
||||
|
||||
assert {:actor, {"already announced this object", []}} in cng.errors
|
||||
assert {:object, {"already announced by this actor", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if the actor can't announce the object", %{
|
||||
announcer: announcer,
|
||||
user: user
|
||||
} do
|
||||
{:ok, post_activity} =
|
||||
CommonAPI.post(user, %{status: "a secret post", visibility: "private"})
|
||||
|
||||
object = Object.normalize(post_activity, false)
|
||||
|
||||
# Another user can't announce it
|
||||
{:ok, announce, []} = Builder.announce(announcer, object, public: false)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(announce, [])
|
||||
|
||||
assert {:actor, {"can not announce this object", []}} in cng.errors
|
||||
|
||||
# The actor of the object can announce it
|
||||
{:ok, announce, []} = Builder.announce(user, object, public: false)
|
||||
|
||||
assert {:ok, _, _} = ObjectValidator.validate(announce, [])
|
||||
|
||||
# The actor of the object can not announce it publicly
|
||||
{:ok, announce, []} = Builder.announce(user, object, public: true)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(announce, [])
|
||||
|
||||
assert {:actor, {"can not announce this object publicly", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
|
||||
describe "updates" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
object = %{
|
||||
"id" => user.ap_id,
|
||||
"name" => "A new name",
|
||||
"summary" => "A new bio"
|
||||
}
|
||||
|
||||
{:ok, valid_update, []} = Builder.update(user, object)
|
||||
|
||||
%{user: user, valid_update: valid_update}
|
||||
end
|
||||
|
||||
test "validates a basic object", %{valid_update: valid_update} do
|
||||
assert {:ok, _update, []} = ObjectValidator.validate(valid_update, [])
|
||||
end
|
||||
|
||||
test "returns an error if the object can't be updated by the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
assert {:error, _cng} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
end
|
||||
|
||||
describe "blocks" do
|
||||
setup do
|
||||
user = insert(:user, local: false)
|
||||
blocked = insert(:user)
|
||||
|
||||
{:ok, valid_block, []} = Builder.block(user, blocked)
|
||||
|
||||
%{user: user, valid_block: valid_block}
|
||||
end
|
||||
|
||||
test "validates a basic object", %{
|
||||
valid_block: valid_block
|
||||
} do
|
||||
assert {:ok, _block, []} = ObjectValidator.validate(valid_block, [])
|
||||
end
|
||||
|
||||
test "returns an error if we don't know the blocked user", %{
|
||||
valid_block: valid_block
|
||||
} do
|
||||
block =
|
||||
valid_block
|
||||
|> Map.put("object", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
assert {:error, _cng} = ObjectValidator.validate(block, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AnnouncValidationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "announces" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
announcer = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
object = Object.normalize(post_activity, false)
|
||||
{:ok, valid_announce, []} = Builder.announce(announcer, object)
|
||||
|
||||
%{
|
||||
valid_announce: valid_announce,
|
||||
user: user,
|
||||
post_activity: post_activity,
|
||||
announcer: announcer
|
||||
}
|
||||
end
|
||||
|
||||
test "returns ok for a valid announce", %{valid_announce: valid_announce} do
|
||||
assert {:ok, _object, _meta} = ObjectValidator.validate(valid_announce, [])
|
||||
end
|
||||
|
||||
test "returns an error if the object can't be found", %{valid_announce: valid_announce} do
|
||||
without_object =
|
||||
valid_announce
|
||||
|> Map.delete("object")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_object, [])
|
||||
|
||||
assert {:object, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
|
||||
nonexisting_object =
|
||||
valid_announce
|
||||
|> Map.put("object", "https://gensokyo.2hu/objects/99999999")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(nonexisting_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if we don't have the actor", %{valid_announce: valid_announce} do
|
||||
nonexisting_actor =
|
||||
valid_announce
|
||||
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(nonexisting_actor, [])
|
||||
|
||||
assert {:actor, {"can't find user", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if the actor already announced the object", %{
|
||||
valid_announce: valid_announce,
|
||||
announcer: announcer,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
_announce = CommonAPI.repeat(post_activity.id, announcer)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(valid_announce, [])
|
||||
|
||||
assert {:actor, {"already announced this object", []}} in cng.errors
|
||||
assert {:object, {"already announced by this actor", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "returns an error if the actor can't announce the object", %{
|
||||
announcer: announcer,
|
||||
user: user
|
||||
} do
|
||||
{:ok, post_activity} =
|
||||
CommonAPI.post(user, %{status: "a secret post", visibility: "private"})
|
||||
|
||||
object = Object.normalize(post_activity, false)
|
||||
|
||||
# Another user can't announce it
|
||||
{:ok, announce, []} = Builder.announce(announcer, object, public: false)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(announce, [])
|
||||
|
||||
assert {:actor, {"can not announce this object", []}} in cng.errors
|
||||
|
||||
# The actor of the object can announce it
|
||||
{:ok, announce, []} = Builder.announce(user, object, public: false)
|
||||
|
||||
assert {:ok, _, _} = ObjectValidator.validate(announce, [])
|
||||
|
||||
# The actor of the object can not announce it publicly
|
||||
{:ok, announce, []} = Builder.announce(user, object, public: true)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(announce, [])
|
||||
|
||||
assert {:actor, {"can not announce this object publicly", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "attachments" do
|
||||
test "works with honkerific attachments" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
"name" => "",
|
||||
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
|
||||
"type" => "Document",
|
||||
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
|
||||
}
|
||||
|
||||
assert {:ok, attachment} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert attachment.mediaType == "application/octet-stream"
|
||||
end
|
||||
|
||||
test "it turns mastodon attachments into our attachments" do
|
||||
attachment = %{
|
||||
"url" =>
|
||||
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
|
||||
"type" => "Document",
|
||||
"name" => nil,
|
||||
"mediaType" => "image/jpeg"
|
||||
}
|
||||
|
||||
{:ok, attachment} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert [
|
||||
%{
|
||||
href:
|
||||
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
|
||||
type: "Link",
|
||||
mediaType: "image/jpeg"
|
||||
}
|
||||
] = attachment.url
|
||||
|
||||
assert attachment.mediaType == "image/jpeg"
|
||||
end
|
||||
|
||||
test "it handles our own uploads" do
|
||||
user = insert(:user)
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
{:ok, attachment} =
|
||||
attachment.data
|
||||
|> AttachmentValidator.cast_and_validate()
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
|
||||
assert attachment.mediaType == "image/jpeg"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.BlockValidationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "blocks" do
|
||||
setup do
|
||||
user = insert(:user, local: false)
|
||||
blocked = insert(:user)
|
||||
|
||||
{:ok, valid_block, []} = Builder.block(user, blocked)
|
||||
|
||||
%{user: user, valid_block: valid_block}
|
||||
end
|
||||
|
||||
test "validates a basic object", %{
|
||||
valid_block: valid_block
|
||||
} do
|
||||
assert {:ok, _block, []} = ObjectValidator.validate(valid_block, [])
|
||||
end
|
||||
|
||||
test "returns an error if we don't know the blocked user", %{
|
||||
valid_block: valid_block
|
||||
} do
|
||||
block =
|
||||
valid_block
|
||||
|> Map.put("object", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
assert {:error, _cng} = ObjectValidator.validate(block, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
211
test/web/activity_pub/object_validators/chat_validation_test.exs
Normal file
211
test/web/activity_pub/object_validators/chat_validation_test.exs
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "chat message create activities" do
|
||||
test "it is invalid if the object already exists" do
|
||||
user = insert(:user)
|
||||
recipient = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
|
||||
object = Object.normalize(activity, false)
|
||||
|
||||
{:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(create_data, [])
|
||||
|
||||
assert {:object, {"The object to create already exists", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is invalid if the object data has a different `to` or `actor` field" do
|
||||
user = insert(:user)
|
||||
recipient = insert(:user)
|
||||
{:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
|
||||
|
||||
{:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(create_data, [])
|
||||
|
||||
assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
|
||||
assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
|
||||
describe "chat messages" do
|
||||
setup do
|
||||
clear_config([:instance, :remote_limit])
|
||||
user = insert(:user)
|
||||
recipient = insert(:user, local: false)
|
||||
|
||||
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
|
||||
|
||||
%{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
|
||||
end
|
||||
|
||||
test "let's through some basic html", %{user: user, recipient: recipient} do
|
||||
{:ok, valid_chat_message, _} =
|
||||
Builder.chat_message(
|
||||
user,
|
||||
recipient.ap_id,
|
||||
"hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
|
||||
)
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["content"] ==
|
||||
"hey <a href=\"https://example.org\">example</a> alert('uguu')"
|
||||
end
|
||||
|
||||
test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert Map.put(valid_chat_message, "attachment", nil) == object
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", attachment.data)
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment in an array", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", [attachment.data])
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "validates for a basic object with an attachment but without content", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user
|
||||
} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("attachment", attachment.data)
|
||||
|> Map.delete("content")
|
||||
|
||||
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
|
||||
|
||||
assert object["attachment"]
|
||||
end
|
||||
|
||||
test "does not validate if the message has no content", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
contentless =
|
||||
valid_chat_message
|
||||
|> Map.delete("content")
|
||||
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
|
||||
end
|
||||
|
||||
test "does not validate if the message is longer than the remote_limit", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
Pleroma.Config.put([:instance, :remote_limit], 2)
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
|
||||
end
|
||||
|
||||
test "does not validate if the recipient is blocking the actor", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user,
|
||||
recipient: recipient
|
||||
} do
|
||||
Pleroma.User.block(recipient, user)
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
|
||||
end
|
||||
|
||||
test "does not validate if the recipient is not accepting chat messages", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
recipient: recipient
|
||||
} do
|
||||
recipient
|
||||
|> Ecto.Changeset.change(%{accepts_chat_messages: false})
|
||||
|> Pleroma.Repo.update!()
|
||||
|
||||
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
|
||||
end
|
||||
|
||||
test "does not validate if the actor or the recipient is not in our system", %{
|
||||
valid_chat_message: valid_chat_message
|
||||
} do
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("actor", "https://raymoo.com/raymoo")
|
||||
|
||||
{:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("to", ["https://raymoo.com/raymoo"])
|
||||
|
||||
{:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
end
|
||||
|
||||
test "does not validate for a message with multiple recipients", %{
|
||||
valid_chat_message: valid_chat_message,
|
||||
user: user,
|
||||
recipient: recipient
|
||||
} do
|
||||
chat_message =
|
||||
valid_chat_message
|
||||
|> Map.put("to", [user.ap_id, recipient.ap_id])
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(chat_message, [])
|
||||
end
|
||||
|
||||
test "does not validate if it doesn't concern local users" do
|
||||
user = insert(:user, local: false)
|
||||
recipient = insert(:user, local: false)
|
||||
|
||||
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
|
||||
assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "deletes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "cancel me daddy"})
|
||||
|
||||
{:ok, valid_post_delete, _} = Builder.delete(user, post_activity.data["object"])
|
||||
{:ok, valid_user_delete, _} = Builder.delete(user, user.ap_id)
|
||||
|
||||
%{user: user, valid_post_delete: valid_post_delete, valid_user_delete: valid_user_delete}
|
||||
end
|
||||
|
||||
test "it is valid for a post deletion", %{valid_post_delete: valid_post_delete} do
|
||||
{:ok, valid_post_delete, _} = ObjectValidator.validate(valid_post_delete, [])
|
||||
|
||||
assert valid_post_delete["deleted_activity_id"]
|
||||
end
|
||||
|
||||
test "it is invalid if the object isn't in a list of certain types", %{
|
||||
valid_post_delete: valid_post_delete
|
||||
} do
|
||||
object = Object.get_by_ap_id(valid_post_delete["object"])
|
||||
|
||||
data =
|
||||
object.data
|
||||
|> Map.put("type", "Like")
|
||||
|
||||
{:ok, _object} =
|
||||
object
|
||||
|> Ecto.Changeset.change(%{data: data})
|
||||
|> Object.update_and_set_cache()
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(valid_post_delete, [])
|
||||
assert {:object, {"object not in allowed types", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is valid for a user deletion", %{valid_user_delete: valid_user_delete} do
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_user_delete, []))
|
||||
end
|
||||
|
||||
test "it's invalid if the id is missing", %{valid_post_delete: valid_post_delete} do
|
||||
no_id =
|
||||
valid_post_delete
|
||||
|> Map.delete("id")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(no_id, [])
|
||||
|
||||
assert {:id, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the object doesn't exist", %{valid_post_delete: valid_post_delete} do
|
||||
missing_object =
|
||||
valid_post_delete
|
||||
|> Map.put("object", "http://does.not/exist")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the actor of the object and the actor of delete are from different domains",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
valid_user = insert(:user)
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", valid_user.ap_id)
|
||||
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_other_actor, []))
|
||||
|
||||
invalid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(invalid_other_actor, [])
|
||||
|
||||
assert {:actor, {"is not allowed to delete object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's valid if the actor of the object is a local superuser",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
user =
|
||||
insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
|
||||
assert meta[:do_not_federate]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactHandlingTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "EmojiReacts" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
object = Pleroma.Object.get_by_ap_id(post_activity.data["object"])
|
||||
|
||||
{:ok, valid_emoji_react, []} = Builder.emoji_react(user, object, "👌")
|
||||
|
||||
%{user: user, post_activity: post_activity, valid_emoji_react: valid_emoji_react}
|
||||
end
|
||||
|
||||
test "it validates a valid EmojiReact", %{valid_emoji_react: valid_emoji_react} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_emoji_react, [])
|
||||
end
|
||||
|
||||
test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_content =
|
||||
valid_emoji_react
|
||||
|> Map.delete("content")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", "x")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:content, {"must be a single character emoji", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.FollowValidationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "Follows" do
|
||||
setup do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
{:ok, valid_follow, []} = Builder.follow(follower, followed)
|
||||
%{follower: follower, followed: followed, valid_follow: valid_follow}
|
||||
end
|
||||
|
||||
test "validates a basic follow object", %{valid_follow: valid_follow} do
|
||||
assert {:ok, _follow, []} = ObjectValidator.validate(valid_follow, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
113
test/web/activity_pub/object_validators/like_validation_test.exs
Normal file
113
test/web/activity_pub/object_validators/like_validation_test.exs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.LikeValidationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "likes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
valid_like = %{
|
||||
"to" => [user.ap_id],
|
||||
"cc" => [],
|
||||
"type" => "Like",
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"object" => post_activity.data["object"],
|
||||
"actor" => user.ap_id,
|
||||
"context" => "a context"
|
||||
}
|
||||
|
||||
%{valid_like: valid_like, user: user, post_activity: post_activity}
|
||||
end
|
||||
|
||||
test "returns ok when called in the ObjectValidator", %{valid_like: valid_like} do
|
||||
{:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
|
||||
|
||||
assert "id" in Map.keys(object)
|
||||
end
|
||||
|
||||
test "is valid for a valid object", %{valid_like: valid_like} do
|
||||
assert LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "sets the 'to' field to the object actor if no recipients are given", %{
|
||||
valid_like: valid_like,
|
||||
user: user
|
||||
} do
|
||||
without_recipients =
|
||||
valid_like
|
||||
|> Map.delete("to")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_recipients, [])
|
||||
|
||||
assert object["to"] == [user.ap_id]
|
||||
end
|
||||
|
||||
test "sets the context field to the context of the object if no context is given", %{
|
||||
valid_like: valid_like,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
without_context =
|
||||
valid_like
|
||||
|> Map.delete("context")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_context, [])
|
||||
|
||||
assert object["context"] == post_activity.data["context"]
|
||||
end
|
||||
|
||||
test "it errors when the actor is missing or not known", %{valid_like: valid_like} do
|
||||
without_actor = Map.delete(valid_like, "actor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_actor).valid?
|
||||
|
||||
with_invalid_actor = Map.put(valid_like, "actor", "invalidactor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_actor).valid?
|
||||
end
|
||||
|
||||
test "it errors when the object is missing or not known", %{valid_like: valid_like} do
|
||||
without_object = Map.delete(valid_like, "object")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_object).valid?
|
||||
|
||||
with_invalid_object = Map.put(valid_like, "object", "invalidobject")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_object).valid?
|
||||
end
|
||||
|
||||
test "it errors when the actor has already like the object", %{
|
||||
valid_like: valid_like,
|
||||
user: user,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
_like = CommonAPI.favorite(user, post_activity.id)
|
||||
|
||||
refute LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "it works when actor or object are wrapped in maps", %{valid_like: valid_like} do
|
||||
wrapped_like =
|
||||
valid_like
|
||||
|> Map.put("actor", %{"id" => valid_like["actor"]})
|
||||
|> Map.put("object", %{"id" => valid_like["object"]})
|
||||
|
||||
validated = LikeValidator.cast_and_validate(wrapped_like)
|
||||
|
||||
assert validated.valid?
|
||||
|
||||
assert {:actor, valid_like["actor"]} in validated.changes
|
||||
assert {:object, valid_like["object"]} in validated.changes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.UndoHandlingTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "Undos" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
{:ok, like} = CommonAPI.favorite(user, post_activity.id)
|
||||
{:ok, valid_like_undo, []} = Builder.undo(user, like)
|
||||
|
||||
%{user: user, like: like, valid_like_undo: valid_like_undo}
|
||||
end
|
||||
|
||||
test "it validates a basic like undo", %{valid_like_undo: valid_like_undo} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_like_undo, [])
|
||||
end
|
||||
|
||||
test "it does not validate if the actor of the undo is not the actor of the object", %{
|
||||
valid_like_undo: valid_like_undo
|
||||
} do
|
||||
other_user = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
bad_actor =
|
||||
valid_like_undo
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(bad_actor, [])
|
||||
|
||||
assert {:actor, {"not the same as object actor", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it does not validate if the object is missing", %{valid_like_undo: valid_like_undo} do
|
||||
missing_object =
|
||||
valid_like_undo
|
||||
|> Map.put("object", "https://gensokyo.2hu/objects/1")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
assert length(cng.errors) == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "updates" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
object = %{
|
||||
"id" => user.ap_id,
|
||||
"name" => "A new name",
|
||||
"summary" => "A new bio"
|
||||
}
|
||||
|
||||
{:ok, valid_update, []} = Builder.update(user, object)
|
||||
|
||||
%{user: user, valid_update: valid_update}
|
||||
end
|
||||
|
||||
test "validates a basic object", %{valid_update: valid_update} do
|
||||
assert {:ok, _update, []} = ObjectValidator.validate(valid_update, [])
|
||||
end
|
||||
|
||||
test "returns an error if the object can't be updated by the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
assert {:error, _cng} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -123,6 +123,39 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
end
|
||||
|
||||
describe "publish_one/1" do
|
||||
test "publish to url with with different ports" do
|
||||
inbox80 = "http://42.site/users/nick1/inbox"
|
||||
inbox42 = "http://42.site:42/users/nick1/inbox"
|
||||
|
||||
mock(fn
|
||||
%{method: :post, url: "http://42.site:42/users/nick1/inbox"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: "port 42"}}
|
||||
|
||||
%{method: :post, url: "http://42.site/users/nick1/inbox"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: "port 80"}}
|
||||
end)
|
||||
|
||||
actor = insert(:user)
|
||||
|
||||
assert {:ok, %{body: "port 42"}} =
|
||||
Publisher.publish_one(%{
|
||||
inbox: inbox42,
|
||||
json: "{}",
|
||||
actor: actor,
|
||||
id: 1,
|
||||
unreachable_since: true
|
||||
})
|
||||
|
||||
assert {:ok, %{body: "port 80"}} =
|
||||
Publisher.publish_one(%{
|
||||
inbox: inbox80,
|
||||
json: "{}",
|
||||
actor: actor,
|
||||
id: 1,
|
||||
unreachable_since: true
|
||||
})
|
||||
end
|
||||
|
||||
test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is not specified",
|
||||
Instances,
|
||||
[:passthrough],
|
||||
|
|
@ -131,7 +164,6 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
inbox = "http://200.site/users/nick1/inbox"
|
||||
|
||||
assert {:ok, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
|
||||
|
||||
assert called(Instances.set_reachable(inbox))
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Relay
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Pleroma.Factory
|
||||
|
|
@ -53,8 +53,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
|
|||
test "returns activity" do
|
||||
user = insert(:user)
|
||||
service_actor = Relay.get_actor()
|
||||
ActivityPub.follow(service_actor, user)
|
||||
Pleroma.User.follow(service_actor, user)
|
||||
CommonAPI.follow(service_actor, user)
|
||||
assert "#{user.ap_id}/followers" in User.following(service_actor)
|
||||
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
|
||||
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
|
||||
|
|
@ -74,6 +73,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
|
|||
assert Relay.publish(activity) == {:error, "Not implemented"}
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "returns error when activity not public" do
|
||||
activity = insert(:direct_note_activity)
|
||||
assert Relay.publish(activity) == {:error, false}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|
|||
|> Poison.decode!()
|
||||
|> Map.put("object", user.ap_id)
|
||||
|
||||
with_mock Pleroma.User, [:passthrough], follow: fn _, _ -> {:error, :testing} end do
|
||||
with_mock Pleroma.User, [:passthrough], follow: fn _, _, _ -> {:error, :testing} end do
|
||||
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
%Activity{} = activity = Activity.get_by_ap_id(id)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -452,7 +451,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
{:ok, follower} = User.follow(follower, followed)
|
||||
assert User.following?(follower, followed) == true
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
accept_data =
|
||||
File.read!("test/fixtures/mastodon-accept-activity.json")
|
||||
|
|
@ -482,7 +481,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
follower = insert(:user)
|
||||
followed = insert(:user, locked: true)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
accept_data =
|
||||
File.read!("test/fixtures/mastodon-accept-activity.json")
|
||||
|
|
@ -504,7 +503,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
follower = insert(:user)
|
||||
followed = insert(:user, locked: true)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
accept_data =
|
||||
File.read!("test/fixtures/mastodon-accept-activity.json")
|
||||
|
|
@ -569,7 +568,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
followed = insert(:user, locked: true)
|
||||
|
||||
{:ok, follower} = User.follow(follower, followed)
|
||||
{:ok, _follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, _follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
assert User.following?(follower, followed) == true
|
||||
|
||||
|
|
@ -595,7 +594,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
followed = insert(:user, locked: true)
|
||||
|
||||
{:ok, follower} = User.follow(follower, followed)
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, followed)
|
||||
|
||||
assert User.following?(follower, followed) == true
|
||||
|
||||
|
|
@ -659,22 +658,44 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
|
||||
)
|
||||
|
||||
attachment = %{
|
||||
"type" => "Link",
|
||||
"mediaType" => "video/mp4",
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
|
||||
"mediaType" => "video/mp4"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
assert object.data["url"] ==
|
||||
"https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3"
|
||||
|
||||
assert object.data["attachment"] == [attachment]
|
||||
assert object.data["attachment"] == [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"mediaType" => "video/mp4",
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
|
||||
"mediaType" => "video/mp4"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
{:ok, object} =
|
||||
Fetcher.fetch_object_from_id(
|
||||
"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
|
||||
)
|
||||
|
||||
assert object.data["attachment"] == [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"mediaType" => "video/mp4",
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://framatube.org/static/webseed/6050732a-8a7a-43d4-a6cd-809525a1d206-1080.mp4",
|
||||
"mediaType" => "video/mp4"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
assert object.data["url"] ==
|
||||
"https://framatube.org/videos/watch/6050732a-8a7a-43d4-a6cd-809525a1d206"
|
||||
end
|
||||
|
||||
test "it accepts Flag activities" do
|
||||
|
|
@ -753,6 +774,29 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert [user.follower_address] == activity.data["to"]
|
||||
end
|
||||
|
||||
test "it correctly processes messages with weirdness in address fields" do
|
||||
user = insert(:user)
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"to" => [nil, user.follower_address],
|
||||
"cc" => ["https://www.w3.org/ns/activitystreams#Public", ["¿"]],
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "…",
|
||||
"type" => "Note",
|
||||
"attributedTo" => user.ap_id,
|
||||
"inReplyTo" => nil
|
||||
},
|
||||
"actor" => user.ap_id
|
||||
}
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
|
||||
|
||||
assert ["https://www.w3.org/ns/activitystreams#Public"] == activity.data["cc"]
|
||||
assert [user.follower_address] == activity.data["to"]
|
||||
end
|
||||
|
||||
test "it accepts Move activities" do
|
||||
old_user = insert(:user)
|
||||
new_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.AdminAPI.AccountView
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -197,8 +196,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
user = insert(:user, locked: true)
|
||||
follower = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_two} = ActivityPub.follow(follower, user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
|
||||
|
||||
data =
|
||||
follow_activity_two.data
|
||||
|
|
@ -221,8 +220,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
user = insert(:user, locked: true)
|
||||
follower = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_two} = ActivityPub.follow(follower, user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
|
||||
|
||||
data =
|
||||
follow_activity_two.data
|
||||
|
|
|
|||
|
|
@ -158,4 +158,23 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
|
||||
end
|
||||
end
|
||||
|
||||
describe "acceptsChatMessages" do
|
||||
test "it returns this value if it is set" do
|
||||
true_user = insert(:user, accepts_chat_messages: true)
|
||||
false_user = insert(:user, accepts_chat_messages: false)
|
||||
nil_user = insert(:user, accepts_chat_messages: nil)
|
||||
|
||||
assert %{"capabilities" => %{"acceptsChatMessages" => true}} =
|
||||
UserView.render("user.json", user: true_user)
|
||||
|
||||
assert %{"capabilities" => %{"acceptsChatMessages" => false}} =
|
||||
UserView.render("user.json", user: false_user)
|
||||
|
||||
refute Map.has_key?(
|
||||
UserView.render("user.json", user: nil_user)["capabilities"],
|
||||
"acceptsChatMessages"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41,6 +41,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
{:ok, %{admin: admin, token: token, conn: conn}}
|
||||
end
|
||||
|
||||
test "with valid `admin_token` query parameter, skips OAuth scopes check" do
|
||||
clear_config([:admin_token], "password123")
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
conn = get(build_conn(), "/api/pleroma/admin/users/#{user.nickname}?admin_token=password123")
|
||||
|
||||
assert json_response(conn, 200)
|
||||
end
|
||||
|
||||
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
|
||||
setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], true)
|
||||
|
||||
|
|
@ -1514,6 +1524,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "gets a remote users when [:instance, :limit_to_local_content] is set to :unauthenticated",
|
||||
%{conn: conn} do
|
||||
clear_config(Pleroma.Config.get([:instance, :limit_to_local_content]), :unauthenticated)
|
||||
user = insert(:user, %{local: false, nickname: "u@peer1.com"})
|
||||
conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials")
|
||||
|
||||
assert json_response(conn, 200)
|
||||
end
|
||||
|
||||
describe "GET /users/:nickname/credentials" do
|
||||
test "gets the user credentials", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -152,6 +152,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
assert emoji_val[:groups] == [a: 1, b: 2]
|
||||
assert assets_val[:mascots] == [a: 1, b: 2]
|
||||
end
|
||||
|
||||
test "with valid `admin_token` query parameter, skips OAuth scopes check" do
|
||||
clear_config([:admin_token], "password123")
|
||||
|
||||
build_conn()
|
||||
|> get("/api/pleroma/admin/config?admin_token=password123")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /api/pleroma/admin/config error", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
|> get("/api/pleroma/admin/reports")
|
||||
|
||||
assert json_response(conn, :forbidden) ==
|
||||
%{"error" => "User is not an admin or OAuth admin scope is not granted."}
|
||||
%{"error" => "User is not an admin."}
|
||||
end
|
||||
|
||||
test "returns 403 when requested by anonymous" do
|
||||
|
|
|
|||
|
|
@ -491,6 +491,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
|
||||
assert object.data["source"] == post
|
||||
end
|
||||
|
||||
test "it filters out obviously bad tags when accepting a post as Markdown" do
|
||||
|
|
@ -507,6 +508,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
|
||||
assert object.data["source"] == post
|
||||
end
|
||||
|
||||
test "it does not allow replies to direct messages that are not direct messages themselves" do
|
||||
|
|
@ -932,6 +934,15 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "follow/2" do
|
||||
test "directly follows a non-locked local user" do
|
||||
[follower, followed] = insert_pair(:user)
|
||||
{:ok, follower, followed, _} = CommonAPI.follow(follower, followed)
|
||||
|
||||
assert User.following?(follower, followed)
|
||||
end
|
||||
end
|
||||
|
||||
describe "unfollow/2" do
|
||||
test "also unsubscribes a user" do
|
||||
[follower, followed] = insert_pair(:user)
|
||||
|
|
@ -996,9 +1007,9 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
follower = insert(:user)
|
||||
follower_two = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_two} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_three} = ActivityPub.follow(follower_two, user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
|
||||
|
||||
assert follow_activity.data["state"] == "pending"
|
||||
assert follow_activity_two.data["state"] == "pending"
|
||||
|
|
@ -1016,9 +1027,9 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
follower = insert(:user)
|
||||
follower_two = insert(:user)
|
||||
|
||||
{:ok, follow_activity} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_two} = ActivityPub.follow(follower, user)
|
||||
{:ok, follow_activity_three} = ActivityPub.follow(follower_two, user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_two} = CommonAPI.follow(follower, user)
|
||||
{:ok, _, _, follow_activity_three} = CommonAPI.follow(follower_two, user)
|
||||
|
||||
assert follow_activity.data["state"] == "pending"
|
||||
assert follow_activity_two.data["state"] == "pending"
|
||||
|
|
|
|||
|
|
@ -108,6 +108,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
assert user_data["locked"] == true
|
||||
end
|
||||
|
||||
test "updates the user's chat acceptance status", %{conn: conn} do
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{accepts_chat_messages: "false"})
|
||||
|
||||
assert user_data = json_response_and_validate_schema(conn, 200)
|
||||
assert user_data["pleroma"]["accepts_chat_messages"] == false
|
||||
end
|
||||
|
||||
test "updates the user's allow_following_move", %{user: user, conn: conn} do
|
||||
assert user.allow_following_move == true
|
||||
|
||||
|
|
@ -216,10 +223,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
|
||||
assert user.avatar == %{}
|
||||
|
||||
assert user_response = json_response_and_validate_schema(conn, 200)
|
||||
res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 200)
|
||||
assert user_response["avatar"] != User.avatar_url(user)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
refute user.avatar == %{}
|
||||
|
||||
# Also resets it
|
||||
_res = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => ""})
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.avatar == nil
|
||||
end
|
||||
|
||||
test "updates the user's banner", %{user: user, conn: conn} do
|
||||
|
|
@ -229,26 +247,39 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
|
||||
res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(conn, 200)
|
||||
assert user_response = json_response_and_validate_schema(res, 200)
|
||||
assert user_response["header"] != User.banner_url(user)
|
||||
|
||||
# Also resets it
|
||||
_res = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => ""})
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.banner == nil
|
||||
end
|
||||
|
||||
test "updates the user's background", %{conn: conn} do
|
||||
test "updates the user's background", %{conn: conn, user: user} do
|
||||
new_header = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
conn =
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"pleroma_background_image" => new_header
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(conn, 200)
|
||||
assert user_response = json_response_and_validate_schema(res, 200)
|
||||
assert user_response["pleroma"]["background_image"]
|
||||
#
|
||||
# Also resets it
|
||||
_res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{"pleroma_background_image" => ""})
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.background == nil
|
||||
end
|
||||
|
||||
test "requires 'write:accounts' permission" do
|
||||
|
|
@ -320,6 +351,30 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|
|||
]
|
||||
end
|
||||
|
||||
test "emojis in fields labels", %{conn: conn} do
|
||||
fields = [
|
||||
%{"name" => ":firefox:", "value" => "is best 2hu"},
|
||||
%{"name" => "they wins", "value" => ":blank:"}
|
||||
]
|
||||
|
||||
account_data =
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert account_data["fields"] == [
|
||||
%{"name" => ":firefox:", "value" => "is best 2hu"},
|
||||
%{"name" => "they wins", "value" => ":blank:"}
|
||||
]
|
||||
|
||||
assert account_data["source"]["fields"] == [
|
||||
%{"name" => ":firefox:", "value" => "is best 2hu"},
|
||||
%{"name" => "they wins", "value" => ":blank:"}
|
||||
]
|
||||
|
||||
assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = account_data["emojis"]
|
||||
end
|
||||
|
||||
test "update fields via x-www-form-urlencoded", %{conn: conn} do
|
||||
fields =
|
||||
[
|
||||
|
|
|
|||
|
|
@ -583,6 +583,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3_id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] =
|
||||
conn
|
||||
|> get(
|
||||
"/api/v1/accounts/#{user.id}/followers?id=#{user.id}&limit=20&max_id=#{
|
||||
follower3_id
|
||||
}"
|
||||
)
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3_id}")
|
||||
|
||||
assert [%{"id" => ^follower2_id}] = json_response_and_validate_schema(res_conn, 200)
|
||||
|
|
@ -654,6 +663,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert id2 == following2.id
|
||||
assert id1 == following1.id
|
||||
|
||||
res_conn =
|
||||
get(
|
||||
conn,
|
||||
"/api/v1/accounts/#{user.id}/following?id=#{user.id}&limit=20&max_id=#{following3.id}"
|
||||
)
|
||||
|
||||
assert [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200)
|
||||
assert id2 == following2.id
|
||||
assert id1 == following1.id
|
||||
|
||||
res_conn =
|
||||
get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
|
||||
|
||||
|
|
@ -708,7 +727,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
followed = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false")
|
||||
ret_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
|
||||
|
||||
assert %{"showing_reblogs" => false} = json_response_and_validate_schema(ret_conn, 200)
|
||||
|
||||
|
|
@ -722,7 +744,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|
||||
assert %{"showing_reblogs" => true} =
|
||||
conn
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^reblog_id}] =
|
||||
|
|
@ -731,6 +754,35 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> json_response(200)
|
||||
end
|
||||
|
||||
test "following with reblogs" do
|
||||
%{conn: conn} = oauth_access(["follow", "read:statuses"])
|
||||
followed = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow")
|
||||
|
||||
assert %{"showing_reblogs" => true} = json_response_and_validate_schema(ret_conn, 200)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
|
||||
{:ok, %{id: reblog_id}} = CommonAPI.repeat(activity.id, followed)
|
||||
|
||||
assert [%{"id" => ^reblog_id}] =
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|> json_response(200)
|
||||
|
||||
assert %{"showing_reblogs" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] ==
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|> json_response(200)
|
||||
end
|
||||
|
||||
test "following / unfollowing errors", %{user: user, conn: conn} do
|
||||
# self follow
|
||||
conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
|
||||
|
|
@ -904,7 +956,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
%{
|
||||
"access_token" => token,
|
||||
"created_at" => _created_at,
|
||||
"scope" => _scope,
|
||||
"scope" => ^scope,
|
||||
"token_type" => "Bearer"
|
||||
} = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
|
|
@ -1066,7 +1118,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{
|
||||
"access_token" => access_token,
|
||||
"created_at" => _,
|
||||
"scope" => ["read", "write", "follow", "push"],
|
||||
"scope" => "read write follow push",
|
||||
"token_type" => "Bearer"
|
||||
} = response
|
||||
|
||||
|
|
@ -1184,7 +1236,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{
|
||||
"access_token" => access_token,
|
||||
"created_at" => _,
|
||||
"scope" => ["read"],
|
||||
"scope" => "read",
|
||||
"token_type" => "Bearer"
|
||||
} =
|
||||
conn
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
|
|||
test "/api/v1/follow_requests works", %{user: user, conn: conn} do
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
|
||||
{:ok, other_user} = User.follow(other_user, user, :follow_pending)
|
||||
|
||||
assert User.following?(other_user, user) == false
|
||||
|
|
@ -34,7 +34,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
|
|||
test "/api/v1/follow_requests/:id/authorize works", %{user: user, conn: conn} do
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
|
||||
{:ok, other_user} = User.follow(other_user, user, :follow_pending)
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
|
|||
test "/api/v1/follow_requests/:id/reject works", %{user: user, conn: conn} do
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = ActivityPub.follow(other_user, user)
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,11 +32,15 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|
|||
"avatar_upload_limit" => _,
|
||||
"background_upload_limit" => _,
|
||||
"banner_upload_limit" => _,
|
||||
"background_image" => _
|
||||
"background_image" => _,
|
||||
"chat_limit" => _,
|
||||
"description_limit" => _
|
||||
} = result
|
||||
|
||||
assert result["pleroma"]["metadata"]["account_activation_required"] != nil
|
||||
assert result["pleroma"]["metadata"]["features"]
|
||||
assert result["pleroma"]["metadata"]["federation"]
|
||||
assert result["pleroma"]["metadata"]["fields_limits"]
|
||||
assert result["pleroma"]["vapid_public_key"]
|
||||
|
||||
assert email == from_config_email
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
assert status["id"] == to_string(activity.id)
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "constructs hashtags from search query", %{conn: conn} do
|
||||
results =
|
||||
conn
|
||||
|
|
@ -318,11 +319,13 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
test "search fetches remote accounts", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
query = URI.encode_query(%{q: " mike@osada.macgirvin.com ", resolve: true})
|
||||
|
||||
results =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
|
||||
|> get("/api/v1/search?q=mike@osada.macgirvin.com&resolve=true")
|
||||
|> get("/api/v1/search?#{query}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
[account] = results["accounts"]
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
setup do: clear_config([:instance, :federating])
|
||||
setup do: clear_config([:instance, :allow_relay])
|
||||
setup do: clear_config([:rich_media, :enabled])
|
||||
setup do: clear_config([:mrf, :policies])
|
||||
setup do: clear_config([:mrf_keyword, :reject])
|
||||
|
||||
describe "posting statuses" do
|
||||
setup do: oauth_access(["write:statuses"])
|
||||
|
|
@ -157,6 +159,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> json_response_and_validate_schema(422)
|
||||
end
|
||||
|
||||
test "Get MRF reason when posting a status is rejected by one", %{conn: conn} do
|
||||
Pleroma.Config.put([:mrf_keyword, :reject], ["GNO"])
|
||||
Pleroma.Config.put([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||
|
||||
assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{"status" => "GNO/Linux"})
|
||||
|> json_response_and_validate_schema(422)
|
||||
end
|
||||
|
||||
test "posting an undefined status with an attachment", %{user: user, conn: conn} do
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
|
|
@ -760,13 +773,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
test "when you created it" do
|
||||
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
||||
activity = insert(:note_activity, user: author)
|
||||
object = Object.normalize(activity)
|
||||
|
||||
conn =
|
||||
content = object.data["content"]
|
||||
source = object.data["source"]
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, author)
|
||||
|> delete("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{} = json_response_and_validate_schema(conn, 200)
|
||||
assert match?(%{"content" => ^content, "text" => ^source}, result)
|
||||
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
|
|
@ -789,7 +807,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
conn = delete(conn, "/api/v1/statuses/#{activity.id}")
|
||||
|
||||
assert %{"error" => _} = json_response_and_validate_schema(conn, 403)
|
||||
assert %{"error" => "Record not found"} == json_response_and_validate_schema(conn, 404)
|
||||
|
||||
assert Activity.get_by_id(activity.id) == activity
|
||||
end
|
||||
|
|
|
|||
|
|
@ -418,4 +418,78 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
assert [status_none] == json_response_and_validate_schema(all_test, :ok)
|
||||
end
|
||||
end
|
||||
|
||||
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"})
|
||||
{:ok, _activity2} = CommonAPI.post(user, %{status: "test #tag1"})
|
||||
|
||||
activity1
|
||||
|> Ecto.Changeset.change(%{local: false})
|
||||
|> Pleroma.Repo.update()
|
||||
|
||||
base_uri = "/api/v1/timelines/tag/tag1"
|
||||
error_response = %{"error" => "authorization required for timeline view"}
|
||||
|
||||
%{base_uri: base_uri, error_response: error_response}
|
||||
end
|
||||
|
||||
defp ensure_authenticated_access(base_uri) do
|
||||
%{conn: auth_conn} = oauth_access(["read:statuses"])
|
||||
|
||||
res_conn = get(auth_conn, "#{base_uri}?local=true")
|
||||
assert length(json_response(res_conn, 200)) == 1
|
||||
|
||||
res_conn = get(auth_conn, "#{base_uri}?local=false")
|
||||
assert length(json_response(res_conn, 200)) == 2
|
||||
end
|
||||
|
||||
test "with `%{local: true, federated: true}`, returns 403 for unauthenticated users", %{
|
||||
conn: conn,
|
||||
base_uri: base_uri,
|
||||
error_response: error_response
|
||||
} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
for local <- [true, false] do
|
||||
res_conn = get(conn, "#{base_uri}?local=#{local}")
|
||||
|
||||
assert json_response(res_conn, :unauthorized) == error_response
|
||||
end
|
||||
|
||||
ensure_authenticated_access(base_uri)
|
||||
end
|
||||
|
||||
test "with `%{local: false, federated: true}`, forbids unauthenticated access to federated timeline",
|
||||
%{conn: conn, base_uri: base_uri, error_response: error_response} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], false)
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], true)
|
||||
|
||||
res_conn = get(conn, "#{base_uri}?local=true")
|
||||
assert length(json_response(res_conn, 200)) == 1
|
||||
|
||||
res_conn = get(conn, "#{base_uri}?local=false")
|
||||
assert json_response(res_conn, :unauthorized) == error_response
|
||||
|
||||
ensure_authenticated_access(base_uri)
|
||||
end
|
||||
|
||||
test "with `%{local: true, federated: false}`, forbids unauthenticated access to public timeline" <>
|
||||
"(but not to local public activities which are delivered as part of federated timeline)",
|
||||
%{conn: conn, base_uri: base_uri, error_response: error_response} do
|
||||
clear_config([:restrict_unauthenticated, :timelines, :local], true)
|
||||
clear_config([:restrict_unauthenticated, :timelines, :federated], false)
|
||||
|
||||
res_conn = get(conn, "#{base_uri}?local=true")
|
||||
assert json_response(res_conn, :unauthorized) == error_response
|
||||
|
||||
# Note: local activities get delivered as part of federated timeline
|
||||
res_conn = get(conn, "#{base_uri}?local=false")
|
||||
assert length(json_response(res_conn, 200)) == 2
|
||||
|
||||
ensure_authenticated_access(base_uri)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
|
|||
follower = insert(:user)
|
||||
user = insert(:user, local: true, deactivated: true)
|
||||
{:error, error} = MastodonAPI.follow(follower, user)
|
||||
assert error == "Could not follow user: #{user.nickname} is deactivated."
|
||||
assert error == :rejected
|
||||
end
|
||||
|
||||
test "following for user" do
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -18,6 +19,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
:ok
|
||||
end
|
||||
|
||||
setup do: clear_config([:instances_favicons, :enabled])
|
||||
|
||||
test "Represent a user account" do
|
||||
background_image = %{
|
||||
"url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
|
||||
|
|
@ -75,6 +78,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
pleroma: %{
|
||||
ap_id: user.ap_id,
|
||||
background_image: "https://example.com/images/asuka_hospital.png",
|
||||
favicon:
|
||||
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
|
||||
confirmation_pending: false,
|
||||
tags: [],
|
||||
is_admin: false,
|
||||
|
|
@ -85,22 +90,37 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
hide_followers_count: false,
|
||||
hide_follows_count: false,
|
||||
relationship: %{},
|
||||
skip_thread_containment: false
|
||||
skip_thread_containment: false,
|
||||
accepts_chat_messages: nil
|
||||
}
|
||||
}
|
||||
|
||||
assert expected == AccountView.render("show.json", %{user: user})
|
||||
end
|
||||
|
||||
test "Favicon is nil when :instances_favicons is disabled" do
|
||||
user = insert(:user)
|
||||
|
||||
Config.put([:instances_favicons, :enabled], true)
|
||||
|
||||
assert %{
|
||||
pleroma: %{
|
||||
favicon:
|
||||
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png"
|
||||
}
|
||||
} = AccountView.render("show.json", %{user: user})
|
||||
|
||||
Config.put([:instances_favicons, :enabled], false)
|
||||
|
||||
assert %{pleroma: %{favicon: nil}} = AccountView.render("show.json", %{user: user})
|
||||
end
|
||||
|
||||
test "Represent the user account for the account owner" do
|
||||
user = insert(:user)
|
||||
|
||||
notification_settings = %{
|
||||
followers: true,
|
||||
follows: true,
|
||||
non_followers: true,
|
||||
non_follows: true,
|
||||
privacy_option: false
|
||||
block_from_strangers: false,
|
||||
hide_notification_contents: false
|
||||
}
|
||||
|
||||
privacy = user.default_scope
|
||||
|
|
@ -152,6 +172,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
pleroma: %{
|
||||
ap_id: user.ap_id,
|
||||
background_image: nil,
|
||||
favicon:
|
||||
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
|
||||
confirmation_pending: false,
|
||||
tags: [],
|
||||
is_admin: false,
|
||||
|
|
@ -162,7 +184,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
hide_followers_count: false,
|
||||
hide_follows_count: false,
|
||||
relationship: %{},
|
||||
skip_thread_containment: false
|
||||
skip_thread_containment: false,
|
||||
accepts_chat_messages: nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,6 +395,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
user = insert(:user, hide_followers: true, hide_follows: true)
|
||||
other_user = insert(:user)
|
||||
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
|
||||
|
||||
assert User.following?(user, other_user)
|
||||
assert Pleroma.FollowingRelationship.follower_count(other_user) == 1
|
||||
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
assert %{
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
card: nil,
|
||||
reblog: nil,
|
||||
content: HTML.filter_tags(object_data["content"]),
|
||||
text: nil,
|
||||
created_at: created_at,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
|
|
|
|||
|
|
@ -4,82 +4,118 @@
|
|||
|
||||
defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
import Mock
|
||||
alias Pleroma.Config
|
||||
|
||||
setup do: clear_config(:media_proxy)
|
||||
setup do: clear_config([Pleroma.Web.Endpoint, :secret_key_base])
|
||||
import Mock
|
||||
|
||||
alias Pleroma.Web.MediaProxy
|
||||
alias Pleroma.Web.MediaProxy.MediaProxyController
|
||||
alias Plug.Conn
|
||||
|
||||
setup do
|
||||
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
|
||||
end
|
||||
|
||||
test "it returns 404 when MediaProxy disabled", %{conn: conn} do
|
||||
Config.put([:media_proxy, :enabled], false)
|
||||
clear_config([:media_proxy, :enabled], false)
|
||||
|
||||
assert %Plug.Conn{
|
||||
assert %Conn{
|
||||
status: 404,
|
||||
resp_body: "Not Found"
|
||||
} = get(conn, "/proxy/hhgfh/eeeee")
|
||||
|
||||
assert %Plug.Conn{
|
||||
assert %Conn{
|
||||
status: 404,
|
||||
resp_body: "Not Found"
|
||||
} = get(conn, "/proxy/hhgfh/eeee/fff")
|
||||
end
|
||||
|
||||
test "it returns 403 when signature invalidated", %{conn: conn} do
|
||||
Config.put([:media_proxy, :enabled], true)
|
||||
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
|
||||
path = URI.parse(Pleroma.Web.MediaProxy.encode_url("https://google.fn")).path
|
||||
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
|
||||
describe "" do
|
||||
setup do
|
||||
clear_config([:media_proxy, :enabled], true)
|
||||
clear_config([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
|
||||
[url: MediaProxy.encode_url("https://google.fn/test.png")]
|
||||
end
|
||||
|
||||
assert %Plug.Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, path)
|
||||
test "it returns 403 for invalid signature", %{conn: conn, url: url} do
|
||||
Pleroma.Config.put([Pleroma.Web.Endpoint, :secret_key_base], "000")
|
||||
%{path: path} = URI.parse(url)
|
||||
|
||||
assert %Plug.Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, "/proxy/hhgfh/eeee")
|
||||
assert %Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, path)
|
||||
|
||||
assert %Plug.Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, "/proxy/hhgfh/eeee/fff")
|
||||
end
|
||||
assert %Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, "/proxy/hhgfh/eeee")
|
||||
|
||||
test "redirects on valid url when filename invalidated", %{conn: conn} do
|
||||
Config.put([:media_proxy, :enabled], true)
|
||||
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
|
||||
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
|
||||
invalid_url = String.replace(url, "test.png", "test-file.png")
|
||||
response = get(conn, invalid_url)
|
||||
assert response.status == 302
|
||||
assert redirected_to(response) == url
|
||||
end
|
||||
assert %Conn{
|
||||
status: 403,
|
||||
resp_body: "Forbidden"
|
||||
} = get(conn, "/proxy/hhgfh/eeee/fff")
|
||||
end
|
||||
|
||||
test "it performs ReverseProxy.call when signature valid", %{conn: conn} do
|
||||
Config.put([:media_proxy, :enabled], true)
|
||||
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
|
||||
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
|
||||
test "redirects on valid url when filename is invalidated", %{conn: conn, url: url} do
|
||||
invalid_url = String.replace(url, "test.png", "test-file.png")
|
||||
response = get(conn, invalid_url)
|
||||
assert response.status == 302
|
||||
assert redirected_to(response) == url
|
||||
end
|
||||
|
||||
with_mock Pleroma.ReverseProxy,
|
||||
call: fn _conn, _url, _opts -> %Plug.Conn{status: :success} end do
|
||||
assert %Plug.Conn{status: :success} = get(conn, url)
|
||||
test "it performs ReverseProxy.call with valid signature", %{conn: conn, url: url} do
|
||||
with_mock Pleroma.ReverseProxy,
|
||||
call: fn _conn, _url, _opts -> %Conn{status: :success} end do
|
||||
assert %Conn{status: :success} = get(conn, url)
|
||||
end
|
||||
end
|
||||
|
||||
test "it returns 404 when url is in banned_urls cache", %{conn: conn, url: url} do
|
||||
MediaProxy.put_in_banned_urls("https://google.fn/test.png")
|
||||
|
||||
with_mock Pleroma.ReverseProxy,
|
||||
call: fn _conn, _url, _opts -> %Conn{status: :success} end do
|
||||
assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "it returns 404 when url contains in banned_urls cache", %{conn: conn} do
|
||||
Config.put([:media_proxy, :enabled], true)
|
||||
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
|
||||
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
|
||||
Pleroma.Web.MediaProxy.put_in_banned_urls("https://google.fn/test.png")
|
||||
describe "filename_matches/3" do
|
||||
test "preserves the encoded or decoded path" do
|
||||
assert MediaProxyController.filename_matches(
|
||||
%{"filename" => "/Hello world.jpg"},
|
||||
"/Hello world.jpg",
|
||||
"http://pleroma.social/Hello world.jpg"
|
||||
) == :ok
|
||||
|
||||
with_mock Pleroma.ReverseProxy,
|
||||
call: fn _conn, _url, _opts -> %Plug.Conn{status: :success} end do
|
||||
assert %Plug.Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
|
||||
assert MediaProxyController.filename_matches(
|
||||
%{"filename" => "/Hello%20world.jpg"},
|
||||
"/Hello%20world.jpg",
|
||||
"http://pleroma.social/Hello%20world.jpg"
|
||||
) == :ok
|
||||
|
||||
assert MediaProxyController.filename_matches(
|
||||
%{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"},
|
||||
"/my%2Flong%2Furl%2F2019%2F07%2FS.jpg",
|
||||
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
|
||||
) == :ok
|
||||
|
||||
assert MediaProxyController.filename_matches(
|
||||
%{"filename" => "/my%2Flong%2Furl%2F2019%2F07%2FS.jp"},
|
||||
"/my%2Flong%2Furl%2F2019%2F07%2FS.jp",
|
||||
"http://pleroma.social/my%2Flong%2Furl%2F2019%2F07%2FS.jpg"
|
||||
) == {:wrong_filename, "my%2Flong%2Furl%2F2019%2F07%2FS.jpg"}
|
||||
end
|
||||
|
||||
test "encoded url are tried to match for proxy as `conn.request_path` encodes the url" do
|
||||
# conn.request_path will return encoded url
|
||||
request_path = "/ANALYSE-DAI-_-LE-STABLECOIN-100-D%C3%89CENTRALIS%C3%89-BQ.jpg"
|
||||
|
||||
assert MediaProxyController.filename_matches(
|
||||
true,
|
||||
request_path,
|
||||
"https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg"
|
||||
) == :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -71,12 +71,9 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
end
|
||||
|
||||
test "validates signature" do
|
||||
secret_key_base = Config.get([Endpoint, :secret_key_base])
|
||||
clear_config([Endpoint, :secret_key_base], secret_key_base)
|
||||
|
||||
encoded = MediaProxy.url("https://pleroma.social")
|
||||
|
||||
Config.put(
|
||||
clear_config(
|
||||
[Endpoint, :secret_key_base],
|
||||
"00000000000000000000000000000000000000000000000"
|
||||
)
|
||||
|
|
@ -144,15 +141,17 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
request_path,
|
||||
"https://mydomain.com/uploads/2019/07/ANALYSE-DAI-_-LE-STABLECOIN-100-DÉCENTRALISÉ-BQ.jpg"
|
||||
) == :ok
|
||||
assert MediaProxy.decode_url(sig, base64) == {:error, :invalid_signature}
|
||||
end
|
||||
|
||||
test "uses the configured base_url" do
|
||||
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
|
||||
base_url = "https://cache.pleroma.social"
|
||||
clear_config([:media_proxy, :base_url], base_url)
|
||||
|
||||
url = "https://pleroma.soykaf.com/static/logo.png"
|
||||
encoded = MediaProxy.url(url)
|
||||
|
||||
assert String.starts_with?(encoded, Config.get([:media_proxy, :base_url]))
|
||||
assert String.starts_with?(encoded, base_url)
|
||||
end
|
||||
|
||||
# Some sites expect ASCII encoded characters in the URL to be preserved even if
|
||||
|
|
@ -194,10 +193,25 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
end
|
||||
end
|
||||
|
||||
defp decode_result(encoded) do
|
||||
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
|
||||
{:ok, decoded} = MediaProxy.decode_url(sig, base64)
|
||||
decoded
|
||||
end
|
||||
|
||||
describe "whitelist" do
|
||||
setup do: clear_config([:media_proxy, :enabled], true)
|
||||
|
||||
test "mediaproxy whitelist" do
|
||||
clear_config([:media_proxy, :whitelist], ["https://google.com", "https://feld.me"])
|
||||
url = "https://feld.me/foo.png"
|
||||
|
||||
unencoded = MediaProxy.url(url)
|
||||
assert unencoded == url
|
||||
end
|
||||
|
||||
# TODO: delete after removing support bare domains for media proxy whitelist
|
||||
test "mediaproxy whitelist bare domains whitelist (deprecated)" do
|
||||
clear_config([:media_proxy, :whitelist], ["google.com", "feld.me"])
|
||||
url = "https://feld.me/foo.png"
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
|
|||
import Pleroma.Factory
|
||||
import Swoosh.TestAssertions
|
||||
|
||||
@image "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
|
||||
|
||||
describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
|
||||
setup do
|
||||
{:ok, user} =
|
||||
|
|
@ -68,103 +66,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "PATCH /api/v1/pleroma/accounts/update_avatar" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "user avatar can be set", %{user: user, conn: conn} do
|
||||
avatar_image = File.read!("test/fixtures/avatar_data_uri")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image})
|
||||
|
||||
user = refresh_record(user)
|
||||
|
||||
assert %{
|
||||
"name" => _,
|
||||
"type" => _,
|
||||
"url" => [
|
||||
%{
|
||||
"href" => _,
|
||||
"mediaType" => _,
|
||||
"type" => _
|
||||
}
|
||||
]
|
||||
} = user.avatar
|
||||
|
||||
assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "user avatar can be reset", %{user: user, conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_avatar", %{img: ""})
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
|
||||
assert user.avatar == nil
|
||||
|
||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH /api/v1/pleroma/accounts/update_banner" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "can set profile banner", %{user: user, conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => @image})
|
||||
|
||||
user = refresh_record(user)
|
||||
assert user.banner["type"] == "Image"
|
||||
|
||||
assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "can reset profile banner", %{user: user, conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => ""})
|
||||
|
||||
user = refresh_record(user)
|
||||
assert user.banner == %{}
|
||||
|
||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "PATCH /api/v1/pleroma/accounts/update_background" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "background image can be set", %{user: user, conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_background", %{"img" => @image})
|
||||
|
||||
user = refresh_record(user)
|
||||
assert user.background["type"] == "Image"
|
||||
# assert %{"url" => _} = json_response(conn, 200)
|
||||
assert %{"url" => _} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "background image can be reset", %{user: user, conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> patch("/api/v1/pleroma/accounts/update_background", %{"img" => ""})
|
||||
|
||||
user = refresh_record(user)
|
||||
assert user.background == %{}
|
||||
assert %{"url" => nil} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting favorites timeline of specified user" do
|
||||
setup do
|
||||
[current_user, user] = insert_pair(:user, hide_favorites: false)
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Preload.Providers.StatusNetTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Web.Preload.Providers.StatusNet
|
||||
|
||||
setup do: {:ok, StatusNet.generate_terms(nil)}
|
||||
|
||||
test "it renders the info", %{"/api/statusnet/config.json" => info} do
|
||||
assert {:ok, res} = Jason.decode(info)
|
||||
assert res["site"]
|
||||
end
|
||||
end
|
||||
|
|
@ -238,9 +238,11 @@ defmodule Pleroma.Web.Push.ImplTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "hides details for notifications when privacy option enabled" do
|
||||
test "hides contents of notifications when option enabled" do
|
||||
user = insert(:user, nickname: "Bob")
|
||||
user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: true})
|
||||
|
||||
user2 =
|
||||
insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: true})
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
|
|
@ -284,9 +286,11 @@ defmodule Pleroma.Web.Push.ImplTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "returns regular content for notifications with privacy option disabled" do
|
||||
test "returns regular content when hiding contents option disabled" do
|
||||
user = insert(:user, nickname: "Bob")
|
||||
user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: false})
|
||||
|
||||
user2 =
|
||||
insert(:user, nickname: "Rob", notification_settings: %{hide_notification_contents: false})
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
|
|
|
|||
|
|
@ -87,6 +87,20 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do
|
|||
assert html =~ "testing a thing!"
|
||||
end
|
||||
|
||||
test "redirects to json if requested", %{conn: conn, user: user} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "testing a thing!"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header(
|
||||
"accept",
|
||||
"Accept: application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\", text/html"
|
||||
)
|
||||
|> get("/notice/#{activity.id}")
|
||||
|
||||
assert redirected_to(conn, 302) =~ activity.data["object"]
|
||||
end
|
||||
|
||||
test "filters HTML tags", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "<script>alert('xss')</script>"})
|
||||
|
|
|
|||
|
|
@ -128,6 +128,23 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert Streamer.filtered_by_user?(user, announce)
|
||||
end
|
||||
|
||||
test "it does stream notifications announces of the user's own posts in the 'user' stream", %{
|
||||
user: user
|
||||
} do
|
||||
Streamer.get_topic_and_add_socket("user", user)
|
||||
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, announce} = CommonAPI.repeat(activity.id, other_user)
|
||||
|
||||
notification =
|
||||
Pleroma.Notification
|
||||
|> Repo.get_by(%{user_id: user.id, activity_id: announce.id})
|
||||
|> Repo.preload(:activity)
|
||||
|
||||
refute Streamer.filtered_by_user?(user, notification)
|
||||
end
|
||||
|
||||
test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do
|
||||
Streamer.get_topic_and_add_socket("user", user)
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
test "it updates notification settings", %{user: user, conn: conn} do
|
||||
conn
|
||||
|> put("/api/pleroma/notification_settings", %{
|
||||
"followers" => false,
|
||||
"block_from_strangers" => true,
|
||||
"bar" => 1
|
||||
})
|
||||
|> json_response(:ok)
|
||||
|
|
@ -199,130 +199,25 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
user = refresh_record(user)
|
||||
|
||||
assert %Pleroma.User.NotificationSetting{
|
||||
followers: false,
|
||||
follows: true,
|
||||
non_follows: true,
|
||||
non_followers: true,
|
||||
privacy_option: false
|
||||
block_from_strangers: true,
|
||||
hide_notification_contents: false
|
||||
} == user.notification_settings
|
||||
end
|
||||
|
||||
test "it updates notification privacy option", %{user: user, conn: conn} do
|
||||
test "it updates notification settings to enable hiding contents", %{user: user, conn: conn} do
|
||||
conn
|
||||
|> put("/api/pleroma/notification_settings", %{"privacy_option" => "1"})
|
||||
|> put("/api/pleroma/notification_settings", %{"hide_notification_contents" => "1"})
|
||||
|> json_response(:ok)
|
||||
|
||||
user = refresh_record(user)
|
||||
|
||||
assert %Pleroma.User.NotificationSetting{
|
||||
followers: true,
|
||||
follows: true,
|
||||
non_follows: true,
|
||||
non_followers: true,
|
||||
privacy_option: true
|
||||
block_from_strangers: false,
|
||||
hide_notification_contents: true
|
||||
} == user.notification_settings
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/statusnet/config" do
|
||||
test "it returns config in xml format", %{conn: conn} do
|
||||
instance = Config.get(:instance)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get("/api/statusnet/config")
|
||||
|> response(:ok)
|
||||
|
||||
assert response ==
|
||||
"<config>\n<site>\n<name>#{Keyword.get(instance, :name)}</name>\n<site>#{
|
||||
Pleroma.Web.base_url()
|
||||
}</site>\n<textlimit>#{Keyword.get(instance, :limit)}</textlimit>\n<closed>#{
|
||||
!Keyword.get(instance, :registrations_open)
|
||||
}</closed>\n</site>\n</config>\n"
|
||||
end
|
||||
|
||||
test "it returns config in json format", %{conn: conn} do
|
||||
instance = Config.get(:instance)
|
||||
Config.put([:instance, :managed_config], true)
|
||||
Config.put([:instance, :registrations_open], false)
|
||||
Config.put([:instance, :invites_enabled], true)
|
||||
Config.put([:instance, :public], false)
|
||||
Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/api/statusnet/config")
|
||||
|> json_response(:ok)
|
||||
|
||||
expected_data = %{
|
||||
"site" => %{
|
||||
"accountActivationRequired" => "0",
|
||||
"closed" => "1",
|
||||
"description" => Keyword.get(instance, :description),
|
||||
"invitesEnabled" => "1",
|
||||
"name" => Keyword.get(instance, :name),
|
||||
"pleromafe" => %{"theme" => "asuka-hospital"},
|
||||
"private" => "1",
|
||||
"safeDMMentionsEnabled" => "0",
|
||||
"server" => Pleroma.Web.base_url(),
|
||||
"textlimit" => to_string(Keyword.get(instance, :limit)),
|
||||
"uploadlimit" => %{
|
||||
"avatarlimit" => to_string(Keyword.get(instance, :avatar_upload_limit)),
|
||||
"backgroundlimit" => to_string(Keyword.get(instance, :background_upload_limit)),
|
||||
"bannerlimit" => to_string(Keyword.get(instance, :banner_upload_limit)),
|
||||
"uploadlimit" => to_string(Keyword.get(instance, :upload_limit))
|
||||
},
|
||||
"vapidPublicKey" => Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
|
||||
}
|
||||
}
|
||||
|
||||
assert response == expected_data
|
||||
end
|
||||
|
||||
test "returns the state of safe_dm_mentions flag", %{conn: conn} do
|
||||
Config.put([:instance, :safe_dm_mentions], true)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/statusnet/config.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["site"]["safeDMMentionsEnabled"] == "1"
|
||||
|
||||
Config.put([:instance, :safe_dm_mentions], false)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/statusnet/config.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["site"]["safeDMMentionsEnabled"] == "0"
|
||||
end
|
||||
|
||||
test "it returns the managed config", %{conn: conn} do
|
||||
Config.put([:instance, :managed_config], false)
|
||||
Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/statusnet/config.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
refute response["site"]["pleromafe"]
|
||||
|
||||
Config.put([:instance, :managed_config], true)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/statusnet/config.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["site"]["pleromafe"] == %{"theme" => "asuka-hospital"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/frontend_configurations" do
|
||||
test "returns everything in :pleroma, :frontend_configurations", %{conn: conn} do
|
||||
config = [
|
||||
|
|
@ -451,28 +346,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "GET /api/statusnet/version" do
|
||||
test "it returns version in xml format", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/xml")
|
||||
|> get("/api/statusnet/version")
|
||||
|> response(:ok)
|
||||
|
||||
assert response == "<version>#{Pleroma.Application.named_version()}</version>"
|
||||
end
|
||||
|
||||
test "it returns version in json format", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/api/statusnet/version")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response == "#{Pleroma.Application.named_version()}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /main/ostatus - remote_subscribe/2" do
|
||||
setup do: clear_config([:instance, :federating], true)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ defmodule Pleroma.Workers.Cron.ClearOauthTokenWorkerTest do
|
|||
)
|
||||
|
||||
Pleroma.Config.put([:oauth2, :clean_expired_tokens], true)
|
||||
ClearOauthTokenWorker.perform(:opts, :job)
|
||||
ClearOauthTokenWorker.perform(%Oban.Job{})
|
||||
assert Pleroma.Repo.all(Pleroma.Web.OAuth.Token) == []
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorkerTest do
|
|||
end
|
||||
|
||||
test "it sends digest emails", %{user2: user2} do
|
||||
Pleroma.Workers.Cron.DigestEmailsWorker.perform(:opts, :pid)
|
||||
Pleroma.Workers.Cron.DigestEmailsWorker.perform(%Oban.Job{})
|
||||
# Performing job(s) enqueued at previous step
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ defmodule Pleroma.Workers.Cron.DigestEmailsWorkerTest do
|
|||
test "it doesn't fail when a user has no email", %{user2: user2} do
|
||||
{:ok, _} = user2 |> Ecto.Changeset.change(%{email: nil}) |> Pleroma.Repo.update()
|
||||
|
||||
Pleroma.Workers.Cron.DigestEmailsWorker.perform(:opts, :pid)
|
||||
Pleroma.Workers.Cron.DigestEmailsWorker.perform(%Oban.Job{})
|
||||
# Performing job(s) enqueued at previous step
|
||||
ObanHelpers.perform_all()
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorkerTest do
|
|||
user2 = insert(:user, %{inserted_at: yesterday})
|
||||
CommonAPI.post(user, %{status: "cofe"})
|
||||
|
||||
NewUsersDigestWorker.perform(nil, nil)
|
||||
NewUsersDigestWorker.perform(%Oban.Job{})
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert_received {:email, email}
|
||||
|
|
@ -39,7 +39,7 @@ defmodule Pleroma.Workers.Cron.NewUsersDigestWorkerTest do
|
|||
|
||||
CommonAPI.post(user, %{status: "cofe"})
|
||||
|
||||
NewUsersDigestWorker.perform(nil, nil)
|
||||
NewUsersDigestWorker.perform(%Oban.Job{})
|
||||
ObanHelpers.perform_all()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do
|
|||
%{activity_id: activity.id, scheduled_at: naive_datetime}
|
||||
)
|
||||
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(:ops, :pid)
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(%Oban.Job{})
|
||||
|
||||
refute Pleroma.Repo.get(Pleroma.Activity, activity.id)
|
||||
refute Pleroma.Repo.get(Pleroma.ActivityExpiration, expiration.id)
|
||||
|
|
@ -58,7 +58,7 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do
|
|||
|> Ecto.Changeset.change(%{scheduled_at: past_date})
|
||||
|> Repo.update!()
|
||||
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(:ops, :pid)
|
||||
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(%Oban.Job{})
|
||||
|
||||
assert [%{data: %{"type" => "Delete", "deleted_activity_id" => ^id}}] =
|
||||
Pleroma.Repo.all(Pleroma.Activity)
|
||||
|
|
|
|||
|
|
@ -32,10 +32,7 @@ defmodule Pleroma.Workers.ScheduledActivityWorkerTest do
|
|||
params: %{status: "hi"}
|
||||
)
|
||||
|
||||
ScheduledActivityWorker.perform(
|
||||
%{"activity_id" => scheduled_activity.id},
|
||||
:pid
|
||||
)
|
||||
ScheduledActivityWorker.perform(%Oban.Job{args: %{"activity_id" => scheduled_activity.id}})
|
||||
|
||||
refute Repo.get(ScheduledActivity, scheduled_activity.id)
|
||||
activity = Repo.all(Pleroma.Activity) |> Enum.find(&(&1.actor == user.ap_id))
|
||||
|
|
@ -46,7 +43,7 @@ defmodule Pleroma.Workers.ScheduledActivityWorkerTest do
|
|||
Pleroma.Config.put([ScheduledActivity, :enabled], true)
|
||||
|
||||
assert capture_log([level: :error], fn ->
|
||||
ScheduledActivityWorker.perform(%{"activity_id" => 42}, :pid)
|
||||
ScheduledActivityWorker.perform(%Oban.Job{args: %{"activity_id" => 42}})
|
||||
end) =~ "Couldn't find scheduled activity"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue